[Headers] [ARM64EC] Fix extra tokens inside intrin0.h preprocessor directive (#112066)
[llvm-project.git] / offload / src / PluginManager.cpp
blob5e8f91792a551aadbc4c1a0f7f59900ee7c00434
1 //===-- PluginManager.cpp - Plugin loading and communication API ---------===//
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 // Functionality for handling plugins.
11 //===----------------------------------------------------------------------===//
13 #include "PluginManager.h"
14 #include "Shared/Debug.h"
15 #include "Shared/Profile.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include <memory>
21 using namespace llvm;
22 using namespace llvm::sys;
24 PluginManager *PM = nullptr;
26 // Every plugin exports this method to create an instance of the plugin type.
27 #define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
28 #include "Shared/Targets.def"
30 void PluginManager::init() {
31 TIMESCOPE();
32 DP("Loading RTLs...\n");
34 // Attempt to create an instance of each supported plugin.
35 #define PLUGIN_TARGET(Name) \
36 do { \
37 Plugins.emplace_back( \
38 std::unique_ptr<GenericPluginTy>(createPlugin_##Name())); \
39 } while (false);
40 #include "Shared/Targets.def"
42 DP("RTLs loaded!\n");
45 void PluginManager::deinit() {
46 TIMESCOPE();
47 DP("Unloading RTLs...\n");
49 for (auto &Plugin : Plugins) {
50 if (!Plugin->is_initialized())
51 continue;
53 if (auto Err = Plugin->deinit()) {
54 [[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
55 DP("Failed to deinit plugin: %s\n", InfoMsg.c_str());
57 Plugin.release();
60 DP("RTLs unloaded!\n");
63 void PluginManager::initAllPlugins() {
64 for (auto &R : plugins()) {
65 if (auto Err = R.init()) {
66 [[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
67 DP("Failed to init plugin: %s\n", InfoMsg.c_str());
68 continue;
70 DP("Registered plugin %s with %d visible device(s)\n", R.getName(),
71 R.number_of_devices());
75 void PluginManager::registerLib(__tgt_bin_desc *Desc) {
76 PM->RTLsMtx.lock();
78 // Add in all the OpenMP requirements associated with this binary.
79 for (__tgt_offload_entry &Entry :
80 llvm::make_range(Desc->HostEntriesBegin, Desc->HostEntriesEnd))
81 if (Entry.flags == OMP_REGISTER_REQUIRES)
82 PM->addRequirements(Entry.data);
84 // Extract the exectuable image and extra information if availible.
85 for (int32_t i = 0; i < Desc->NumDeviceImages; ++i)
86 PM->addDeviceImage(*Desc, Desc->DeviceImages[i]);
88 // Register the images with the RTLs that understand them, if any.
89 for (DeviceImageTy &DI : PM->deviceImages()) {
90 // Obtain the image and information that was previously extracted.
91 __tgt_device_image *Img = &DI.getExecutableImage();
93 GenericPluginTy *FoundRTL = nullptr;
95 // Scan the RTLs that have associated images until we find one that supports
96 // the current image.
97 for (auto &R : PM->plugins()) {
98 if (!R.is_plugin_compatible(Img))
99 continue;
101 if (!R.is_initialized()) {
102 if (auto Err = R.init()) {
103 [[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
104 DP("Failed to init plugin: %s\n", InfoMsg.c_str());
105 continue;
107 DP("Registered plugin %s with %d visible device(s)\n", R.getName(),
108 R.number_of_devices());
111 if (!R.number_of_devices()) {
112 DP("Skipping plugin %s with no visible devices\n", R.getName());
113 continue;
116 for (int32_t DeviceId = 0; DeviceId < R.number_of_devices(); ++DeviceId) {
117 if (!R.is_device_compatible(DeviceId, Img))
118 continue;
120 DP("Image " DPxMOD " is compatible with RTL %s device %d!\n",
121 DPxPTR(Img->ImageStart), R.getName(), DeviceId);
123 if (!R.is_device_initialized(DeviceId)) {
124 // Initialize the device information for the RTL we are about to use.
125 auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
127 int32_t UserId = ExclusiveDevicesAccessor->size();
129 // Set the device identifier offset in the plugin.
130 #ifdef OMPT_SUPPORT
131 R.set_device_identifier(UserId, DeviceId);
132 #endif
134 auto Device = std::make_unique<DeviceTy>(&R, UserId, DeviceId);
135 if (auto Err = Device->init()) {
136 [[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
137 DP("Failed to init device %d: %s\n", DeviceId, InfoMsg.c_str());
138 continue;
141 ExclusiveDevicesAccessor->push_back(std::move(Device));
143 // We need to map between the plugin's device identifier and the one
144 // that OpenMP will use.
145 PM->DeviceIds[std::make_pair(&R, DeviceId)] = UserId;
148 // Initialize (if necessary) translation table for this library.
149 PM->TrlTblMtx.lock();
150 if (!PM->HostEntriesBeginToTransTable.count(Desc->HostEntriesBegin)) {
151 PM->HostEntriesBeginRegistrationOrder.push_back(
152 Desc->HostEntriesBegin);
153 TranslationTable &TT =
154 (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin];
155 TT.HostTable.EntriesBegin = Desc->HostEntriesBegin;
156 TT.HostTable.EntriesEnd = Desc->HostEntriesEnd;
159 // Retrieve translation table for this library.
160 TranslationTable &TT =
161 (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin];
163 DP("Registering image " DPxMOD " with RTL %s!\n",
164 DPxPTR(Img->ImageStart), R.getName());
166 auto UserId = PM->DeviceIds[std::make_pair(&R, DeviceId)];
167 if (TT.TargetsTable.size() < static_cast<size_t>(UserId + 1)) {
168 TT.DeviceTables.resize(UserId + 1, {});
169 TT.TargetsImages.resize(UserId + 1, nullptr);
170 TT.TargetsEntries.resize(UserId + 1, {});
171 TT.TargetsTable.resize(UserId + 1, nullptr);
174 // Register the image for this target type and invalidate the table.
175 TT.TargetsImages[UserId] = Img;
176 TT.TargetsTable[UserId] = nullptr;
178 PM->UsedImages.insert(Img);
179 FoundRTL = &R;
181 PM->TrlTblMtx.unlock();
184 if (!FoundRTL)
185 DP("No RTL found for image " DPxMOD "!\n", DPxPTR(Img->ImageStart));
187 PM->RTLsMtx.unlock();
189 bool UseAutoZeroCopy = Plugins.size() > 0;
191 auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
192 for (const auto &Device : *ExclusiveDevicesAccessor)
193 UseAutoZeroCopy &= Device->useAutoZeroCopy();
195 // Auto Zero-Copy can only be currently triggered when the system is an
196 // homogeneous APU architecture without attached discrete GPUs.
197 // If all devices suggest to use it, change requirment flags to trigger
198 // zero-copy behavior when mapping memory.
199 if (UseAutoZeroCopy)
200 addRequirements(OMPX_REQ_AUTO_ZERO_COPY);
202 DP("Done registering entries!\n");
205 // Temporary forward declaration, old style CTor/DTor handling is going away.
206 int target(ident_t *Loc, DeviceTy &Device, void *HostPtr,
207 KernelArgsTy &KernelArgs, AsyncInfoTy &AsyncInfo);
209 void PluginManager::unregisterLib(__tgt_bin_desc *Desc) {
210 DP("Unloading target library!\n");
212 PM->RTLsMtx.lock();
213 // Find which RTL understands each image, if any.
214 for (DeviceImageTy &DI : PM->deviceImages()) {
215 // Obtain the image and information that was previously extracted.
216 __tgt_device_image *Img = &DI.getExecutableImage();
218 GenericPluginTy *FoundRTL = NULL;
220 // Scan the RTLs that have associated images until we find one that supports
221 // the current image. We only need to scan RTLs that are already being used.
222 for (auto &R : PM->plugins()) {
223 if (R.is_initialized())
224 continue;
226 // Ensure that we do not use any unused images associated with this RTL.
227 if (!UsedImages.contains(Img))
228 continue;
230 FoundRTL = &R;
232 DP("Unregistered image " DPxMOD " from RTL\n", DPxPTR(Img->ImageStart));
234 break;
237 // if no RTL was found proceed to unregister the next image
238 if (!FoundRTL) {
239 DP("No RTLs in use support the image " DPxMOD "!\n",
240 DPxPTR(Img->ImageStart));
243 PM->RTLsMtx.unlock();
244 DP("Done unregistering images!\n");
246 // Remove entries from PM->HostPtrToTableMap
247 PM->TblMapMtx.lock();
248 for (__tgt_offload_entry *Cur = Desc->HostEntriesBegin;
249 Cur < Desc->HostEntriesEnd; ++Cur) {
250 PM->HostPtrToTableMap.erase(Cur->addr);
253 // Remove translation table for this descriptor.
254 auto TransTable =
255 PM->HostEntriesBeginToTransTable.find(Desc->HostEntriesBegin);
256 if (TransTable != PM->HostEntriesBeginToTransTable.end()) {
257 DP("Removing translation table for descriptor " DPxMOD "\n",
258 DPxPTR(Desc->HostEntriesBegin));
259 PM->HostEntriesBeginToTransTable.erase(TransTable);
260 } else {
261 DP("Translation table for descriptor " DPxMOD " cannot be found, probably "
262 "it has been already removed.\n",
263 DPxPTR(Desc->HostEntriesBegin));
266 PM->TblMapMtx.unlock();
268 DP("Done unregistering library!\n");
271 Expected<DeviceTy &> PluginManager::getDevice(uint32_t DeviceNo) {
272 auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
273 if (DeviceNo >= ExclusiveDevicesAccessor->size())
274 return createStringError(
275 inconvertibleErrorCode(),
276 "Device number '%i' out of range, only %i devices available", DeviceNo,
277 ExclusiveDevicesAccessor->size());
279 return *(*ExclusiveDevicesAccessor)[DeviceNo];