From 9e1964ddaaa634e352a4e072be25de3adecf2031 Mon Sep 17 00:00:00 2001 From: Laurent Morichetti Date: Tue, 28 Apr 2020 22:35:46 -0700 Subject: [PATCH] Make the device binary copy optional Device binaries that are embedded inside the host binary do not require a copy. Their lifetime is guaranteed to exceed that of the loaded executable. Add a 'make_copy' parameter to amd::Program::addDeviceProgram. If make_copy is false the original image will be used and will not get freed when the amd::Program is destroyed. Change-Id: I7973bb0243f5a2d1b639b8a88445cfe6af919dd7 --- rocclr/platform/program.cpp | 38 +++++++++++++++++++++---------------- rocclr/platform/program.hpp | 5 +++-- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/rocclr/platform/program.cpp b/rocclr/platform/program.cpp index fe9940796b..c961cba550 100644 --- a/rocclr/platform/program.cpp +++ b/rocclr/platform/program.cpp @@ -62,8 +62,8 @@ Program::~Program() { for (const auto& it : binary_) { const binary_t& Bin = it.second; - if (Bin.first) { - delete[] Bin.first; + if (std::get<2>(Bin)) { + delete[] std::get<0>(Bin); } } @@ -82,7 +82,7 @@ const Symbol* Program::findSymbol(const char* kernelName) const { } int32_t Program::addDeviceProgram(Device& device, const void* image, size_t length, - amd::option::Options* options) { + bool make_copy, amd::option::Options* options) { if (image != NULL && !amd::isElfMagic((const char*)image)) { if (device.settings().useLightning_) { return CL_INVALID_BINARY; @@ -148,22 +148,28 @@ int32_t Program::addDeviceProgram(Device& device, const void* image, size_t leng } if (image != NULL) { - uint8_t* memory = binary(rootDev).first; + const uint8_t* memory = std::get<0>(binary(rootDev)); // clone 'binary' (it is owned by the host thread). if (memory == NULL) { - memory = new (std::nothrow) uint8_t[length]; - if (memory == NULL) { - delete program; - return CL_OUT_OF_HOST_MEMORY; + if (make_copy) { + auto *image_copy = new (std::nothrow) uint8_t[length]; + if (image_copy == NULL) { + delete program; + return CL_OUT_OF_HOST_MEMORY; + } + + ::memcpy(image_copy, image, length); + memory = image_copy; + } + else { + memory = static_cast(image); } - ::memcpy(memory, image, length); - // Save the original image - binary_[&rootDev] = std::make_pair(memory, length); + binary_[&rootDev] = std::make_tuple(memory, length, make_copy); } - if (!program->setBinary(reinterpret_cast(memory), length)) { + if (!program->setBinary(reinterpret_cast(memory), length)) { delete program; return CL_INVALID_BINARY; } @@ -230,7 +236,7 @@ int32_t Program::compile(const std::vector& devices, size_t numHeaders, device::Program* devProgram = getDeviceProgram(*it); if (devProgram == NULL) { const binary_t& bin = binary(*it); - retval = addDeviceProgram(*it, bin.first, bin.second, &parsedOptions); + retval = addDeviceProgram(*it, std::get<0>(bin), std::get<1>(bin), false, &parsedOptions); if (retval != CL_SUCCESS) { return retval; } @@ -358,7 +364,7 @@ int32_t Program::link(const std::vector& devices, size_t numInputs, device::Program* devProgram = getDeviceProgram(*it); if (devProgram == NULL) { const binary_t& bin = binary(*it); - retval = addDeviceProgram(*it, bin.first, bin.second, &parsedOptions); + retval = addDeviceProgram(*it, std::get<0>(bin), std::get<1>(bin), false, &parsedOptions); if (retval != CL_SUCCESS) { return retval; } @@ -506,11 +512,11 @@ int32_t Program::build(const std::vector& devices, const char* options, device::Program* devProgram = getDeviceProgram(*it); if (devProgram == NULL) { const binary_t& bin = binary(*it); - if (sourceCode_.empty() && (bin.first == NULL)) { + if (sourceCode_.empty() && (std::get<0>(bin) == NULL)) { retval = false; continue; } - retval = addDeviceProgram(*it, bin.first, bin.second, &parsedOptions); + retval = addDeviceProgram(*it, std::get<0>(bin), std::get<1>(bin), false, &parsedOptions); if (retval != CL_SUCCESS) { return retval; } diff --git a/rocclr/platform/program.hpp b/rocclr/platform/program.hpp index 1435a7849e..ac31936fde 100644 --- a/rocclr/platform/program.hpp +++ b/rocclr/platform/program.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include namespace amd { @@ -79,7 +80,7 @@ class Context; //! A collection of binaries for devices in the associated context. class Program : public RuntimeObject { public: - typedef std::pair binary_t; + typedef std::tuple binary_t; typedef std::set devicelist_t; typedef std::unordered_map devicebinary_t; typedef std::unordered_map deviceprograms_t; @@ -167,7 +168,7 @@ class Program : public RuntimeObject { //! Add a new device program with or without binary image and options. int32_t addDeviceProgram(Device&, const void* image = NULL, size_t len = 0, - amd::option::Options* options = NULL); + bool make_copy = true, amd::option::Options* options = NULL); //! Find the section for the given device. Return NULL if not found. device::Program* getDeviceProgram(const Device& device) const;