| 91 | } |
| 92 | |
| 93 | int32_t Program::addDeviceProgram(Device& device, const void* image, size_t length, bool make_copy, |
| 94 | amd::option::Options* options, const amd::Program* same_prog, |
| 95 | amd::Os::FileDesc fdesc, size_t foffset, std::string uri) { |
| 96 | if (image != NULL && !amd::Elf::isElfMagic((const char*)image)) { |
| 97 | return CL_INVALID_BINARY; |
| 98 | } |
| 99 | |
| 100 | // Check if the device is already associated with this program |
| 101 | if (deviceList_.find(&device) != deviceList_.end()) { |
| 102 | return CL_INVALID_VALUE; |
| 103 | } |
| 104 | |
| 105 | Device& rootDev = device; |
| 106 | |
| 107 | // if the rootDev is already associated with a program |
| 108 | if (getDeviceProgram(rootDev) != NULL) { |
| 109 | return CL_SUCCESS; |
| 110 | } |
| 111 | |
| 112 | amd::option::Options emptyOpts; |
| 113 | if (options == NULL) { |
| 114 | options = &emptyOpts; |
| 115 | } |
| 116 | |
| 117 | options->oVariables->BinaryIsSpirv = language_ == SPIRV; |
| 118 | device::Program* program = rootDev.createProgram(*this, options); |
| 119 | if (program == NULL) { |
| 120 | return CL_OUT_OF_HOST_MEMORY; |
| 121 | } |
| 122 | |
| 123 | if (image != NULL) { |
| 124 | const uint8_t* memory = std::get<0>(binary(rootDev)); |
| 125 | // clone 'binary' (it is owned by the host thread). |
| 126 | if (memory == NULL) { |
| 127 | if (make_copy) { |
| 128 | auto* image_copy = new (std::nothrow) uint8_t[length]; |
| 129 | if (image_copy == NULL) { |
| 130 | delete program; |
| 131 | return CL_OUT_OF_HOST_MEMORY; |
| 132 | } |
| 133 | |
| 134 | ::memcpy(image_copy, image, length); |
| 135 | memory = image_copy; |
| 136 | } else { |
| 137 | memory = static_cast<const uint8_t*>(image); |
| 138 | } |
| 139 | |
| 140 | // Save the original image |
| 141 | binary_[&rootDev] = std::make_tuple(memory, std::make_pair(length, foffset), make_copy); |
| 142 | } |
| 143 | |
| 144 | const device::Program* same_dev_prog = nullptr; |
| 145 | if ((amd::IS_HIP) && (same_prog != nullptr)) { |
| 146 | const auto& same_dev_prog_map_ = same_prog->devicePrograms(); |
| 147 | guarantee(same_dev_prog_map_.size() == 1, "For same_prog, devicePrograms size != 1"); |
| 148 | same_dev_prog = same_dev_prog_map_.begin()->second; |
| 149 | } |
| 150 | |