0af2c7043c
SWDEV-102726 - [OCL-LC-ROCm] Open source OpenCL Runtime - Changes required to use the Khronos ICD sources instead of ours. Affected files ... ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/CMakeLists.txt#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_gl.cpp#54 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_icd.cpp#29 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/khronos/headers/opencl2.0/CL/cl_platform.h#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/CMakeLists.txt#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubinary.cpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubinary.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.cpp#319 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.hpp#127 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#233 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuresource.cpp#239 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/object.hpp#18 edit
212 строки
5.8 KiB
C++
212 строки
5.8 KiB
C++
//
|
|
// Copyright 2011 Advanced Micro Devices, Inc. All rights reserved.
|
|
//
|
|
|
|
#include "device/cpu/cpubinary.hpp"
|
|
#include "device/cpu/cpudevice.hpp"
|
|
#include "device/cpu/cpuprogram.hpp"
|
|
#include "utils/versions.hpp"
|
|
#include "os/os.hpp"
|
|
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
|
|
namespace cpu {
|
|
|
|
ClBinary::FeatureCheckResult ClBinary::checkFeatures() {
|
|
/* Validate that all cpu features of loaded binary target (i.e. elf_target) exists in current
|
|
* target.
|
|
* If some of elf_target features doesn't exist in current target we fail the build since we
|
|
* assume that elf LLVM-IR and binary are
|
|
* target specific and can't be recompiled to current target*/
|
|
uint16_t target = (uint16_t)dev().settings().cpuFeatures_;
|
|
uint16_t elf_target;
|
|
amd::OclElf::oclElfPlatform platform;
|
|
if (!elfIn()->getTarget(elf_target, platform)) {
|
|
LogError("Loading OCL CPU binary: incorrect format");
|
|
return fcERROR;
|
|
}
|
|
uint64_t chip_options = 0x0;
|
|
if (platform == amd::OclElf::COMPLIB_PLATFORM) {
|
|
// BIF 3.0
|
|
uint32_t flag;
|
|
if (!elfIn()->getFlags(flag)) {
|
|
LogError("Loading OCL CPU binary: incorrect format");
|
|
return fcERROR;
|
|
}
|
|
aclTargetInfo tgtInfo = aclGetTargetInfoFromChipID(LP64_SWITCH("x86", "x86-64"), flag, NULL);
|
|
chip_options = aclGetChipOptions(tgtInfo);
|
|
if (((target & chip_options) != chip_options) ||
|
|
((elf_target == EM_386) && (strcmp(LP64_SWITCH("x86", "x86-64"), "x86") != 0)) ||
|
|
((elf_target == EM_X86_64) && (strcmp(LP64_SWITCH("x86", "x86-64"), "x86-64") != 0))) {
|
|
LogError("Loading OCL CPU binary: different target");
|
|
return fcERROR;
|
|
}
|
|
} else {
|
|
// BIF 2.0
|
|
if ((platform != amd::OclElf::CPU_PLATFORM) || ((target & elf_target) != elf_target)) {
|
|
LogError("Loading OCL CPU binary: different target");
|
|
return fcERROR;
|
|
}
|
|
}
|
|
char* section;
|
|
size_t sz;
|
|
|
|
/* If current target has more cpu features than the one for which the binary was (notice it must
|
|
* have all features as in elf_target
|
|
* due to previous check), we can benefit from recompiling the LLVM-IR if exists in binary (if
|
|
* there are errors, ignore them !).*/
|
|
if (((platform == amd::OclElf::CPU_PLATFORM) && ((target ^ elf_target) != 0)) ||
|
|
((platform == amd::OclElf::COMPLIB_PLATFORM) && ((target ^ chip_options) != 0))) {
|
|
if (elfIn_->getSection(amd::OclElf::LLVMIR, §ion, &sz)) {
|
|
if ((section != NULL) && (sz > 0)) {
|
|
// hasDLL being false to force recompiling
|
|
fcRECOMPILE;
|
|
}
|
|
}
|
|
}
|
|
return fcOK;
|
|
}
|
|
|
|
bool ClBinary::loadX86(Program& program, std::string& dllName, bool& hasDLL) {
|
|
hasDLL = false;
|
|
|
|
std::string tempName = amd::Os::getTempFileName();
|
|
|
|
dllName = tempName + "." WINDOWS_SWITCH("dll", MACOS_SWITCH("dyld", "so"));
|
|
|
|
switch (checkFeatures()) {
|
|
case fcERROR:
|
|
return false;
|
|
case fcRECOMPILE:
|
|
return true;
|
|
case fcOK:
|
|
// Fallthrough
|
|
break;
|
|
}
|
|
|
|
char* section;
|
|
size_t sz;
|
|
|
|
if (!elfIn_->getSection(amd::OclElf::DLL, §ion, &sz)) {
|
|
LogError("Loading OCL CPU binary: error occured!");
|
|
return false;
|
|
}
|
|
|
|
if ((section == NULL) || (sz == 0)) {
|
|
// hasDLL being false to force recompiling
|
|
return true;
|
|
}
|
|
|
|
std::fstream f;
|
|
f.open(dllName.c_str(), (std::fstream::out | std::fstream::binary));
|
|
|
|
if (!f.is_open()) {
|
|
#ifdef _WIN32
|
|
amd::Os::unlink(tempName.c_str());
|
|
#endif // _WIN32
|
|
LogError("Loading OCL CPU binary: cannot open a file!");
|
|
return false;
|
|
}
|
|
f.write(section, sz);
|
|
f.close();
|
|
|
|
hasDLL = true;
|
|
return true;
|
|
}
|
|
|
|
bool ClBinary::storeX86(Program& program, std::string& dllName) {
|
|
std::fstream f;
|
|
f.open(dllName.c_str(), (std::fstream::in | std::fstream::binary));
|
|
if (!f.is_open()) {
|
|
return false;
|
|
}
|
|
|
|
f.seekg(0, std::fstream::end);
|
|
size_t x86CodeSize = f.tellg();
|
|
f.seekg(0, std::fstream::beg);
|
|
|
|
if (saveISA()) {
|
|
char* x86Code = new char[x86CodeSize];
|
|
f.read(x86Code, x86CodeSize);
|
|
elfOut_->addSection(amd::OclElf::DLL, x86Code, x86CodeSize);
|
|
delete[] x86Code;
|
|
}
|
|
f.close();
|
|
return true;
|
|
}
|
|
|
|
bool ClBinary::loadX86JIT(Program& program, bool& hasJITBinary) {
|
|
hasJITBinary = false;
|
|
|
|
switch (checkFeatures()) {
|
|
case fcERROR:
|
|
return false;
|
|
case fcRECOMPILE:
|
|
return true;
|
|
case fcOK:
|
|
// Fallthrough
|
|
break;
|
|
}
|
|
|
|
char* section;
|
|
size_t sz;
|
|
|
|
if (!elfIn_->getSection(amd::OclElf::JITBINARY, §ion, &sz)) {
|
|
LogError("Loading OCL CPU JIT binary: error occured!");
|
|
return false;
|
|
}
|
|
|
|
if ((section == NULL) || (sz == 0)) {
|
|
// force recompiling
|
|
return true;
|
|
}
|
|
acl_error err = ACL_SUCCESS;
|
|
program.setJITBinary(aclJITObjectImageCopy(program.compiler(), section, sz, &err));
|
|
if (err != ACL_SUCCESS) {
|
|
LogWarning("aclJITObjectImageCopy failed");
|
|
return false;
|
|
}
|
|
hasJITBinary = true;
|
|
return true;
|
|
}
|
|
|
|
void checkDifference(const char* buf1, const char* buf2, size_t size) {
|
|
for (size_t i = 0; i < size; ++i) {
|
|
if (buf1[i] != buf2[i]) {
|
|
printf("Index %d different", (int)i);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
bool ClBinary::storeX86JIT(Program& program) {
|
|
if (saveISA()) {
|
|
acl_error err = ACL_SUCCESS;
|
|
aclJITObjectImage objectImage = program.getJITBinary();
|
|
size_t x86CodeSize = aclJITObjectImageSize(program.compiler(), objectImage, &err);
|
|
if (err != ACL_SUCCESS) {
|
|
LogWarning("aclJITObjectImageSize failed");
|
|
return false;
|
|
}
|
|
const char* x86CodePtr = aclJITObjectImageData(program.compiler(), objectImage, &err);
|
|
if (err != ACL_SUCCESS) {
|
|
LogWarning("aclJITObjectImageData failed");
|
|
return false;
|
|
}
|
|
elfOut_->addSection(amd::OclElf::JITBINARY, x86CodePtr, x86CodeSize);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ClBinary::storeX86Asm(const char* buffer, size_t size) {
|
|
if (saveAS()) {
|
|
elfOut_->addSection(amd::OclElf::ASTEXT, buffer, size);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace cpu
|