summaryrefslogtreecommitdiff
path: root/offload/liboffload
diff options
context:
space:
mode:
authorJoseph Huber <huberjn@outlook.com>2025-09-16 08:57:28 -0500
committerGitHub <noreply@github.com>2025-09-16 08:57:28 -0500
commite7101dac9cbdad08696a05b4b73ed76c20a6f2fc (patch)
treecc5ffdc7dc109152767e8200fd0754f889d0f789 /offload/liboffload
parent311d78f2a1d80fd6b7700a0199c146accd2c7d3c (diff)
[Offload] Copy loaded images into managed storage (#158748)
Summary: Currently we have this `__tgt_device_image` indirection which just takes a reference to some pointers. This was all find and good when the only usage of this was from a section of GPU code that came from an ELF constant section. However, we have expanded beyond that and now need to worry about managing lifetimes. We have code that references the image even after it was loaded internally. This patch changes the implementation to instaed copy the memory buffer and manage it locally. This PR reworks the JIT and other image handling to directly manage its own memory. We now don't need to duplicate this behavior externally at the Offload API level. Also we actually free these if the user unloads them. Upside, less likely to crash and burn. Downside, more latency when loading an image.
Diffstat (limited to 'offload/liboffload')
-rw-r--r--offload/liboffload/src/OffloadImpl.cpp35
1 files changed, 9 insertions, 26 deletions
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 7e8e297831f4..b5b9b0e83b97 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -157,14 +157,11 @@ struct ol_event_impl_t {
struct ol_program_impl_t {
ol_program_impl_t(plugin::DeviceImageTy *Image,
- std::unique_ptr<llvm::MemoryBuffer> ImageData,
- const __tgt_device_image &DeviceImage)
- : Image(Image), ImageData(std::move(ImageData)),
- DeviceImage(DeviceImage) {}
+ llvm::MemoryBufferRef DeviceImage)
+ : Image(Image), DeviceImage(DeviceImage) {}
plugin::DeviceImageTy *Image;
- std::unique_ptr<llvm::MemoryBuffer> ImageData;
std::mutex SymbolListMutex;
- __tgt_device_image DeviceImage;
+ llvm::MemoryBufferRef DeviceImage;
llvm::StringMap<std::unique_ptr<ol_symbol_impl_t>> KernelSymbols;
llvm::StringMap<std::unique_ptr<ol_symbol_impl_t>> GlobalSymbols;
};
@@ -891,28 +888,14 @@ Error olMemFill_impl(ol_queue_handle_t Queue, void *Ptr, size_t PatternSize,
Error olCreateProgram_impl(ol_device_handle_t Device, const void *ProgData,
size_t ProgDataSize, ol_program_handle_t *Program) {
// Make a copy of the program binary in case it is released by the caller.
- auto ImageData = MemoryBuffer::getMemBufferCopy(
- StringRef(reinterpret_cast<const char *>(ProgData), ProgDataSize));
-
- auto DeviceImage = __tgt_device_image{
- const_cast<char *>(ImageData->getBuffer().data()),
- const_cast<char *>(ImageData->getBuffer().data()) + ProgDataSize, nullptr,
- nullptr};
-
- ol_program_handle_t Prog =
- new ol_program_impl_t(nullptr, std::move(ImageData), DeviceImage);
-
- auto Res =
- Device->Device->loadBinary(Device->Device->Plugin, &Prog->DeviceImage);
- if (!Res) {
- delete Prog;
+ StringRef Buffer(reinterpret_cast<const char *>(ProgData), ProgDataSize);
+ Expected<plugin::DeviceImageTy *> Res =
+ Device->Device->loadBinary(Device->Device->Plugin, Buffer);
+ if (!Res)
return Res.takeError();
- }
- assert(*Res != nullptr && "loadBinary returned nullptr");
-
- Prog->Image = *Res;
- *Program = Prog;
+ assert(*Res && "loadBinary returned nullptr");
+ *Program = new ol_program_impl_t(*Res, (*Res)->getMemoryBuffer());
return Error::success();
}