Files
rocm-systems/rocclr/runtime/device/cpu/cpubinary.cpp
T
foreman 0af2c7043c P4 to Git Change 1404293 by lmoriche@lmoriche_opencl_dev2 on 2017/05/01 16:43:07
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
2017-05-01 15:54:18 -05:00

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, &section, &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, &section, &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, &section, &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