-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[OpenMP] Reorganize the initialization of PluginAdaptorTy
#74397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
|
||
#include "llvm/Support/Error.h" | ||
#include "llvm/Support/ErrorHandling.h" | ||
#include <memory> | ||
|
||
using namespace llvm; | ||
using namespace llvm::sys; | ||
|
@@ -30,27 +31,43 @@ static const char *RTLNames[] = { | |
/* AMDGPU target */ "libomptarget.rtl.amdgpu", | ||
}; | ||
|
||
PluginAdaptorTy::PluginAdaptorTy(const std::string &Name) : Name(Name) { | ||
Expected<std::unique_ptr<PluginAdaptorTy>> | ||
PluginAdaptorTy::create(const std::string &Name) { | ||
DP("Attempting to load library '%s'...\n", Name.c_str()); | ||
|
||
std::string ErrMsg; | ||
LibraryHandler = std::make_unique<DynamicLibrary>( | ||
auto LibraryHandler = std::make_unique<DynamicLibrary>( | ||
DynamicLibrary::getPermanentLibrary(Name.c_str(), &ErrMsg)); | ||
|
||
if (!LibraryHandler->isValid()) { | ||
// Library does not exist or cannot be found. | ||
DP("Unable to load library '%s': %s!\n", Name.c_str(), ErrMsg.c_str()); | ||
return; | ||
return createStringError(inconvertibleErrorCode(), | ||
"Unable to load library '%s': %s!\n", Name.c_str(), | ||
ErrMsg.c_str()); | ||
} | ||
|
||
DP("Successfully loaded library '%s'!\n", Name.c_str()); | ||
auto PluginAdaptor = std::unique_ptr<PluginAdaptorTy>( | ||
new PluginAdaptorTy(Name, std::move(LibraryHandler))); | ||
if (auto Err = PluginAdaptor->init()) | ||
return Err; | ||
return PluginAdaptor; | ||
} | ||
|
||
PluginAdaptorTy::PluginAdaptorTy(const std::string &Name, | ||
std::unique_ptr<llvm::sys::DynamicLibrary> DL) | ||
: Name(Name), LibraryHandler(std::move(DL)) {} | ||
|
||
Error PluginAdaptorTy::init() { | ||
|
||
#define PLUGIN_API_HANDLE(NAME, MANDATORY) \ | ||
NAME = reinterpret_cast<decltype(NAME)>( \ | ||
LibraryHandler->getAddressOfSymbol(GETNAME(__tgt_rtl_##NAME))); \ | ||
if (MANDATORY && !NAME) { \ | ||
DP("Invalid plugin as necessary interface is not found.\n"); \ | ||
return; \ | ||
return createStringError(inconvertibleErrorCode(), \ | ||
"Invalid plugin as necessary interface function " \ | ||
"(%s) was not found.\n", \ | ||
NAME); \ | ||
} | ||
|
||
#include "Shared/PluginAPI.inc" | ||
|
@@ -59,22 +76,25 @@ PluginAdaptorTy::PluginAdaptorTy(const std::string &Name) : Name(Name) { | |
// Remove plugin on failure to call optional init_plugin | ||
int32_t Rc = init_plugin(); | ||
if (Rc != OFFLOAD_SUCCESS) { | ||
DP("Unable to initialize library '%s': %u!\n", Name.c_str(), Rc); | ||
return; | ||
return createStringError(inconvertibleErrorCode(), | ||
"Unable to initialize library '%s': %u!\n", | ||
Name.c_str(), Rc); | ||
} | ||
|
||
// No devices are supported by this RTL? | ||
NumberOfDevices = number_of_devices(); | ||
if (!NumberOfDevices) { | ||
DP("No devices supported in this RTL\n"); | ||
return; | ||
NumberOfPluginDevices = number_of_devices(); | ||
if (!NumberOfPluginDevices) { | ||
return createStringError(inconvertibleErrorCode(), | ||
"No devices supported in this RTL\n"); | ||
} | ||
|
||
DP("Registered '%s' with %d devices!\n", Name.c_str(), NumberOfDevices); | ||
DP("Registered '%s' with %d plugin visible devices!\n", Name.c_str(), | ||
NumberOfPluginDevices); | ||
return Error::success(); | ||
} | ||
|
||
void PluginAdaptorTy::addOffloadEntries(DeviceImageTy &DI) { | ||
for (int32_t I = 0; I < NumberOfDevices; ++I) { | ||
for (int32_t I = 0, E = getNumberOfUserDevices(); I < E; ++I) { | ||
auto DeviceOrErr = PM->getDevice(DeviceOffset + I); | ||
if (!DeviceOrErr) | ||
FATAL_MESSAGE(DeviceOffset + I, "%s", | ||
|
@@ -92,45 +112,61 @@ void PluginManager::init() { | |
// Attempt to open all the plugins and, if they exist, check if the interface | ||
// is correct and if they are supporting any devices. | ||
for (const char *Name : RTLNames) { | ||
PluginAdaptors.emplace_back(std::string(Name) + ".so"); | ||
if (PluginAdaptors.back().getNumDevices() <= 0) | ||
PluginAdaptors.pop_back(); | ||
auto PluginAdaptorOrErr = | ||
PluginAdaptorTy::create(std::string(Name) + ".so"); | ||
if (!PluginAdaptorOrErr) { | ||
[[maybe_unused]] std::string InfoMsg = | ||
toString(PluginAdaptorOrErr.takeError()); | ||
DP("%s", InfoMsg.c_str()); | ||
} else { | ||
PluginAdaptors.push_back(std::move(*PluginAdaptorOrErr)); | ||
} | ||
} | ||
|
||
DP("RTLs loaded!\n"); | ||
} | ||
|
||
void PluginManager::initPlugin(PluginAdaptorTy &Plugin) { | ||
// If this RTL is not already in use, initialize it. | ||
if (Plugin.isUsed() || !Plugin.NumberOfDevices) | ||
void PluginAdaptorTy::initDevices(PluginManager &PM) { | ||
if (isUsed()) | ||
return; | ||
|
||
// If this RTL is not already in use, initialize it. | ||
assert(getNumberOfPluginDevices() > 0 && | ||
"Tried to initialize useless plugin adaptor"); | ||
|
||
// Initialize the device information for the RTL we are about to use. | ||
auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); | ||
const size_t Start = ExclusiveDevicesAccessor->size(); | ||
ExclusiveDevicesAccessor->reserve(Start + Plugin.NumberOfDevices); | ||
for (int32_t DeviceId = 0; DeviceId < Plugin.NumberOfDevices; DeviceId++) { | ||
ExclusiveDevicesAccessor->push_back(std::make_unique<DeviceTy>(&Plugin)); | ||
// global device ID | ||
(*ExclusiveDevicesAccessor)[Start + DeviceId]->DeviceID = Start + DeviceId; | ||
// RTL local device ID | ||
(*ExclusiveDevicesAccessor)[Start + DeviceId]->RTLDeviceID = DeviceId; | ||
} | ||
auto ExclusiveDevicesAccessor = PM.getExclusiveDevicesAccessor(); | ||
|
||
// Initialize the index of this RTL and save it in the used RTLs. | ||
Plugin.DeviceOffset = Start; | ||
DeviceOffset = ExclusiveDevicesAccessor->size(); | ||
|
||
// If possible, set the device identifier offset in the plugin. | ||
if (Plugin.set_device_offset) | ||
Plugin.set_device_offset(Start); | ||
if (set_device_offset) | ||
set_device_offset(DeviceOffset); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this function named this way? This function is not like some others that are actually function pointers of C library/plugin functions. Of course it is not this patch's issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is like the others. I moved it into the PluginAdaptorTy so it checks the function pointer and calls it, like other plugin functions. |
||
|
||
int32_t NumPD = getNumberOfPluginDevices(); | ||
ExclusiveDevicesAccessor->reserve(DeviceOffset + NumPD); | ||
for (int32_t PDevI = 0, UserDevId = DeviceOffset; PDevI < NumPD; PDevI++) { | ||
auto Device = std::make_unique<DeviceTy>(this, UserDevId, PDevI); | ||
if (auto Err = Device->init()) { | ||
DP("Skip plugin known device %d: %s\n", PDevI, | ||
toString(std::move(Err)).c_str()); | ||
continue; | ||
} | ||
|
||
ExclusiveDevicesAccessor->push_back(std::move(Device)); | ||
++NumberOfUserDevices; | ||
++UserDevId; | ||
} | ||
|
||
DP("RTL " DPxMOD " has index %d!\n", DPxPTR(Plugin.LibraryHandler.get()), | ||
Plugin.DeviceOffset); | ||
DP("Plugin adaptor " DPxMOD " has index %d, exposes %d out of %d devices!\n", | ||
DPxPTR(LibraryHandler.get()), DeviceOffset, NumberOfUserDevices, | ||
NumberOfPluginDevices); | ||
} | ||
|
||
void PluginManager::initAllPlugins() { | ||
for (auto &R : PluginAdaptors) | ||
initPlugin(R); | ||
R->initDevices(*this); | ||
} | ||
|
||
static void registerImageIntoTranslationTable(TranslationTable &TT, | ||
|
@@ -143,15 +179,16 @@ static void registerImageIntoTranslationTable(TranslationTable &TT, | |
|
||
// Resize the Targets Table and Images to accommodate the new targets if | ||
// required | ||
unsigned TargetsTableMinimumSize = RTL.DeviceOffset + RTL.NumberOfDevices; | ||
unsigned TargetsTableMinimumSize = | ||
RTL.DeviceOffset + RTL.getNumberOfUserDevices(); | ||
|
||
if (TT.TargetsTable.size() < TargetsTableMinimumSize) { | ||
TT.TargetsImages.resize(TargetsTableMinimumSize, 0); | ||
TT.TargetsTable.resize(TargetsTableMinimumSize, 0); | ||
} | ||
|
||
// Register the image in all devices for this target type. | ||
for (int32_t I = 0; I < RTL.NumberOfDevices; ++I) { | ||
for (int32_t I = 0; I < RTL.getNumberOfUserDevices(); ++I) { | ||
// If we are changing the image we are also invalidating the target table. | ||
if (TT.TargetsImages[RTL.DeviceOffset + I] != Image) { | ||
TT.TargetsImages[RTL.DeviceOffset + I] = Image; | ||
|
@@ -194,7 +231,7 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) { | |
DP("Image " DPxMOD " is compatible with RTL %s!\n", | ||
DPxPTR(Img->ImageStart), R.Name.c_str()); | ||
|
||
PM->initPlugin(R); | ||
R.initDevices(*this); | ||
|
||
// Initialize (if necessary) translation table for this library. | ||
PM->TrlTblMtx.lock(); | ||
|
@@ -263,7 +300,7 @@ void PluginManager::unregisterLib(__tgt_bin_desc *Desc) { | |
|
||
// Execute dtors for static objects if the device has been used, i.e. | ||
// if its PendingCtors list has been emptied. | ||
for (int32_t I = 0; I < FoundRTL->NumberOfDevices; ++I) { | ||
for (int32_t I = 0; I < FoundRTL->getNumberOfUserDevices(); ++I) { | ||
auto DeviceOrErr = PM->getDevice(FoundRTL->DeviceOffset + I); | ||
if (!DeviceOrErr) | ||
FATAL_MESSAGE(FoundRTL->DeviceOffset + I, "%s", | ||
|
@@ -337,17 +374,5 @@ Expected<DeviceTy &> PluginManager::getDevice(uint32_t DeviceNo) { | |
"Device number '%i' out of range, only %i devices available", DeviceNo, | ||
ExclusiveDevicesAccessor->size()); | ||
|
||
DeviceTy &Device = *(*ExclusiveDevicesAccessor)[DeviceNo]; | ||
|
||
DP("Is the device %d (local ID %d) initialized? %d\n", DeviceNo, | ||
Device.RTLDeviceID, Device.IsInit); | ||
|
||
// Init the device if not done before | ||
if (!Device.IsInit && Device.initOnce() != OFFLOAD_SUCCESS) { | ||
return createStringError(inconvertibleErrorCode(), | ||
"Failed to init device %d\n", DeviceNo); | ||
} | ||
|
||
DP("Device %d is ready to use.\n", DeviceNo); | ||
return Device; | ||
return *(*ExclusiveDevicesAccessor)[DeviceNo]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why has this changed? It looks unrelated.