[Offload][L0] Add support for OffloadBinary format in L0 plugin (#185404)
- Accept OffloadBinaries as valid images by plugins that support them in the PluginInterface. - Add support in L0 plugin to extract SPIRV images and their associated metadata from an OffloadBinary image. Depends on: - #185663 Follow-up PRs: - #185413 (Changes SPIRV wrapper generation to use OffloadBinary) - #185425 (Adjusts llvm-objdump) - #184774 (Adjusts llvm-offload-binary)
This commit is contained in:
parent
1ae518aa76
commit
3ff332ad0f
@ -18,6 +18,8 @@
|
||||
#include "L0Plugin.h"
|
||||
#include "L0Trace.h"
|
||||
|
||||
#include "llvm/Object/OffloadBinary.h"
|
||||
|
||||
namespace llvm::omp::target::plugin {
|
||||
|
||||
using namespace llvm::omp::target;
|
||||
@ -161,6 +163,42 @@ Expected<bool> LevelZeroPluginTy::isELFCompatible(uint32_t DeviceId,
|
||||
return isValidOneOmpImage(Image, MajorVer, MinorVer);
|
||||
}
|
||||
|
||||
// We only need to check for formats other than ELF here.
|
||||
Expected<bool> LevelZeroPluginTy::isImageCompatible(StringRef Image) const {
|
||||
switch (identify_magic(Image)) {
|
||||
case file_magic::spirv_object:
|
||||
// Handle SPIRV objects directly
|
||||
return true;
|
||||
case file_magic::offload_binary: {
|
||||
// Handle OffloadBinary format
|
||||
MemoryBufferRef Buffer(Image, "offload_binary");
|
||||
auto BinariesOrErr = OffloadBinary::create(Buffer);
|
||||
if (!BinariesOrErr)
|
||||
return BinariesOrErr.takeError();
|
||||
|
||||
auto &Binaries = *BinariesOrErr;
|
||||
if (Binaries.size() != 1)
|
||||
return false;
|
||||
|
||||
const OffloadBinary *InnerBinary = Binaries[0].get();
|
||||
ImageKind ImageKind = InnerBinary->getImageKind();
|
||||
llvm::Triple Triple(InnerBinary->getTriple());
|
||||
|
||||
if (Triple.getArch() != getTripleArch())
|
||||
return false;
|
||||
|
||||
if (ImageKind != llvm::object::IMG_SPIRV &&
|
||||
ImageKind != llvm::object::IMG_Object)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// Unknown format
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Error LevelZeroPluginTy::syncBarrierImpl(omp_interop_val_t *Interop) {
|
||||
if (!Interop) {
|
||||
return Plugin::error(ErrorCode::INVALID_ARGUMENT,
|
||||
|
||||
@ -215,8 +215,76 @@ bool isValidOneOmpImage(StringRef Image, uint64_t &MajorVer,
|
||||
Error L0ProgramBuilderTy::buildModules(const std::string_view BuildOptions) {
|
||||
auto &l0Device = getL0Device();
|
||||
auto Image = getMemoryBuffer();
|
||||
|
||||
// Check if image is an inner OffloadBinary (nested format)
|
||||
if (identify_magic(Image.getBuffer()) == file_magic::offload_binary) {
|
||||
ODBG(OLDT_Module) << "Processing nested OffloadBinary image";
|
||||
|
||||
// Parse inner OffloadBinary
|
||||
auto InnerBinariesOrErr = llvm::object::OffloadBinary::create(Image);
|
||||
if (!InnerBinariesOrErr)
|
||||
return Plugin::error(
|
||||
ErrorCode::UNKNOWN, "Failed to parse inner OffloadBinary: %s",
|
||||
llvm::toString(InnerBinariesOrErr.takeError()).c_str());
|
||||
|
||||
auto &InnerBinaries = *InnerBinariesOrErr;
|
||||
|
||||
// Should contain exactly one image
|
||||
if (InnerBinaries.size() != 1)
|
||||
return Plugin::error(ErrorCode::UNKNOWN,
|
||||
"Expected single inner OffloadBinary entry, got %zu",
|
||||
InnerBinaries.size());
|
||||
|
||||
const llvm::object::OffloadBinary *InnerBinary = InnerBinaries[0].get();
|
||||
llvm::object::ImageKind ImageKind = InnerBinary->getImageKind();
|
||||
|
||||
// Extract image data from inner binary
|
||||
llvm::StringRef ImageData = InnerBinary->getImage();
|
||||
const uint8_t *ImgBegin =
|
||||
reinterpret_cast<const uint8_t *>(ImageData.data());
|
||||
|
||||
// Read metadata from inner binary
|
||||
llvm::StringRef Version = InnerBinary->getString("version");
|
||||
llvm::StringRef CompileOpts = InnerBinary->getString("compile-opts");
|
||||
llvm::StringRef LinkOpts = InnerBinary->getString("link-opts");
|
||||
|
||||
ODBG(OLDT_Module) << "Inner OffloadBinary metadata: version=" << Version
|
||||
<< ", kind=" << ImageKind;
|
||||
|
||||
// Build options string combining BuildOptions with compile/link opts
|
||||
std::string Options(BuildOptions);
|
||||
if (!CompileOpts.empty() || !LinkOpts.empty()) {
|
||||
if (!CompileOpts.empty())
|
||||
Options += " " + CompileOpts.str();
|
||||
if (!LinkOpts.empty())
|
||||
Options += " " + LinkOpts.str();
|
||||
replaceDriverOptsWithBackendOpts(l0Device, Options);
|
||||
ODBG(OLDT_Module) << "Using compile options: " << CompileOpts
|
||||
<< ", link options: " << LinkOpts;
|
||||
}
|
||||
|
||||
// Determine module format based on image kind
|
||||
ze_module_format_t ModuleFormat;
|
||||
if (ImageKind == llvm::object::IMG_SPIRV) {
|
||||
// SPIR-V intermediate language
|
||||
ODBG(OLDT_Module) << "Loading SPIR-V module";
|
||||
ModuleFormat = ZE_MODULE_FORMAT_IL_SPIRV;
|
||||
} else if (ImageKind == llvm::object::IMG_Object) {
|
||||
// Native binary format
|
||||
ODBG(OLDT_Module) << "Loading native binary module";
|
||||
ModuleFormat = ZE_MODULE_FORMAT_NATIVE;
|
||||
} else {
|
||||
return Plugin::error(ErrorCode::UNKNOWN,
|
||||
"Unsupported image kind %d in inner OffloadBinary",
|
||||
static_cast<int>(ImageKind));
|
||||
}
|
||||
|
||||
// Load module into Level Zero
|
||||
return addModule(ImageData.size(), ImgBegin, Options, ModuleFormat);
|
||||
}
|
||||
|
||||
if (identify_magic(Image.getBuffer()) == file_magic::spirv_object) {
|
||||
// Handle legacy plain SPIR-V image.
|
||||
ODBG(OLDT_Module) << "Processing raw SPIR-V image";
|
||||
const uint8_t *ImgBegin =
|
||||
reinterpret_cast<const uint8_t *>(Image.getBufferStart());
|
||||
return addModule(Image.getBufferSize(), ImgBegin, BuildOptions,
|
||||
@ -228,6 +296,7 @@ Error L0ProgramBuilderTy::buildModules(const std::string_view BuildOptions) {
|
||||
ODBG(OLDT_Module) << "Warning: image is not a valid oneAPI OpenMP image.";
|
||||
return Plugin::error(ErrorCode::UNKNOWN, "Invalid oneAPI OpenMP image");
|
||||
}
|
||||
ODBG(OLDT_Module) << "Processing ELF-wrapped SPIR-V image";
|
||||
|
||||
// Iterate over the images and pick the first one that fits.
|
||||
uint64_t ImageCount = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user