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
Этот коммит содержится в:
Laurent Morichetti
2020-04-28 22:35:46 -07:00
коммит произвёл Laurent Morichetti
родитель b54c3f7db9
Коммит 9e1964ddaa
2 изменённых файлов: 25 добавлений и 18 удалений
+22 -16
Просмотреть файл
@@ -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<const uint8_t*>(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<char*>(memory), length)) {
if (!program->setBinary(reinterpret_cast<const char*>(memory), length)) {
delete program;
return CL_INVALID_BINARY;
}
@@ -230,7 +236,7 @@ int32_t Program::compile(const std::vector<Device*>& 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<Device*>& 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<Device*>& 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;
}
+3 -2
Просмотреть файл
@@ -37,6 +37,7 @@
#include <string>
#include <vector>
#include <map>
#include <tuple>
#include <utility>
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<uint8_t*, size_t> binary_t;
typedef std::tuple<const uint8_t* /*image*/, size_t /*size*/, bool /*allocated*/> binary_t;
typedef std::set<Device const*> devicelist_t;
typedef std::unordered_map<Device const*, binary_t> devicebinary_t;
typedef std::unordered_map<Device const*, device::Program*> 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;