Skip to content

Commit bc4e0c0

Browse files
authored
[OpenMP][NFC] Modernize the plugin handling (#74034)
This basically moves code around again, but this time to provide cleaner interfaces and remove duplication. PluginAdaptorManagerTy is almost all gone after this.
1 parent ff0d8a9 commit bc4e0c0

File tree

5 files changed

+170
-174
lines changed

5 files changed

+170
-174
lines changed

openmp/libomptarget/include/PluginManager.h

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,34 @@
2020

2121
#include "llvm/ADT/DenseSet.h"
2222
#include "llvm/ADT/SmallVector.h"
23+
#include "llvm/ADT/iterator_range.h"
2324
#include "llvm/Support/DynamicLibrary.h"
2425

2526
#include <list>
2627
#include <mutex>
28+
#include <string>
2729

2830
struct PluginAdaptorTy {
29-
int32_t Idx = -1; // RTL index, index is the number of devices
30-
// of other RTLs that were registered before,
31-
// i.e. the OpenMP index of the first device
32-
// to be registered with this RTL.
33-
int32_t NumberOfDevices = -1; // Number of devices this RTL deals with.
31+
PluginAdaptorTy(const std::string &Name);
3432

35-
std::unique_ptr<llvm::sys::DynamicLibrary> LibraryHandler;
33+
bool isUsed() const { return DeviceOffset >= 0; }
34+
35+
/// Return the number of devices available to this plugin.
36+
int32_t getNumDevices() const { return NumberOfDevices; }
37+
38+
/// RTL index, index is the number of devices of other RTLs that were
39+
/// registered before, i.e. the OpenMP index of the first device to be
40+
/// registered with this RTL.
41+
int32_t DeviceOffset = -1;
3642

37-
#ifdef OMPTARGET_DEBUG
38-
std::string RTLName;
39-
#endif
43+
/// Number of devices this RTL deals with.
44+
int32_t NumberOfDevices = -1;
45+
46+
/// Name of the shared object file representing the plugin.
47+
std::string Name;
48+
49+
/// Access to the shared object file representing the plugin.
50+
std::unique_ptr<llvm::sys::DynamicLibrary> LibraryHandler;
4051

4152
#define PLUGIN_API_HANDLE(NAME, MANDATORY) \
4253
using NAME##_ty = decltype(__tgt_rtl_##NAME); \
@@ -45,9 +56,6 @@ struct PluginAdaptorTy {
4556
#include "Shared/PluginAPI.inc"
4657
#undef PLUGIN_API_HANDLE
4758

48-
// Are there images associated with this RTL.
49-
bool IsUsed = false;
50-
5159
llvm::DenseSet<const __tgt_device_image *> UsedImages;
5260

5361
// Mutex for thread-safety when calling RTL interface functions.
@@ -58,41 +66,26 @@ struct PluginAdaptorTy {
5866

5967
/// RTLs identified in the system.
6068
struct PluginAdaptorManagerTy {
61-
// List of the detected runtime libraries.
62-
std::list<PluginAdaptorTy> AllRTLs;
63-
64-
// Array of pointers to the detected runtime libraries that have compatible
65-
// binaries.
66-
llvm::SmallVector<PluginAdaptorTy *> UsedRTLs;
67-
6869
int64_t RequiresFlags = OMP_REQ_UNDEFINED;
6970

7071
explicit PluginAdaptorManagerTy() = default;
7172

7273
// Register the clauses of the requires directive.
7374
void registerRequires(int64_t Flags);
7475

75-
// Initialize RTL if it has not been initialized
76-
void initRTLonce(PluginAdaptorTy &RTL);
77-
78-
// Initialize all RTLs
79-
void initAllRTLs();
80-
8176
// Register a shared library with all (compatible) RTLs.
8277
void registerLib(__tgt_bin_desc *Desc);
8378

8479
// Unregister a shared library from all RTLs.
8580
void unregisterLib(__tgt_bin_desc *Desc);
86-
87-
// not thread-safe, called from global constructor (i.e. once)
88-
void loadRTLs();
89-
90-
private:
91-
static bool attemptLoadRTL(const std::string &RTLName, PluginAdaptorTy &RTL);
9281
};
9382

9483
/// Struct for the data required to handle plugins
9584
struct PluginManager {
85+
PluginManager() {}
86+
87+
void init();
88+
9689
/// RTLs identified on the host
9790
PluginAdaptorManagerTy RTLs;
9891

@@ -141,9 +134,30 @@ struct PluginManager {
141134
return Devices.size();
142135
}
143136

137+
int getNumUsedPlugins() const {
138+
int NCI = 0;
139+
for (auto &P : PluginAdaptors)
140+
NCI += P.isUsed();
141+
return NCI;
142+
}
143+
144+
// Initialize \p Plugin if it has not been initialized.
145+
void initPlugin(PluginAdaptorTy &Plugin);
146+
147+
// Initialize all plugins.
148+
void initAllPlugins();
149+
150+
/// Iterator range for all plugin adaptors (in use or not, but always valid).
151+
auto pluginAdaptors() {
152+
return llvm::make_range(PluginAdaptors.begin(), PluginAdaptors.end());
153+
}
154+
144155
private:
145156
bool RTLsLoaded = false;
146157
llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
158+
159+
// List of all plugin adaptors, in use or not.
160+
std::list<PluginAdaptorTy> PluginAdaptors;
147161
};
148162

149163
extern PluginManager *PM;

openmp/libomptarget/src/PluginManager.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,105 @@
1212

1313
#include "PluginManager.h"
1414

15+
using namespace llvm;
16+
using namespace llvm::sys;
17+
1518
PluginManager *PM;
19+
20+
// List of all plugins that can support offloading.
21+
static const char *RTLNames[] = {
22+
/* PowerPC target */ "libomptarget.rtl.ppc64",
23+
/* x86_64 target */ "libomptarget.rtl.x86_64",
24+
/* CUDA target */ "libomptarget.rtl.cuda",
25+
/* AArch64 target */ "libomptarget.rtl.aarch64",
26+
/* AMDGPU target */ "libomptarget.rtl.amdgpu",
27+
};
28+
29+
PluginAdaptorTy::PluginAdaptorTy(const std::string &Name) : Name(Name) {
30+
DP("Attempting to load library '%s'...\n", Name.c_str());
31+
32+
std::string ErrMsg;
33+
LibraryHandler = std::make_unique<DynamicLibrary>(
34+
DynamicLibrary::getPermanentLibrary(Name.c_str(), &ErrMsg));
35+
36+
if (!LibraryHandler->isValid()) {
37+
// Library does not exist or cannot be found.
38+
DP("Unable to load library '%s': %s!\n", Name.c_str(), ErrMsg.c_str());
39+
return;
40+
}
41+
42+
DP("Successfully loaded library '%s'!\n", Name.c_str());
43+
44+
#define PLUGIN_API_HANDLE(NAME, MANDATORY) \
45+
NAME = reinterpret_cast<decltype(NAME)>( \
46+
LibraryHandler->getAddressOfSymbol(GETNAME(__tgt_rtl_##NAME))); \
47+
if (MANDATORY && !NAME) { \
48+
DP("Invalid plugin as necessary interface is not found.\n"); \
49+
return; \
50+
}
51+
52+
#include "Shared/PluginAPI.inc"
53+
#undef PLUGIN_API_HANDLE
54+
55+
// Remove plugin on failure to call optional init_plugin
56+
int32_t Rc = init_plugin();
57+
if (Rc != OFFLOAD_SUCCESS) {
58+
DP("Unable to initialize library '%s': %u!\n", Name.c_str(), Rc);
59+
return;
60+
}
61+
62+
// No devices are supported by this RTL?
63+
NumberOfDevices = number_of_devices();
64+
if (!NumberOfDevices) {
65+
DP("No devices supported in this RTL\n");
66+
return;
67+
}
68+
69+
DP("Registered '%s' with %d devices!\n", Name.c_str(), NumberOfDevices);
70+
}
71+
72+
void PluginManager::init() {
73+
DP("Loading RTLs...\n");
74+
75+
// Attempt to open all the plugins and, if they exist, check if the interface
76+
// is correct and if they are supporting any devices.
77+
for (const char *Name : RTLNames) {
78+
PluginAdaptors.emplace_back(std::string(Name) + ".so");
79+
if (PluginAdaptors.back().getNumDevices() <= 0)
80+
PluginAdaptors.pop_back();
81+
}
82+
83+
DP("RTLs loaded!\n");
84+
}
85+
86+
void PluginManager::initPlugin(PluginAdaptorTy &Plugin) {
87+
// If this RTL is not already in use, initialize it.
88+
if (Plugin.isUsed() || !Plugin.NumberOfDevices)
89+
return;
90+
91+
// Initialize the device information for the RTL we are about to use.
92+
const size_t Start = Devices.size();
93+
Devices.reserve(Start + Plugin.NumberOfDevices);
94+
for (int32_t DeviceId = 0; DeviceId < Plugin.NumberOfDevices; DeviceId++) {
95+
Devices.push_back(std::make_unique<DeviceTy>(&Plugin));
96+
// global device ID
97+
Devices[Start + DeviceId]->DeviceID = Start + DeviceId;
98+
// RTL local device ID
99+
Devices[Start + DeviceId]->RTLDeviceID = DeviceId;
100+
}
101+
102+
// Initialize the index of this RTL and save it in the used RTLs.
103+
Plugin.DeviceOffset = Start;
104+
105+
// If possible, set the device identifier offset in the plugin.
106+
if (Plugin.set_device_offset)
107+
Plugin.set_device_offset(Start);
108+
109+
DP("RTL " DPxMOD " has index %d!\n", DPxPTR(Plugin.LibraryHandler.get()),
110+
Plugin.DeviceOffset);
111+
}
112+
113+
void PluginManager::initAllPlugins() {
114+
for (auto &R : PluginAdaptors)
115+
initPlugin(R);
116+
}

openmp/libomptarget/src/interface.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ EXTERN void __tgt_register_lib(__tgt_bin_desc *Desc) {
5454

5555
////////////////////////////////////////////////////////////////////////////////
5656
/// Initialize all available devices without registering any image
57-
EXTERN void __tgt_init_all_rtls() { PM->RTLs.initAllRTLs(); }
57+
EXTERN void __tgt_init_all_rtls() { PM->initAllPlugins(); }
5858

5959
////////////////////////////////////////////////////////////////////////////////
6060
/// unloads a target shared library
@@ -426,7 +426,7 @@ EXTERN void __tgt_push_mapper_component(void *RtMapperHandle, void *Base,
426426
EXTERN void __tgt_set_info_flag(uint32_t NewInfoLevel) {
427427
std::atomic<uint32_t> &InfoLevel = getInfoLevelInternal();
428428
InfoLevel.store(NewInfoLevel);
429-
for (auto &R : PM->RTLs.AllRTLs) {
429+
for (auto &R : PM->pluginAdaptors()) {
430430
if (R.set_info_flag)
431431
R.set_info_flag(NewInfoLevel);
432432
}

openmp/libomptarget/src/omptarget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ void handleTargetOutcome(bool Success, ident_t *Loc) {
300300
FAILURE_MESSAGE("Consult https://openmp.llvm.org/design/Runtimes.html "
301301
"for debugging options.\n");
302302

303-
if (PM->RTLs.UsedRTLs.empty()) {
303+
if (!PM->getNumUsedPlugins()) {
304304
llvm::SmallVector<llvm::StringRef> Archs;
305305
llvm::transform(PM->Images, std::back_inserter(Archs),
306306
[](const auto &X) {

0 commit comments

Comments
 (0)