1 //===-- PluginManager.h - Plugin loading and communication API --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Declarations for managing devices that are handled by RTL plugins.
11 //===----------------------------------------------------------------------===//
13 #ifndef OMPTARGET_PLUGIN_MANAGER_H
14 #define OMPTARGET_PLUGIN_MANAGER_H
16 #include "PluginInterface.h"
18 #include "DeviceImage.h"
19 #include "ExclusiveAccess.h"
20 #include "Shared/APITypes.h"
21 #include "Shared/Requirements.h"
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"
38 using GenericPluginTy
= llvm::omp::target::plugin::GenericPluginTy
;
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
>>;
46 /// Exclusive accessor type for the device container.
47 using ExclusiveDevicesAccessorTy
= Accessor
<DeviceContainerTy
>;
55 // Register a shared library with all (compatible) RTLs.
56 void registerLib(__tgt_bin_desc
*Desc
);
58 // Unregister a shared library from all RTLs.
59 void unregisterLib(__tgt_bin_desc
*Desc
);
61 void addDeviceImage(__tgt_bin_desc
&TgtBinDesc
,
62 __tgt_device_image
&TgtDeviceImage
) {
63 DeviceImages
.emplace_back(
64 std::make_unique
<DeviceImageTy
>(TgtBinDesc
, TgtDeviceImage
));
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
);
71 /// Iterate over all initialized and ready devices registered with this
73 auto devices(ExclusiveDevicesAccessorTy
&DevicesAccessor
) {
74 return llvm::make_pointee_range(*DevicesAccessor
);
77 /// Iterate over all device images registered with this plugin.
78 auto deviceImages() { return llvm::make_pointee_range(DeviceImages
); }
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
<__tgt_offload_entry
*> HostEntriesBeginRegistrationOrder
;
86 /// Map from ptrs on the host to an entry in the Translation Table
87 HostPtrToTableMapTy HostPtrToTableMap
;
88 std::mutex TblMapMtx
; ///< For HostPtrToTableMap
90 // Work around for plugins that call dlopen on shared libraries that call
91 // tgt_register_lib during their initialisation. Stash the pointers in a
92 // vector until the plugins are all initialised and then register them.
93 bool delayRegisterLib(__tgt_bin_desc
*Desc
) {
96 DelayedBinDesc
.push_back(Desc
);
100 void registerDelayedLibraries() {
101 // Only called by libomptarget constructor
103 for (auto *Desc
: DelayedBinDesc
)
104 __tgt_register_lib(Desc
);
105 DelayedBinDesc
.clear();
108 /// Return the number of usable devices.
109 int getNumDevices() { return getExclusiveDevicesAccessor()->size(); }
111 /// Return an exclusive handle to access the devices container.
112 ExclusiveDevicesAccessorTy
getExclusiveDevicesAccessor() {
113 return Devices
.getExclusiveAccessor();
116 /// Initialize \p Plugin. Returns true on success.
117 bool initializePlugin(GenericPluginTy
&Plugin
);
119 /// Initialize device \p DeviceNo of \p Plugin. Returns true on success.
120 bool initializeDevice(GenericPluginTy
&Plugin
, int32_t DeviceId
);
122 /// Eagerly initialize all plugins and their devices.
123 void initializeAllDevices();
125 /// Iterator range for all plugins (in use or not, but always valid).
126 auto plugins() { return llvm::make_pointee_range(Plugins
); }
128 /// Iterator range for all plugins (in use or not, but always valid).
129 auto plugins() const { return llvm::make_pointee_range(Plugins
); }
131 /// Return the user provided requirements.
132 int64_t getRequirements() const { return Requirements
.getRequirements(); }
134 /// Add \p Flags to the user provided requirements.
135 void addRequirements(int64_t Flags
) { Requirements
.addRequirements(Flags
); }
137 /// Returns the number of plugins that are active.
138 int getNumActivePlugins() const {
140 for (auto &R
: plugins())
141 if (R
.is_initialized())
148 bool RTLsLoaded
= false;
149 llvm::SmallVector
<__tgt_bin_desc
*> DelayedBinDesc
;
151 // List of all plugins, in use or not.
152 llvm::SmallVector
<std::unique_ptr
<GenericPluginTy
>> Plugins
;
154 // Mapping of plugins to the OpenMP device identifier.
155 llvm::DenseMap
<std::pair
<const GenericPluginTy
*, int32_t>, int32_t>
158 // Set of all device images currently in use.
159 llvm::DenseSet
<const __tgt_device_image
*> UsedImages
;
161 /// Executable images and information extracted from the input images passed
163 llvm::SmallVector
<std::unique_ptr
<DeviceImageTy
>> DeviceImages
;
165 /// The user provided requirements.
166 RequirementCollection Requirements
;
168 std::mutex RTLsMtx
; ///< For RTLs
170 /// Devices associated with plugins, accesses to the container are exclusive.
171 ProtectedObj
<DeviceContainerTy
> Devices
;
174 /// Initialize the plugin manager and OpenMP runtime.
177 /// Deinitialize the plugin and delete it.
178 void deinitRuntime();
180 extern PluginManager
*PM
;
182 #endif // OMPTARGET_PLUGIN_MANAGER_H