Skip to content

Commit 8dec66a

Browse files
jdoerfertronlieb
authored andcommitted
[OpenMP][NFC] Modernize the plugin handling (llvm#74034)
This basically moves code around again, but this time to provide cleaner interfaces and remove duplication. PluginAdaptorManagerTy is almost all gone after this. Change-Id: I2c9db48af4b047277bbde393124716f19e9002d8
1 parent b25aa03 commit 8dec66a

File tree

5 files changed

+173
-191
lines changed

5 files changed

+173
-191
lines changed

openmp/libomptarget/include/PluginManager.h

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,38 @@
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
// Forward declarations.
2931
struct DeviceTy;
3032
struct __tgt_bin_desc;
3133

3234
struct PluginAdaptorTy {
33-
int32_t Idx = -1; // RTL index, index is the number of devices
34-
// of other RTLs that were registered before,
35-
// i.e. the OpenMP index of the first device
36-
// to be registered with this RTL.
37-
int32_t NumberOfDevices = -1; // Number of devices this RTL deals with.
35+
PluginAdaptorTy(const std::string &Name);
3836

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

41-
#ifdef OMPTARGET_DEBUG
42-
std::string RTLName;
43-
#endif
47+
/// Number of devices this RTL deals with.
48+
int32_t NumberOfDevices = -1;
49+
50+
/// Name of the shared object file representing the plugin.
51+
std::string Name;
52+
53+
/// Access to the shared object file representing the plugin.
54+
std::unique_ptr<llvm::sys::DynamicLibrary> LibraryHandler;
4455

4556
#define PLUGIN_API_HANDLE(NAME, MANDATORY) \
4657
using NAME##_ty = decltype(__tgt_rtl_##NAME); \
@@ -49,9 +60,6 @@ struct PluginAdaptorTy {
4960
#include "Shared/PluginAPI.inc"
5061
#undef PLUGIN_API_HANDLE
5162

52-
// Are there images associated with this RTL.
53-
bool IsUsed = false;
54-
5563
llvm::DenseSet<const __tgt_device_image *> UsedImages;
5664

5765
// Mutex for thread-safety when calling RTL interface functions.
@@ -62,41 +70,26 @@ struct PluginAdaptorTy {
6270

6371
/// RTLs identified in the system.
6472
struct PluginAdaptorManagerTy {
65-
// List of the detected runtime libraries.
66-
std::list<PluginAdaptorTy> AllRTLs;
67-
68-
// Array of pointers to the detected runtime libraries that have compatible
69-
// binaries.
70-
llvm::SmallVector<PluginAdaptorTy *> UsedRTLs;
71-
7273
int64_t RequiresFlags = OMP_REQ_UNDEFINED;
7374

7475
explicit PluginAdaptorManagerTy() = default;
7576

7677
// Register the clauses of the requires directive.
7778
void registerRequires(int64_t Flags);
7879

79-
// Initialize RTL if it has not been initialized
80-
void initRTLonce(PluginAdaptorTy &RTL);
81-
82-
// Initialize all RTLs
83-
void initAllRTLs();
84-
8580
// Register a shared library with all (compatible) RTLs.
8681
void registerLib(__tgt_bin_desc *Desc);
8782

8883
// Unregister a shared library from all RTLs.
8984
void unregisterLib(__tgt_bin_desc *Desc);
90-
91-
// not thread-safe, called from global constructor (i.e. once)
92-
void loadRTLs();
93-
94-
private:
95-
static bool attemptLoadRTL(const std::string &RTLName, PluginAdaptorTy &RTL);
9685
};
9786

9887
/// Struct for the data required to handle plugins
9988
struct PluginManager {
89+
PluginManager() {}
90+
91+
void init();
92+
10093
/// RTLs identified on the host
10194
PluginAdaptorManagerTy RTLs;
10295

@@ -145,9 +138,30 @@ struct PluginManager {
145138
return Devices.size();
146139
}
147140

141+
int getNumUsedPlugins() const {
142+
int NCI = 0;
143+
for (auto &P : PluginAdaptors)
144+
NCI += P.isUsed();
145+
return NCI;
146+
}
147+
148+
// Initialize \p Plugin if it has not been initialized.
149+
void initPlugin(PluginAdaptorTy &Plugin);
150+
151+
// Initialize all plugins.
152+
void initAllPlugins();
153+
154+
/// Iterator range for all plugin adaptors (in use or not, but always valid).
155+
auto pluginAdaptors() {
156+
return llvm::make_range(PluginAdaptors.begin(), PluginAdaptors.end());
157+
}
158+
148159
private:
149160
bool RTLsLoaded = false;
150161
llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
162+
163+
// List of all plugin adaptors, in use or not.
164+
std::list<PluginAdaptorTy> PluginAdaptors;
151165
};
152166

153167
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+
/* AMDGPU target */ "libomptarget.rtl.amdgpu",
23+
/* CUDA target */ "libomptarget.rtl.cuda",
24+
/* x86_64 target */ "libomptarget.rtl.x86_64",
25+
/* AArch64 target */ "libomptarget.rtl.aarch64",
26+
/* PowerPC target */ "libomptarget.rtl.ppc64",
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
@@ -448,7 +448,7 @@ EXTERN void __tgt_push_mapper_component(void *RtMapperHandle, void *Base,
448448
EXTERN void __tgt_set_info_flag(uint32_t NewInfoLevel) {
449449
std::atomic<uint32_t> &InfoLevel = getInfoLevelInternal();
450450
InfoLevel.store(NewInfoLevel);
451-
for (auto &R : PM->RTLs.AllRTLs) {
451+
for (auto &R : PM->pluginAdaptors()) {
452452
if (R.set_info_flag)
453453
R.set_info_flag(NewInfoLevel);
454454
}

openmp/libomptarget/src/omptarget.cpp

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

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

0 commit comments

Comments
 (0)