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 all plugins.
117 void initAllPlugins();
119 /// Iterator range for all plugins (in use or not, but always valid).
120 auto plugins() { return llvm::make_pointee_range(Plugins
); }
122 /// Iterator range for all plugins (in use or not, but always valid).
123 auto plugins() const { return llvm::make_pointee_range(Plugins
); }
125 /// Return the user provided requirements.
126 int64_t getRequirements() const { return Requirements
.getRequirements(); }
128 /// Add \p Flags to the user provided requirements.
129 void addRequirements(int64_t Flags
) { Requirements
.addRequirements(Flags
); }
131 /// Returns the number of plugins that are active.
132 int getNumActivePlugins() const {
134 for (auto &R
: plugins())
135 if (R
.is_initialized())
142 bool RTLsLoaded
= false;
143 llvm::SmallVector
<__tgt_bin_desc
*> DelayedBinDesc
;
145 // List of all plugins, in use or not.
146 llvm::SmallVector
<std::unique_ptr
<GenericPluginTy
>> Plugins
;
148 // Mapping of plugins to the OpenMP device identifier.
149 llvm::DenseMap
<std::pair
<const GenericPluginTy
*, int32_t>, int32_t>
152 // Set of all device images currently in use.
153 llvm::DenseSet
<const __tgt_device_image
*> UsedImages
;
155 /// Executable images and information extracted from the input images passed
157 llvm::SmallVector
<std::unique_ptr
<DeviceImageTy
>> DeviceImages
;
159 /// The user provided requirements.
160 RequirementCollection Requirements
;
162 std::mutex RTLsMtx
; ///< For RTLs
164 /// Devices associated with plugins, accesses to the container are exclusive.
165 ProtectedObj
<DeviceContainerTy
> Devices
;
168 /// Initialize the plugin manager and OpenMP runtime.
171 /// Deinitialize the plugin and delete it.
172 void deinitRuntime();
174 extern PluginManager
*PM
;
176 #endif // OMPTARGET_PLUGIN_MANAGER_H