diff --git a/openmp/libomptarget/include/PluginManager.h b/openmp/libomptarget/include/PluginManager.h index e5a41a0f329d0..94ecce01ca74c 100644 --- a/openmp/libomptarget/include/PluginManager.h +++ b/openmp/libomptarget/include/PluginManager.h @@ -73,25 +73,17 @@ struct PluginAdaptorTy { std::mutex Mtx; }; -/// RTLs identified in the system. -struct PluginAdaptorManagerTy { - explicit PluginAdaptorManagerTy() = default; - - // Register a shared library with all (compatible) RTLs. - void registerLib(__tgt_bin_desc *Desc); - - // Unregister a shared library from all RTLs. - void unregisterLib(__tgt_bin_desc *Desc); -}; - /// Struct for the data required to handle plugins struct PluginManager { PluginManager() {} void init(); - /// RTLs identified on the host - PluginAdaptorManagerTy RTLs; + // Register a shared library with all (compatible) RTLs. + void registerLib(__tgt_bin_desc *Desc); + + // Unregister a shared library from all RTLs. + void unregisterLib(__tgt_bin_desc *Desc); void addDeviceImage(__tgt_bin_desc &TgtBinDesc, __tgt_device_image &TgtDeviceImage) { DeviceImages.emplace_back(std::make_unique(TgtBinDesc, TgtDeviceImage)); diff --git a/openmp/libomptarget/src/PluginManager.cpp b/openmp/libomptarget/src/PluginManager.cpp index ec29a3db956b6..e6dedeb699b14 100644 --- a/openmp/libomptarget/src/PluginManager.cpp +++ b/openmp/libomptarget/src/PluginManager.cpp @@ -122,3 +122,194 @@ void PluginManager::initAllPlugins() { for (auto &R : PluginAdaptors) initPlugin(R); } + +static void registerImageIntoTranslationTable(TranslationTable &TT, + PluginAdaptorTy &RTL, + __tgt_device_image *Image) { + + // same size, as when we increase one, we also increase the other. + assert(TT.TargetsTable.size() == TT.TargetsImages.size() && + "We should have as many images as we have tables!"); + + // Resize the Targets Table and Images to accommodate the new targets if + // required + unsigned TargetsTableMinimumSize = RTL.DeviceOffset + RTL.NumberOfDevices; + + 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) { + // 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; + TT.TargetsTable[RTL.DeviceOffset + I] = + 0; // lazy initialization of target table. + } + } +} + +void PluginManager::registerLib(__tgt_bin_desc *Desc) { + PM->RTLsMtx.lock(); + + // Extract the exectuable image and extra information if availible. + for (int32_t i = 0; i < Desc->NumDeviceImages; ++i) + PM->addDeviceImage(*Desc, Desc->DeviceImages[i]); + + // Register the images with the RTLs that understand them, if any. + for (DeviceImageTy &DI : PM->deviceImages()) { + // Obtain the image and information that was previously extracted. + __tgt_device_image *Img = &DI.getExecutableImage(); + __tgt_image_info *Info = &DI.getImageInfo(); + + PluginAdaptorTy *FoundRTL = nullptr; + + // Scan the RTLs that have associated images until we find one that supports + // the current image. + for (auto &R : PM->pluginAdaptors()) { + if (R.is_valid_binary_info) { + if (!R.is_valid_binary_info(Img, Info)) { + DP("Image " DPxMOD " is NOT compatible with RTL %s!\n", + DPxPTR(Img->ImageStart), R.Name.c_str()); + continue; + } + } else if (!R.is_valid_binary(Img)) { + DP("Image " DPxMOD " is NOT compatible with RTL %s!\n", + DPxPTR(Img->ImageStart), R.Name.c_str()); + continue; + } + + DP("Image " DPxMOD " is compatible with RTL %s!\n", + DPxPTR(Img->ImageStart), R.Name.c_str()); + + PM->initPlugin(R); + + // Initialize (if necessary) translation table for this library. + PM->TrlTblMtx.lock(); + if (!PM->HostEntriesBeginToTransTable.count(Desc->HostEntriesBegin)) { + PM->HostEntriesBeginRegistrationOrder.push_back(Desc->HostEntriesBegin); + TranslationTable &TransTable = + (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin]; + TransTable.HostTable.EntriesBegin = Desc->HostEntriesBegin; + TransTable.HostTable.EntriesEnd = Desc->HostEntriesEnd; + } + + // Retrieve translation table for this library. + TranslationTable &TransTable = + (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin]; + + DP("Registering image " DPxMOD " with RTL %s!\n", DPxPTR(Img->ImageStart), + R.Name.c_str()); + registerImageIntoTranslationTable(TransTable, R, Img); + R.UsedImages.insert(Img); + + PM->TrlTblMtx.unlock(); + FoundRTL = &R; + + // Register all offload entries with the devices handled by the plugin. + R.addOffloadEntries(DI); + + // if an RTL was found we are done - proceed to register the next image + break; + } + + if (!FoundRTL) { + DP("No RTL found for image " DPxMOD "!\n", DPxPTR(Img->ImageStart)); + } + } + PM->RTLsMtx.unlock(); + + DP("Done registering entries!\n"); +} + +// Temporary forward declaration, old style CTor/DTor handling is going away. +int target(ident_t *Loc, DeviceTy &Device, void *HostPtr, + KernelArgsTy &KernelArgs, AsyncInfoTy &AsyncInfo); + +void PluginManager::unregisterLib(__tgt_bin_desc *Desc) { + DP("Unloading target library!\n"); + + PM->RTLsMtx.lock(); + // Find which RTL understands each image, if any. + for (DeviceImageTy &DI : PM->deviceImages()) { + // Obtain the image and information that was previously extracted. + __tgt_device_image *Img = &DI.getExecutableImage(); + + PluginAdaptorTy *FoundRTL = NULL; + + // Scan the RTLs that have associated images until we find one that supports + // the current image. We only need to scan RTLs that are already being used. + for (auto &R : PM->pluginAdaptors()) { + if (!R.isUsed()) + continue; + + // Ensure that we do not use any unused images associated with this RTL. + if (!R.UsedImages.contains(Img)) + continue; + + FoundRTL = &R; + + // 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) { + DeviceTy &Device = *PM->Devices[FoundRTL->DeviceOffset + I]; + Device.PendingGlobalsMtx.lock(); + if (Device.PendingCtorsDtors[Desc].PendingCtors.empty()) { + AsyncInfoTy AsyncInfo(Device); + for (auto &Dtor : Device.PendingCtorsDtors[Desc].PendingDtors) { + int Rc = + target(nullptr, Device, Dtor, CTorDTorKernelArgs, AsyncInfo); + if (Rc != OFFLOAD_SUCCESS) { + DP("Running destructor " DPxMOD " failed.\n", DPxPTR(Dtor)); + } + } + // Remove this library's entry from PendingCtorsDtors + Device.PendingCtorsDtors.erase(Desc); + // All constructors have been issued, wait for them now. + if (AsyncInfo.synchronize() != OFFLOAD_SUCCESS) + DP("Failed synchronizing destructors kernels.\n"); + } + Device.PendingGlobalsMtx.unlock(); + } + + DP("Unregistered image " DPxMOD " from RTL " DPxMOD "!\n", + DPxPTR(Img->ImageStart), DPxPTR(R.LibraryHandler.get())); + + break; + } + + // if no RTL was found proceed to unregister the next image + if (!FoundRTL) { + DP("No RTLs in use support the image " DPxMOD "!\n", + DPxPTR(Img->ImageStart)); + } + } + PM->RTLsMtx.unlock(); + DP("Done unregistering images!\n"); + + // Remove entries from PM->HostPtrToTableMap + PM->TblMapMtx.lock(); + for (__tgt_offload_entry *Cur = Desc->HostEntriesBegin; + Cur < Desc->HostEntriesEnd; ++Cur) { + PM->HostPtrToTableMap.erase(Cur->addr); + } + + // Remove translation table for this descriptor. + auto TransTable = + PM->HostEntriesBeginToTransTable.find(Desc->HostEntriesBegin); + if (TransTable != PM->HostEntriesBeginToTransTable.end()) { + DP("Removing translation table for descriptor " DPxMOD "\n", + DPxPTR(Desc->HostEntriesBegin)); + PM->HostEntriesBeginToTransTable.erase(TransTable); + } else { + DP("Translation table for descriptor " DPxMOD " cannot be found, probably " + "it has been already removed.\n", + DPxPTR(Desc->HostEntriesBegin)); + } + + PM->TblMapMtx.unlock(); + + DP("Done unregistering library!\n"); +} diff --git a/openmp/libomptarget/src/interface.cpp b/openmp/libomptarget/src/interface.cpp index 2266dd039636b..62cf2262deb62 100644 --- a/openmp/libomptarget/src/interface.cpp +++ b/openmp/libomptarget/src/interface.cpp @@ -49,7 +49,7 @@ EXTERN void __tgt_register_lib(__tgt_bin_desc *Desc) { if (PM->delayRegisterLib(Desc)) return; - PM->RTLs.registerLib(Desc); + PM->registerLib(Desc); } //////////////////////////////////////////////////////////////////////////////// @@ -60,7 +60,7 @@ EXTERN void __tgt_init_all_rtls() { PM->initAllPlugins(); } /// unloads a target shared library EXTERN void __tgt_unregister_lib(__tgt_bin_desc *Desc) { TIMESCOPE(); - PM->RTLs.unregisterLib(Desc); + PM->unregisterLib(Desc); } template diff --git a/openmp/libomptarget/src/rtl.cpp b/openmp/libomptarget/src/rtl.cpp index f81baaa40bfdc..5eb1c553df491 100644 --- a/openmp/libomptarget/src/rtl.cpp +++ b/openmp/libomptarget/src/rtl.cpp @@ -58,193 +58,3 @@ __attribute__((destructor(101))) void deinit() { DP("Deinit target library!\n"); delete PM; } - -//////////////////////////////////////////////////////////////////////////////// -// Functionality for registering libs - -static void registerImageIntoTranslationTable(TranslationTable &TT, - PluginAdaptorTy &RTL, - __tgt_device_image *Image) { - - // same size, as when we increase one, we also increase the other. - assert(TT.TargetsTable.size() == TT.TargetsImages.size() && - "We should have as many images as we have tables!"); - - // Resize the Targets Table and Images to accommodate the new targets if - // required - unsigned TargetsTableMinimumSize = RTL.DeviceOffset + RTL.NumberOfDevices; - - 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) { - // 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; - TT.TargetsTable[RTL.DeviceOffset + I] = - 0; // lazy initialization of target table. - } - } -} - -void PluginAdaptorManagerTy::registerLib(__tgt_bin_desc *Desc) { - PM->RTLsMtx.lock(); - - // Extract the exectuable image and extra information if availible. - for (int32_t i = 0; i < Desc->NumDeviceImages; ++i) - PM->addDeviceImage(*Desc, Desc->DeviceImages[i]); - - // Register the images with the RTLs that understand them, if any. - for (DeviceImageTy &DI : PM->deviceImages()) { - // Obtain the image and information that was previously extracted. - __tgt_device_image *Img = &DI.getExecutableImage(); - __tgt_image_info *Info = &DI.getImageInfo(); - - PluginAdaptorTy *FoundRTL = nullptr; - - // Scan the RTLs that have associated images until we find one that supports - // the current image. - for (auto &R : PM->pluginAdaptors()) { - if (R.is_valid_binary_info) { - if (!R.is_valid_binary_info(Img, Info)) { - DP("Image " DPxMOD " is NOT compatible with RTL %s!\n", - DPxPTR(Img->ImageStart), R.Name.c_str()); - continue; - } - } else if (!R.is_valid_binary(Img)) { - DP("Image " DPxMOD " is NOT compatible with RTL %s!\n", - DPxPTR(Img->ImageStart), R.Name.c_str()); - continue; - } - - DP("Image " DPxMOD " is compatible with RTL %s!\n", - DPxPTR(Img->ImageStart), R.Name.c_str()); - - PM->initPlugin(R); - - // Initialize (if necessary) translation table for this library. - PM->TrlTblMtx.lock(); - if (!PM->HostEntriesBeginToTransTable.count(Desc->HostEntriesBegin)) { - PM->HostEntriesBeginRegistrationOrder.push_back(Desc->HostEntriesBegin); - TranslationTable &TransTable = - (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin]; - TransTable.HostTable.EntriesBegin = Desc->HostEntriesBegin; - TransTable.HostTable.EntriesEnd = Desc->HostEntriesEnd; - } - - // Retrieve translation table for this library. - TranslationTable &TransTable = - (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin]; - - DP("Registering image " DPxMOD " with RTL %s!\n", DPxPTR(Img->ImageStart), - R.Name.c_str()); - registerImageIntoTranslationTable(TransTable, R, Img); - R.UsedImages.insert(Img); - - PM->TrlTblMtx.unlock(); - FoundRTL = &R; - - // Register all offload entries with the devices handled by the plugin. - R.addOffloadEntries(DI); - - // if an RTL was found we are done - proceed to register the next image - break; - } - - if (!FoundRTL) { - DP("No RTL found for image " DPxMOD "!\n", DPxPTR(Img->ImageStart)); - } - } - PM->RTLsMtx.unlock(); - - DP("Done registering entries!\n"); -} - -void PluginAdaptorManagerTy::unregisterLib(__tgt_bin_desc *Desc) { - DP("Unloading target library!\n"); - - PM->RTLsMtx.lock(); - // Find which RTL understands each image, if any. - for (DeviceImageTy &DI : PM->deviceImages()) { - // Obtain the image and information that was previously extracted. - __tgt_device_image *Img = &DI.getExecutableImage(); - - PluginAdaptorTy *FoundRTL = NULL; - - // Scan the RTLs that have associated images until we find one that supports - // the current image. We only need to scan RTLs that are already being used. - for (auto &R : PM->pluginAdaptors()) { - if (!R.isUsed()) - continue; - - // Ensure that we do not use any unused images associated with this RTL. - if (!R.UsedImages.contains(Img)) - continue; - - FoundRTL = &R; - - // 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) { - DeviceTy &Device = *PM->Devices[FoundRTL->DeviceOffset + I]; - Device.PendingGlobalsMtx.lock(); - if (Device.PendingCtorsDtors[Desc].PendingCtors.empty()) { - AsyncInfoTy AsyncInfo(Device); - for (auto &Dtor : Device.PendingCtorsDtors[Desc].PendingDtors) { - int Rc = - target(nullptr, Device, Dtor, CTorDTorKernelArgs, AsyncInfo); - if (Rc != OFFLOAD_SUCCESS) { - DP("Running destructor " DPxMOD " failed.\n", DPxPTR(Dtor)); - } - } - // Remove this library's entry from PendingCtorsDtors - Device.PendingCtorsDtors.erase(Desc); - // All constructors have been issued, wait for them now. - if (AsyncInfo.synchronize() != OFFLOAD_SUCCESS) - DP("Failed synchronizing destructors kernels.\n"); - } - Device.PendingGlobalsMtx.unlock(); - } - - DP("Unregistered image " DPxMOD " from RTL " DPxMOD "!\n", - DPxPTR(Img->ImageStart), DPxPTR(R.LibraryHandler.get())); - - break; - } - - // if no RTL was found proceed to unregister the next image - if (!FoundRTL) { - DP("No RTLs in use support the image " DPxMOD "!\n", - DPxPTR(Img->ImageStart)); - } - } - PM->RTLsMtx.unlock(); - DP("Done unregistering images!\n"); - - // Remove entries from PM->HostPtrToTableMap - PM->TblMapMtx.lock(); - for (__tgt_offload_entry *Cur = Desc->HostEntriesBegin; - Cur < Desc->HostEntriesEnd; ++Cur) { - PM->HostPtrToTableMap.erase(Cur->addr); - } - - // Remove translation table for this descriptor. - auto TransTable = - PM->HostEntriesBeginToTransTable.find(Desc->HostEntriesBegin); - if (TransTable != PM->HostEntriesBeginToTransTable.end()) { - DP("Removing translation table for descriptor " DPxMOD "\n", - DPxPTR(Desc->HostEntriesBegin)); - PM->HostEntriesBeginToTransTable.erase(TransTable); - } else { - DP("Translation table for descriptor " DPxMOD " cannot be found, probably " - "it has been already removed.\n", - DPxPTR(Desc->HostEntriesBegin)); - } - - PM->TblMapMtx.unlock(); - - DP("Done unregistering library!\n"); -}