Skip to content

Commit dc6e68a

Browse files
committed
[Offload] Only initialize a plugin if it is needed (llvm#92765)
relands 21f3a60 [Offload] Only initialize a plugin if it is needed (llvm#92765) includes f284af [Offload][Fix] Fix lazy initialization with multiple images includes fix in patchset 3 to resolve 3 smoke tests: currently fails smoke: multi-image multi-image3 targetid_multi_image Change-Id: Ic1890f6e765fd9a91d00f1b85e36f26382b8c608
1 parent 0c9bbb8 commit dc6e68a

File tree

5 files changed

+71
-37
lines changed

5 files changed

+71
-37
lines changed

offload/plugins-nextgen/common/include/JIT.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ struct JITEngine {
5555
process(const __tgt_device_image &Image,
5656
target::plugin::GenericDeviceTy &Device);
5757

58-
/// Return true if \p Image is a bitcode image that can be JITed for the given
59-
/// architecture.
60-
Expected<bool> checkBitcodeImage(StringRef Buffer) const;
61-
6258
private:
6359
/// Compile the bitcode image \p Image and generate the binary image that can
6460
/// be loaded to the target device of the triple \p Triple architecture \p

offload/plugins-nextgen/common/include/PluginInterface.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,10 @@ struct GenericPluginTy {
11641164
/// given target. Returns true if the \p Image is compatible with the plugin.
11651165
Expected<bool> checkELFImage(StringRef Image) const;
11661166

1167+
/// Return true if the \p Image can be compiled to run on the platform's
1168+
/// target architecture.
1169+
Expected<bool> checkBitcodeImage(StringRef Image) const;
1170+
11671171
/// Indicate if an image is compatible with the plugin devices. Notice that
11681172
/// this function may be called before actually initializing the devices. So
11691173
/// we could not move this function into GenericDeviceTy.
@@ -1186,8 +1190,11 @@ struct GenericPluginTy {
11861190
public:
11871191
// TODO: This plugin interface needs to be cleaned up.
11881192

1193+
/// Returns true if the plugin has been initialized.
1194+
int32_t is_initialized() const;
1195+
11891196
/// Returns non-zero if the provided \p Image can be executed by the runtime.
1190-
int32_t is_valid_binary(__tgt_device_image *Image);
1197+
int32_t is_valid_binary(__tgt_device_image *Image, bool Initialized = true);
11911198

11921199
/// Checks if the image is not supported.
11931200
void check_invalid_image(__tgt_device_image *InvalidImage);
@@ -1352,6 +1359,9 @@ struct GenericPluginTy {
13521359
bool isEagerMaps);
13531360

13541361
private:
1362+
/// Indicates if the platform runtime has been fully initialized.
1363+
bool Initialized = false;
1364+
13551365
/// Number of devices available for the plugin.
13561366
int32_t NumDevices = 0;
13571367

offload/plugins-nextgen/common/src/JIT.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -323,19 +323,3 @@ JITEngine::process(const __tgt_device_image &Image,
323323

324324
return &Image;
325325
}
326-
327-
Expected<bool> JITEngine::checkBitcodeImage(StringRef Buffer) const {
328-
TimeTraceScope TimeScope("Check bitcode image");
329-
330-
assert(identify_magic(Buffer) == file_magic::bitcode &&
331-
"Input is not bitcode");
332-
333-
LLVMContext Context;
334-
auto ModuleOrErr = getLazyBitcodeModule(MemoryBufferRef(Buffer, ""), Context,
335-
/*ShouldLazyLoadMetadata=*/true);
336-
if (!ModuleOrErr)
337-
return ModuleOrErr.takeError();
338-
Module &M = **ModuleOrErr;
339-
340-
return Triple(M.getTargetTriple()).getArch() == TT.getArch();
341-
}

offload/plugins-nextgen/common/src/PluginInterface.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "omp-tools.h"
2828
#endif
2929

30+
#include "llvm/Bitcode/BitcodeReader.h"
3031
#include "llvm/Frontend/OpenMP/OMPConstants.h"
3132
#include "llvm/Support/Error.h"
3233
#include "llvm/Support/JSON.h"
@@ -1607,6 +1608,7 @@ Error GenericPluginTy::init() {
16071608
if (!NumDevicesOrErr)
16081609
return NumDevicesOrErr.takeError();
16091610

1611+
Initialized = true;
16101612
NumDevices = *NumDevicesOrErr;
16111613
if (NumDevices == 0)
16121614
return Plugin::success();
@@ -1692,14 +1694,27 @@ Expected<bool> GenericPluginTy::checkELFImage(StringRef Image) const {
16921694
if (!MachineOrErr)
16931695
return MachineOrErr.takeError();
16941696

1695-
if (!*MachineOrErr)
1697+
return MachineOrErr;
1698+
}
1699+
1700+
Expected<bool> GenericPluginTy::checkBitcodeImage(StringRef Image) const {
1701+
if (identify_magic(Image) != file_magic::bitcode)
16961702
return false;
16971703

1698-
// Perform plugin-dependent checks for the specific architecture if needed.
1699-
return isELFCompatible(Image);
1704+
LLVMContext Context;
1705+
auto ModuleOrErr = getLazyBitcodeModule(MemoryBufferRef(Image, ""), Context,
1706+
/*ShouldLazyLoadMetadata=*/true);
1707+
if (!ModuleOrErr)
1708+
return ModuleOrErr.takeError();
1709+
Module &M = **ModuleOrErr;
1710+
1711+
return Triple(M.getTargetTriple()).getArch() == getTripleArch();
17001712
}
17011713

1702-
int32_t GenericPluginTy::is_valid_binary(__tgt_device_image *Image) {
1714+
int32_t GenericPluginTy::is_initialized() const { return Initialized; }
1715+
1716+
int32_t GenericPluginTy::is_valid_binary(__tgt_device_image *Image,
1717+
bool Initialized) {
17031718
auto T = logger::log<int32_t>(__func__, Image);
17041719
int32_t R = [&]() {
17051720
StringRef Buffer(reinterpret_cast<const char *>(Image->ImageStart),
@@ -1719,10 +1734,25 @@ int32_t GenericPluginTy::is_valid_binary(__tgt_device_image *Image) {
17191734
auto MatchOrErr = checkELFImage(Buffer);
17201735
if (Error Err = MatchOrErr.takeError())
17211736
return HandleError(std::move(Err));
1722-
return *MatchOrErr;
1737+
if (!Initialized || !*MatchOrErr)
1738+
return *MatchOrErr;
1739+
1740+
// Perform plugin-dependent checks for the specific architecture if needed.
1741+
auto CompatibleOrErr = isELFCompatible(Buffer);
1742+
if (Error Err = CompatibleOrErr.takeError())
1743+
return HandleError(std::move(Err));
1744+
return *CompatibleOrErr;
17231745
}
1746+
case file_magic::offload_binary: {
1747+
// Perform plugin-dependent checks for the specific architecture if needed.
1748+
auto CompatibleOrErr = isELFCompatible(Buffer);
1749+
if (Error Err = CompatibleOrErr.takeError())
1750+
return HandleError(std::move(Err));
1751+
return *CompatibleOrErr;
1752+
}
1753+
17241754
case file_magic::bitcode: {
1725-
auto MatchOrErr = getJIT().checkBitcodeImage(Buffer);
1755+
auto MatchOrErr = checkBitcodeImage(Buffer);
17261756
if (Error Err = MatchOrErr.takeError())
17271757
return HandleError(std::move(Err));
17281758
return *MatchOrErr;

offload/src/PluginManager.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,8 @@ void PluginManager::init() {
3636
// Attempt to create an instance of each supported plugin.
3737
#define PLUGIN_TARGET(Name) \
3838
do { \
39-
auto Plugin = std::unique_ptr<GenericPluginTy>(createPlugin_##Name()); \
40-
if (auto Err = Plugin->init()) { \
41-
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err)); \
42-
DP("Failed to init plugin: %s\n", InfoMsg.c_str()); \
43-
} else { \
44-
DP("Registered plugin %s with %d visible device(s)\n", \
45-
Plugin->getName(), Plugin->number_of_devices()); \
46-
Plugins.emplace_back(std::move(Plugin)); \
47-
} \
39+
Plugins.emplace_back( \
40+
std::unique_ptr<GenericPluginTy>(createPlugin_##Name())); \
4841
} while (false);
4942
#include "Shared/Targets.def"
5043

@@ -199,6 +192,27 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) {
199192
if (Entry.flags == OMP_REGISTER_REQUIRES)
200193
PM->addRequirements(Entry.data);
201194

195+
// Initialize all the plugins that have associated images.
196+
for (auto &Plugin : Plugins) {
197+
// Extract the exectuable image and extra information if availible.
198+
for (int32_t i = 0; i < Desc->NumDeviceImages; ++i) {
199+
if (Plugin->is_initialized())
200+
continue;
201+
202+
if (!Plugin->is_valid_binary(&Desc->DeviceImages[i],
203+
/*Initialized=*/false))
204+
continue;
205+
206+
if (auto Err = Plugin->init()) {
207+
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
208+
DP("Failed to init plugin: %s\n", InfoMsg.c_str());
209+
} else {
210+
DP("Registered plugin %s with %d visible device(s)\n",
211+
Plugin->getName(), Plugin->number_of_devices());
212+
}
213+
}
214+
}
215+
202216
// Extract the exectuable image and extra information if availible.
203217
for (int32_t i = 0; i < Desc->NumDeviceImages; ++i)
204218
PM->addDeviceImage(*Desc, Desc->DeviceImages[i]);
@@ -217,7 +231,7 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) {
217231
if (!R.number_of_devices())
218232
continue;
219233

220-
if (!R.is_valid_binary(Img)) {
234+
if (!R.is_valid_binary(Img, /*Initialized=*/true)) {
221235
DP("Image " DPxMOD " is NOT compatible with RTL %s!\n",
222236
DPxPTR(Img->ImageStart), R.getName());
223237
continue;

0 commit comments

Comments
 (0)