15
15
16
16
#include " llvm/Support/Error.h"
17
17
#include " llvm/Support/ErrorHandling.h"
18
+ #include < memory>
18
19
19
20
using namespace llvm ;
20
21
using namespace llvm ::sys;
@@ -30,27 +31,43 @@ static const char *RTLNames[] = {
30
31
/* AMDGPU target */ " libomptarget.rtl.amdgpu" ,
31
32
};
32
33
33
- PluginAdaptorTy::PluginAdaptorTy (const std::string &Name) : Name(Name) {
34
+ Expected<std::unique_ptr<PluginAdaptorTy>>
35
+ PluginAdaptorTy::create (const std::string &Name) {
34
36
DP (" Attempting to load library '%s'...\n " , Name.c_str ());
35
37
36
38
std::string ErrMsg;
37
- LibraryHandler = std::make_unique<DynamicLibrary>(
39
+ auto LibraryHandler = std::make_unique<DynamicLibrary>(
38
40
DynamicLibrary::getPermanentLibrary (Name.c_str (), &ErrMsg));
39
41
40
42
if (!LibraryHandler->isValid ()) {
41
43
// Library does not exist or cannot be found.
42
- DP (" Unable to load library '%s': %s!\n " , Name.c_str (), ErrMsg.c_str ());
43
- return ;
44
+ return createStringError (inconvertibleErrorCode (),
45
+ " Unable to load library '%s': %s!\n " , Name.c_str (),
46
+ ErrMsg.c_str ());
44
47
}
45
48
46
49
DP (" Successfully loaded library '%s'!\n " , Name.c_str ());
50
+ auto PluginAdaptor = std::unique_ptr<PluginAdaptorTy>(
51
+ new PluginAdaptorTy (Name, std::move (LibraryHandler)));
52
+ if (auto Err = PluginAdaptor->init ())
53
+ return Err;
54
+ return PluginAdaptor;
55
+ }
56
+
57
+ PluginAdaptorTy::PluginAdaptorTy (const std::string &Name,
58
+ std::unique_ptr<llvm::sys::DynamicLibrary> DL)
59
+ : Name(Name), LibraryHandler(std::move(DL)) {}
60
+
61
+ Error PluginAdaptorTy::init () {
47
62
48
63
#define PLUGIN_API_HANDLE (NAME, MANDATORY ) \
49
64
NAME = reinterpret_cast <decltype (NAME)>( \
50
65
LibraryHandler->getAddressOfSymbol (GETNAME (__tgt_rtl_##NAME))); \
51
66
if (MANDATORY && !NAME) { \
52
- DP (" Invalid plugin as necessary interface is not found.\n " ); \
53
- return ; \
67
+ return createStringError (inconvertibleErrorCode (), \
68
+ " Invalid plugin as necessary interface function " \
69
+ " (%s) was not found.\n " , \
70
+ NAME); \
54
71
}
55
72
56
73
#include " Shared/PluginAPI.inc"
@@ -59,22 +76,25 @@ PluginAdaptorTy::PluginAdaptorTy(const std::string &Name) : Name(Name) {
59
76
// Remove plugin on failure to call optional init_plugin
60
77
int32_t Rc = init_plugin ();
61
78
if (Rc != OFFLOAD_SUCCESS) {
62
- DP (" Unable to initialize library '%s': %u!\n " , Name.c_str (), Rc);
63
- return ;
79
+ return createStringError (inconvertibleErrorCode (),
80
+ " Unable to initialize library '%s': %u!\n " ,
81
+ Name.c_str (), Rc);
64
82
}
65
83
66
84
// No devices are supported by this RTL?
67
- NumberOfDevices = number_of_devices ();
68
- if (!NumberOfDevices ) {
69
- DP ( " No devices supported in this RTL \n " );
70
- return ;
85
+ NumberOfPluginDevices = number_of_devices ();
86
+ if (!NumberOfPluginDevices ) {
87
+ return createStringError ( inconvertibleErrorCode (),
88
+ " No devices supported in this RTL \n " ) ;
71
89
}
72
90
73
- DP (" Registered '%s' with %d devices!\n " , Name.c_str (), NumberOfDevices);
91
+ DP (" Registered '%s' with %d plugin visible devices!\n " , Name.c_str (),
92
+ NumberOfPluginDevices);
93
+ return Error::success ();
74
94
}
75
95
76
96
void PluginAdaptorTy::addOffloadEntries (DeviceImageTy &DI) {
77
- for (int32_t I = 0 ; I < NumberOfDevices ; ++I) {
97
+ for (int32_t I = 0 , E = getNumberOfUserDevices () ; I < E ; ++I) {
78
98
auto DeviceOrErr = PM->getDevice (DeviceOffset + I);
79
99
if (!DeviceOrErr)
80
100
FATAL_MESSAGE (DeviceOffset + I, " %s" ,
@@ -92,45 +112,61 @@ void PluginManager::init() {
92
112
// Attempt to open all the plugins and, if they exist, check if the interface
93
113
// is correct and if they are supporting any devices.
94
114
for (const char *Name : RTLNames) {
95
- PluginAdaptors.emplace_back (std::string (Name) + " .so" );
96
- if (PluginAdaptors.back ().getNumDevices () <= 0 )
97
- PluginAdaptors.pop_back ();
115
+ auto PluginAdaptorOrErr =
116
+ PluginAdaptorTy::create (std::string (Name) + " .so" );
117
+ if (!PluginAdaptorOrErr) {
118
+ [[maybe_unused]] std::string InfoMsg =
119
+ toString (PluginAdaptorOrErr.takeError ());
120
+ DP (" %s" , InfoMsg.c_str ());
121
+ } else {
122
+ PluginAdaptors.push_back (std::move (*PluginAdaptorOrErr));
123
+ }
98
124
}
99
125
100
126
DP (" RTLs loaded!\n " );
101
127
}
102
128
103
- void PluginManager::initPlugin (PluginAdaptorTy &Plugin) {
104
- // If this RTL is not already in use, initialize it.
105
- if (Plugin.isUsed () || !Plugin.NumberOfDevices )
129
+ void PluginAdaptorTy::initDevices (PluginManager &PM) {
130
+ if (isUsed ())
106
131
return ;
107
132
133
+ // If this RTL is not already in use, initialize it.
134
+ assert (getNumberOfPluginDevices () > 0 &&
135
+ " Tried to initialize useless plugin adaptor" );
136
+
108
137
// Initialize the device information for the RTL we are about to use.
109
- auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor ();
110
- const size_t Start = ExclusiveDevicesAccessor->size ();
111
- ExclusiveDevicesAccessor->reserve (Start + Plugin.NumberOfDevices );
112
- for (int32_t DeviceId = 0 ; DeviceId < Plugin.NumberOfDevices ; DeviceId++) {
113
- ExclusiveDevicesAccessor->push_back (std::make_unique<DeviceTy>(&Plugin));
114
- // global device ID
115
- (*ExclusiveDevicesAccessor)[Start + DeviceId]->DeviceID = Start + DeviceId;
116
- // RTL local device ID
117
- (*ExclusiveDevicesAccessor)[Start + DeviceId]->RTLDeviceID = DeviceId;
118
- }
138
+ auto ExclusiveDevicesAccessor = PM.getExclusiveDevicesAccessor ();
119
139
120
140
// Initialize the index of this RTL and save it in the used RTLs.
121
- Plugin. DeviceOffset = Start ;
141
+ DeviceOffset = ExclusiveDevicesAccessor-> size () ;
122
142
123
143
// If possible, set the device identifier offset in the plugin.
124
- if (Plugin.set_device_offset )
125
- Plugin.set_device_offset (Start);
144
+ if (set_device_offset)
145
+ set_device_offset (DeviceOffset);
146
+
147
+ int32_t NumPD = getNumberOfPluginDevices ();
148
+ ExclusiveDevicesAccessor->reserve (DeviceOffset + NumPD);
149
+ for (int32_t PDevI = 0 , UserDevId = DeviceOffset; PDevI < NumPD; PDevI++) {
150
+ auto Device = std::make_unique<DeviceTy>(this , UserDevId, PDevI);
151
+ if (auto Err = Device->init ()) {
152
+ DP (" Skip plugin known device %d: %s\n " , PDevI,
153
+ toString (std::move (Err)).c_str ());
154
+ continue ;
155
+ }
156
+
157
+ ExclusiveDevicesAccessor->push_back (std::move (Device));
158
+ ++NumberOfUserDevices;
159
+ ++UserDevId;
160
+ }
126
161
127
- DP (" RTL " DPxMOD " has index %d!\n " , DPxPTR (Plugin.LibraryHandler .get ()),
128
- Plugin.DeviceOffset );
162
+ DP (" Plugin adaptor " DPxMOD " has index %d, exposes %d out of %d devices!\n " ,
163
+ DPxPTR (LibraryHandler.get ()), DeviceOffset, NumberOfUserDevices,
164
+ NumberOfPluginDevices);
129
165
}
130
166
131
167
void PluginManager::initAllPlugins () {
132
168
for (auto &R : PluginAdaptors)
133
- initPlugin (R );
169
+ R-> initDevices (* this );
134
170
}
135
171
136
172
static void registerImageIntoTranslationTable (TranslationTable &TT,
@@ -143,15 +179,16 @@ static void registerImageIntoTranslationTable(TranslationTable &TT,
143
179
144
180
// Resize the Targets Table and Images to accommodate the new targets if
145
181
// required
146
- unsigned TargetsTableMinimumSize = RTL.DeviceOffset + RTL.NumberOfDevices ;
182
+ unsigned TargetsTableMinimumSize =
183
+ RTL.DeviceOffset + RTL.getNumberOfUserDevices ();
147
184
148
185
if (TT.TargetsTable .size () < TargetsTableMinimumSize) {
149
186
TT.TargetsImages .resize (TargetsTableMinimumSize, 0 );
150
187
TT.TargetsTable .resize (TargetsTableMinimumSize, 0 );
151
188
}
152
189
153
190
// Register the image in all devices for this target type.
154
- for (int32_t I = 0 ; I < RTL.NumberOfDevices ; ++I) {
191
+ for (int32_t I = 0 ; I < RTL.getNumberOfUserDevices () ; ++I) {
155
192
// If we are changing the image we are also invalidating the target table.
156
193
if (TT.TargetsImages [RTL.DeviceOffset + I] != Image) {
157
194
TT.TargetsImages [RTL.DeviceOffset + I] = Image;
@@ -194,7 +231,7 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) {
194
231
DP (" Image " DPxMOD " is compatible with RTL %s!\n " ,
195
232
DPxPTR (Img->ImageStart ), R.Name .c_str ());
196
233
197
- PM-> initPlugin (R );
234
+ R. initDevices (* this );
198
235
199
236
// Initialize (if necessary) translation table for this library.
200
237
PM->TrlTblMtx .lock ();
@@ -263,7 +300,7 @@ void PluginManager::unregisterLib(__tgt_bin_desc *Desc) {
263
300
264
301
// Execute dtors for static objects if the device has been used, i.e.
265
302
// if its PendingCtors list has been emptied.
266
- for (int32_t I = 0 ; I < FoundRTL->NumberOfDevices ; ++I) {
303
+ for (int32_t I = 0 ; I < FoundRTL->getNumberOfUserDevices () ; ++I) {
267
304
auto DeviceOrErr = PM->getDevice (FoundRTL->DeviceOffset + I);
268
305
if (!DeviceOrErr)
269
306
FATAL_MESSAGE (FoundRTL->DeviceOffset + I, " %s" ,
@@ -337,17 +374,5 @@ Expected<DeviceTy &> PluginManager::getDevice(uint32_t DeviceNo) {
337
374
" Device number '%i' out of range, only %i devices available" , DeviceNo,
338
375
ExclusiveDevicesAccessor->size ());
339
376
340
- DeviceTy &Device = *(*ExclusiveDevicesAccessor)[DeviceNo];
341
-
342
- DP (" Is the device %d (local ID %d) initialized? %d\n " , DeviceNo,
343
- Device.RTLDeviceID , Device.IsInit );
344
-
345
- // Init the device if not done before
346
- if (!Device.IsInit && Device.initOnce () != OFFLOAD_SUCCESS) {
347
- return createStringError (inconvertibleErrorCode (),
348
- " Failed to init device %d\n " , DeviceNo);
349
- }
350
-
351
- DP (" Device %d is ready to use.\n " , DeviceNo);
352
- return Device;
377
+ return *(*ExclusiveDevicesAccessor)[DeviceNo];
353
378
}
0 commit comments