P4 to Git Change 1481396 by lmoriche@lmoriche_opencl_dev2 on 2017/11/10 16:12:29

SWDEV-118564 - [OCL-LC-ROCm] Refactor the Lightning Compiler program manager to allow the compiler library API and the ROCm-OpenCL-Driver to coexist in the same platform.
	- Default compiler is the Lightning Compiler
	- Fall back to the HSAIL compiler if the amdoclcl compiler library is in the PATH and the -legacy option is specified (or app-detect)

Affected files ...

... //depot/stg/opencl/drivers/opencl/Makefile#59 edit
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/build/Makefile.api#168 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/api/v0_8/acl.cpp#44 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/api/v0_8/aclLoaders.cpp#14 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/api/v0_8/aclValidation.cpp#7 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/build/Makefile.complib#98 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/loaders/elf/elf.hpp#26 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/utils/OPTIONS.def#137 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/utils/build/Makefile.utils#19 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.cpp#71 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/device.cpp#213 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#292 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#235 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.cpp#49 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/build/Makefile.oclrocm#20 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompiler.cpp#38 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.cpp#8 delete
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.hpp#6 delete
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#75 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.cpp#30 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.hpp#17 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#75 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.hpp#30 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/program.cpp#88 edit


[ROCm/clr commit: 88ba77a1b4]
Tento commit je obsažen v:
foreman
2017-11-10 16:21:49 -05:00
rodič e68b9b7394
revize cdfc1b06be
16 změnil soubory, kde provedl 1010 přidání a 1134 odebrání
+3
Zobrazit soubor
@@ -34,6 +34,9 @@
#ifndef EM_ATI_CALIMAGE_BINARY
#define EM_ATI_CALIMAGE_BINARY 125
#endif
#ifndef EM_AMDGPU
#define EM_AMDGPU 224
#endif
#ifndef ELFOSABI_AMD_OPENCL
#define ELFOSABI_AMD_OPENCL 201
#endif
+1 -1
Zobrazit soubor
@@ -499,7 +499,7 @@ OPTION(OT_BOOL, \
OA_RUNTIME|OVIS_INTERNAL|OVA_DISALLOWED|OFA_PREFIX_F, \
"bin-gpu64", NULL, \
EnableGpuElf64, \
false, 0, 0, NULL, \
IS_LIGHTNING ? true : false, 0, 0, NULL, \
"Generate 64-bit ELF binary for GPU (default: 32-bit)")
// -fdebug-linker -fno-debug-linker
+2 -2
Zobrazit soubor
@@ -919,7 +919,7 @@ bool Program::linkImpl(amd::option::Options* options) {
// Load ISA
// For elf format, setup elfIn() and this elfIn() will be released
// at the end of build by finiBuild().
if (!clBinary()->setElfIn(LP64_SWITCH(ELFCLASS32, ELFCLASS64))) {
if (!clBinary()->setElfIn()) {
buildLog_ += "Internal error: Setting up input OpenCL binary failed!\n";
LogError("Setting up input binary failed");
return false;
@@ -1044,7 +1044,7 @@ bool Program::linkImpl(const std::vector<device::Program*>& inputPrograms,
// Load ISA
// For elf format, setup elfIn() and this elfIn() will be released
// at the end of build by finiBuild().
if (!program->clBinary()->setElfIn(LP64_SWITCH(ELFCLASS32, ELFCLASS64))) {
if (!program->clBinary()->setElfIn()) {
buildLog_ +=
"Internal error: Setting up input OpenCL binary"
" failed!\n";
+21 -42
Zobrazit soubor
@@ -614,7 +614,7 @@ bool CacheCompilation::compileAndLinkExecutable(amd::opencl_driver::Compiler* C,
return true;
}
#endif
#endif // defined(WITH_LIGHTNING_COMPILER)
} // namespace amd
@@ -1088,7 +1088,7 @@ bool Program::getCompileOptionsAtLinking(const std::vector<Program*>& inputProgr
return true;
}
bool Program::initClBinary(char* binaryIn, size_t size) {
bool Program::initClBinary(const char* binaryIn, size_t size) {
if (!initClBinary()) {
return false;
}
@@ -1096,7 +1096,7 @@ bool Program::initClBinary(char* binaryIn, size_t size) {
// Save the original binary that isn't owned by ClBinary
clBinary()->saveOrigBinary(binaryIn, size);
char* bin = binaryIn;
const char* bin = binaryIn;
size_t sz = size;
// unencrypted
@@ -1130,7 +1130,7 @@ bool Program::initClBinary(char* binaryIn, size_t size) {
return false;
}
if (info().arch_id == aclHSAIL || info().arch_id == aclHSAIL64) {
err = aclWriteToMem(aclbin_v30, reinterpret_cast<void**>(&bin), &sz);
err = aclWriteToMem(aclbin_v30, (void**)const_cast<char**>(&bin), &sz);
if (err != ACL_SUCCESS) {
LogWarning("aclWriteToMem failed");
aclBinaryFini(aclbin_v30);
@@ -1139,7 +1139,7 @@ bool Program::initClBinary(char* binaryIn, size_t size) {
aclBinaryFini(aclbin_v30);
} else {
aclBinary* aclbin_v21 = aclCreateFromBinary(aclbin_v30, aclBIFVersion21);
err = aclWriteToMem(aclbin_v21, reinterpret_cast<void**>(&bin), &sz);
err = aclWriteToMem(aclbin_v21, (void**)const_cast<char**>(&bin), &sz);
if (err != ACL_SUCCESS) {
LogWarning("aclWriteToMem failed");
aclBinaryFini(aclbin_v30);
@@ -1150,7 +1150,7 @@ bool Program::initClBinary(char* binaryIn, size_t size) {
aclBinaryFini(aclbin_v21);
}
} else
#endif // defined(WITH_LIGHTNING_COMPILER)
#endif // !defined(WITH_LIGHTNING_COMPILER)
{
size_t decryptedSize;
if (!clBinary()->decryptElf(binaryIn, size, &decryptedBin, &decryptedSize, &encryptCode)) {
@@ -1177,16 +1177,12 @@ bool Program::initClBinary(char* binaryIn, size_t size) {
}
bool Program::setBinary(char* binaryIn, size_t size) {
bool Program::setBinary(const char* binaryIn, size_t size) {
if (!initClBinary(binaryIn, size)) {
return false;
}
#if defined(WITH_LIGHTNING_COMPILER)
if (!clBinary()->setElfIn(ELFCLASS64)) {
#else // !defined(WITH_LIGHTNING_COMPILER)
if (!clBinary()->setElfIn(ELFCLASS32)) {
#endif // !defined(WITH_LIGHTNING_COMPILER)
if (!clBinary()->setElfIn()) {
LogError("Setting input OCL binary failed");
return false;
}
@@ -1209,7 +1205,14 @@ bool Program::setBinary(char* binaryIn, size_t size) {
break;
}
case ET_DYN: {
setType(TYPE_LIBRARY);
char* sect = NULL;
size_t sz = 0;
// FIXME: we should look for the e_machine to detect an HSACO.
if (clBinary()->elfIn()->getSection(amd::OclElf::TEXT, &sect, &sz) && sect && sz > 0) {
setType(TYPE_EXECUTABLE);
} else {
setType(TYPE_LIBRARY);
}
break;
}
case ET_EXEC: {
@@ -1223,35 +1226,12 @@ bool Program::setBinary(char* binaryIn, size_t size) {
clBinary()->loadCompileOptions(compileOptions_);
clBinary()->loadLinkOptions(linkOptions_);
#if defined(WITH_LIGHTNING_COMPILER)
// TODO: Remove this once BIF is no longer used as we should have a machinasm in
// place to get the binary type correctly from above.
// It is a workaround for executable build from the library. The code object
// binary does not have the type information.
char* sect = NULL;
size_t sz = 0;
if (clBinary()->elfIn()->getSection(amd::OclElf::TEXT, &sect, &sz) && sect && sz > 0) {
setType(TYPE_EXECUTABLE);
}
sect = NULL;
sz = 0;
if (type != ET_DYN && // binary is not a library
(clBinary()->elfIn()->getSection(amd::OclElf::LLVMIR, &sect, &sz) && sect && sz > 0)) {
setType(TYPE_COMPILED);
}
#endif
clBinary()->resetElfIn();
return true;
}
bool Program::createBIFBinary(aclBinary* bin) {
#if defined(WITH_LIGHTNING_COMPILER)
assert(!"createBIFBinary() should not be called when using LC");
return false;
#else // defined(WITH_LIGHTNING_COMPILER)
acl_error err;
char* binaryIn = NULL;
size_t size;
@@ -1263,7 +1243,6 @@ bool Program::createBIFBinary(aclBinary* bin) {
clBinary()->saveBIFBinary(binaryIn, size);
aclFreeMem(bin, binaryIn);
return true;
#endif // defined(WITH_LIGHTNING_COMPILER)
}
ClBinary::ClBinary(const amd::Device& dev, BinaryImageFormat bifVer)
@@ -1399,7 +1378,7 @@ void ClBinary::release() {
}
}
void ClBinary::saveBIFBinary(char* binaryIn, size_t size) {
void ClBinary::saveBIFBinary(const char* binaryIn, size_t size) {
char* image = new char[size];
memcpy(image, binaryIn, size);
@@ -1492,7 +1471,7 @@ bool ClBinary::createElfBinary(bool doencrypt, Program::type_t type) {
Program::binary_t ClBinary::data() const { return std::make_pair(binary_, size_); }
bool ClBinary::setBinary(char* theBinary, size_t theBinarySize, bool allocated) {
bool ClBinary::setBinary(const char* theBinary, size_t theBinarySize, bool allocated) {
release();
size_ = theBinarySize;
@@ -1514,7 +1493,7 @@ void ClBinary::setFlags(int encryptCode) {
}
}
bool ClBinary::decryptElf(char* binaryIn, size_t size, char** decryptBin, size_t* decryptSize,
bool ClBinary::decryptElf(const char* binaryIn, size_t size, char** decryptBin, size_t* decryptSize,
int* encryptCode) {
*decryptBin = NULL;
#if defined(HAVE_BLOWFISH_H)
@@ -1540,13 +1519,13 @@ bool ClBinary::decryptElf(char* binaryIn, size_t size, char** decryptBin, size_t
return true;
}
bool ClBinary::setElfIn(unsigned char eclass) {
bool ClBinary::setElfIn() {
if (elfIn_) return true;
if (binary_ == NULL) {
return false;
}
elfIn_ = new amd::OclElf(eclass, binary_, size_, NULL, ELF_C_READ);
elfIn_ = new amd::OclElf(ELFCLASSNONE, binary_, size_, NULL, ELF_C_READ);
if ((elfIn_ == NULL) || elfIn_->hasError()) {
if (elfIn_) {
delete elfIn_;
+11 -17
Zobrazit soubor
@@ -19,7 +19,7 @@
#if defined(WITH_LIGHTNING_COMPILER)
#include "caching/cache.hpp"
#include "driver/AmdCompiler.h"
#endif // defined(WITH_LIGHTNING_COMPILER)
#endif // defined(WITH_LIGHTNING_COMPILER)
#include "acl.h"
#include "hwdebug.hpp"
@@ -1084,7 +1084,7 @@ class Program : public amd::HeapObject {
ClBinary* clBinary() { return clBinary_; }
const ClBinary* clBinary() const { return clBinary_; }
bool setBinary(char* binaryIn, size_t size);
bool setBinary(const char* binaryIn, size_t size);
type_t type() const { return type_; }
@@ -1116,7 +1116,7 @@ class Program : public amd::HeapObject {
virtual bool createBIFBinary(aclBinary* bin);
//! Initialize Binary (used only for clCreateProgramWithBinary()).
bool initClBinary(char* binaryIn, size_t size);
bool initClBinary(const char* binaryIn, size_t size);
//! Initialize Binary
virtual bool initClBinary() = 0;
@@ -1165,10 +1165,10 @@ class ClBinary : public amd::HeapObject {
/** called only in loading image routines,
never called in storing routines */
bool setBinary(char* theBinary, size_t theBinarySize, bool allocated = false);
bool setBinary(const char* theBinary, size_t theBinarySize, bool allocated = false);
//! setin elfIn_
bool setElfIn(unsigned char eclass);
bool setElfIn();
void resetElfIn();
//! set out elf
@@ -1189,9 +1189,9 @@ class ClBinary : public amd::HeapObject {
bool createElfBinary(bool doencrypt, Program::type_t type);
// save BIF binary image
void saveBIFBinary(char* binaryIn, size_t size);
void saveBIFBinary(const char* binaryIn, size_t size);
bool decryptElf(char* binaryIn, size_t size, char** decryptBin, size_t* decryptSize,
bool decryptElf(const char* binaryIn, size_t size, char** decryptBin, size_t* decryptSize,
int* encryptCode);
//! Returns the binary pair for the abstraction layer
@@ -1222,7 +1222,7 @@ class ClBinary : public amd::HeapObject {
//! Check if the binary is recompilable
bool isRecompilable(std::string& llvmBinary, amd::OclElf::oclElfPlatform thePlatform);
void saveOrigBinary(char* origBinary, size_t origSize) {
void saveOrigBinary(const char* origBinary, size_t origSize) {
origBinary_ = origBinary;
origSize_ = origSize;
}
@@ -1306,11 +1306,11 @@ class ClBinary : public amd::HeapObject {
//! Releases the binary data store
void release();
char* binary_; //!< binary data
const char* binary_; //!< binary data
size_t size_; //!< binary size
uint flags_; //!< CL binary object flags
char* origBinary_; //!< original binary data
const char* origBinary_; //!< original binary data
size_t origSize_; //!< original binary size
int encryptCode_; //!< Encryption Code for input binary (0 for not encrypted)
@@ -1468,11 +1468,7 @@ class SvmManager : public AllStatic {
*/
class Device : public RuntimeObject {
protected:
#if defined(WITH_LIGHTNING_COMPILER)
typedef amd::opencl_driver::Compiler Compiler;
#else // !defined(WITH_LIGHTNING_COMPILER)
typedef aclCompiler Compiler;
#endif // !defined(WITH_LIGHTNING_COMPILER)
public:
typedef std::list<CommandQueue*> CommandQueues;
@@ -1753,7 +1749,6 @@ struct KernelParameterDescriptor {
};
#if defined(WITH_LIGHTNING_COMPILER)
//! Compilation process with cache support.
class CacheCompilation : public amd::HeapObject {
public:
@@ -1790,8 +1785,7 @@ class CacheCompilation : public amd::HeapObject {
StringCache codeCache_; //! Cached codes
const bool isCodeCacheEnabled_; //! Code cache enable
};
#endif
#endif // defined(WITH_LIGHTNING_COMPILER)
/*! @}
* @}
+2 -2
Zobrazit soubor
@@ -176,7 +176,7 @@ bool NullProgram::linkImpl(amd::option::Options* options) {
if (ilProgram_.empty()) {
// Setup elfIn() and try to load ISA from binary
// This elfIn() will be released at the end of build by finiBuild().
if (!clBinary()->setElfIn(ELFCLASS32)) {
if (!clBinary()->setElfIn()) {
buildLog_ += "Internal error: Setting input OCL binary failed!\n";
LogError("Setting input OCL binary failed");
return false;
@@ -479,7 +479,7 @@ bool NullProgram::linkImpl(const std::vector<device::Program*>& inputPrograms,
// We are using CL binary directly.
// Setup elfIn() and try to load llvmIR from binary
// This elfIn() will be released at the end of build by finiBuild().
if (!program->clBinary()->setElfIn(ELFCLASS32)) {
if (!program->clBinary()->setElfIn()) {
buildLog_ += "Internal error: Setting input OCL binary failed!\n";
LogError("Setting input OCL binary failed");
return false;
+1 -1
Zobrazit soubor
@@ -1280,7 +1280,7 @@ bool LightningProgram::linkImpl(const std::vector<Program*>& inputPrograms,
// We are using CL binary directly.
// Setup elfIn() and try to load llvmIR from binary
// This elfIn() will be released at the end of build by finiBuild().
if (!program->clBinary()->setElfIn(ELFCLASS64)) {
if (!program->clBinary()->setElfIn()) {
buildLog_ += "Internal error: Setting input OCL binary failed!\n";
return false;
}
+120 -128
Zobrazit soubor
@@ -15,9 +15,7 @@
#if defined(WITH_LIGHTNING_COMPILER)
#include "opencl1.2-c.amdgcn.inc"
#include "opencl2.0-c.amdgcn.inc"
#else // !defined(WITH_LIGHTNING_COMPILER)
#include "roccompilerlib.hpp"
#endif // !defined(WITH_LIGHTNING_COMPILER)
#endif // defined(WITH_LIGHTNING_COMPILER)
#include "utils/options.hpp"
#include <cstdio>
@@ -48,10 +46,125 @@ static void logFunction(const char* msg, size_t size) {
static int programsCount = 0;
bool HSAILProgram::compileImpl(const std::string& sourceCode,
const std::vector<const std::string*>& headers,
const char** headerIncludeNames, amd::option::Options* options) {
acl_error errorCode;
aclTargetInfo target;
target = aclGetTargetInfo(LP64_SWITCH("hsail", "hsail64"),
dev().deviceInfo().complibTarget_, &errorCode);
// end if asic info is ready
// We dump the source code for each program (param: headers)
// into their filenames (headerIncludeNames) into the TEMP
// folder specific to the OS and add the include path while
// compiling
// Find the temp folder for the OS
std::string tempFolder = amd::Os::getEnvironment("TEMP");
if (tempFolder.empty()) {
tempFolder = amd::Os::getEnvironment("TMP");
if (tempFolder.empty()) {
tempFolder = WINDOWS_SWITCH(".", "/tmp");
;
}
}
// Iterate through each source code and dump it into tmp
std::fstream f;
std::vector<std::string> headerFileNames(headers.size());
std::vector<std::string> newDirs;
for (size_t i = 0; i < headers.size(); ++i) {
std::string headerPath = tempFolder;
std::string headerIncludeName(headerIncludeNames[i]);
// replace / in path with current os's file separator
if (amd::Os::fileSeparator() != '/') {
for (std::string::iterator it = headerIncludeName.begin(), end = headerIncludeName.end();
it != end; ++it) {
if (*it == '/') *it = amd::Os::fileSeparator();
}
}
size_t pos = headerIncludeName.rfind(amd::Os::fileSeparator());
if (pos != std::string::npos) {
headerPath += amd::Os::fileSeparator();
headerPath += headerIncludeName.substr(0, pos);
headerIncludeName = headerIncludeName.substr(pos + 1);
}
if (!amd::Os::pathExists(headerPath)) {
bool ret = amd::Os::createPath(headerPath);
assert(ret && "failed creating path!");
newDirs.push_back(headerPath);
}
std::string headerFullName = headerPath + amd::Os::fileSeparator() + headerIncludeName;
headerFileNames[i] = headerFullName;
f.open(headerFullName.c_str(), std::fstream::out);
// Should we allow asserts
assert(!f.fail() && "failed creating header file!");
f.write(headers[i]->c_str(), headers[i]->length());
f.close();
}
// Create Binary
binaryElf_ = aclBinaryInit(sizeof(aclBinary), &target, &binOpts_, &errorCode);
if (errorCode != ACL_SUCCESS) {
buildLog_ +=
"Error while compiling opencl source:\
aclBinary init failure \n";
LogWarning("aclBinaryInit failed");
return false;
}
// Insert opencl into binary
errorCode = aclInsertSection(device().compiler(), binaryElf_, sourceCode.c_str(),
strlen(sourceCode.c_str()), aclSOURCE);
if (errorCode != ACL_SUCCESS) {
buildLog_ +=
"Error while converting to BRIG: \
Inserting openCl Source \n";
}
// Set the options for the compiler
// Set the include path for the temp folder that contains the includes
if (!headers.empty()) {
this->compileOptions_.append(" -I");
this->compileOptions_.append(tempFolder);
}
// Add only for CL2.0 and later
if (options->oVariables->CLStd[2] >= '2') {
std::stringstream opts;
opts << " -D"
<< "CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE=" << device().info().maxGlobalVariableSize_;
compileOptions_.append(opts.str());
}
// Compile source to IR
this->compileOptions_.append(preprocessorOptions(options));
this->compileOptions_.append(codegenOptions(options));
errorCode = aclCompile(device().compiler(), binaryElf_,
//"-Wf,--support_all_extensions",
this->compileOptions_.c_str(), ACL_TYPE_OPENCL,
ACL_TYPE_LLVMIR_BINARY, logFunction);
buildLog_ += aclGetCompilerLog(device().compiler());
if (errorCode != ACL_SUCCESS) {
LogWarning("aclCompile failed");
buildLog_ +=
"Error while compiling \
opencl source: Compiling CL to IR";
return false;
}
// Save the binary in the interface class
saveBinaryAndSetType(TYPE_COMPILED);
return true;
}
#if defined(WITH_LIGHTNING_COMPILER)
bool HSAILProgram::compileImpl_LC(const std::string& sourceCode,
const std::vector<const std::string*>& headers,
const char** headerIncludeNames, amd::option::Options* options) {
bool LightningProgram::compileImpl(const std::string& sourceCode,
const std::vector<const std::string*>& headers,
const char** headerIncludeNames, amd::option::Options* options) {
using namespace amd::opencl_driver;
std::unique_ptr<Compiler> C(newCompilerInstance());
std::vector<Data*> inputs;
@@ -238,128 +351,7 @@ bool HSAILProgram::compileImpl_LC(const std::string& sourceCode,
}
return true;
}
#endif // defined(WITH_LIGHTNING_COMPILER)
bool HSAILProgram::compileImpl(const std::string& sourceCode,
const std::vector<const std::string*>& headers,
const char** headerIncludeNames, amd::option::Options* options) {
#if defined(WITH_LIGHTNING_COMPILER)
return compileImpl_LC(sourceCode, headers, headerIncludeNames, options);
#else // !defined(WITH_LIGHTNING_COMPILER)
acl_error errorCode;
aclTargetInfo target;
target = g_complibApi._aclGetTargetInfo(LP64_SWITCH("hsail", "hsail64"),
dev().deviceInfo().complibTarget_, &errorCode);
// end if asic info is ready
// We dump the source code for each program (param: headers)
// into their filenames (headerIncludeNames) into the TEMP
// folder specific to the OS and add the include path while
// compiling
// Find the temp folder for the OS
std::string tempFolder = amd::Os::getEnvironment("TEMP");
if (tempFolder.empty()) {
tempFolder = amd::Os::getEnvironment("TMP");
if (tempFolder.empty()) {
tempFolder = WINDOWS_SWITCH(".", "/tmp");
;
}
}
// Iterate through each source code and dump it into tmp
std::fstream f;
std::vector<std::string> headerFileNames(headers.size());
std::vector<std::string> newDirs;
for (size_t i = 0; i < headers.size(); ++i) {
std::string headerPath = tempFolder;
std::string headerIncludeName(headerIncludeNames[i]);
// replace / in path with current os's file separator
if (amd::Os::fileSeparator() != '/') {
for (std::string::iterator it = headerIncludeName.begin(), end = headerIncludeName.end();
it != end; ++it) {
if (*it == '/') *it = amd::Os::fileSeparator();
}
}
size_t pos = headerIncludeName.rfind(amd::Os::fileSeparator());
if (pos != std::string::npos) {
headerPath += amd::Os::fileSeparator();
headerPath += headerIncludeName.substr(0, pos);
headerIncludeName = headerIncludeName.substr(pos + 1);
}
if (!amd::Os::pathExists(headerPath)) {
bool ret = amd::Os::createPath(headerPath);
assert(ret && "failed creating path!");
newDirs.push_back(headerPath);
}
std::string headerFullName = headerPath + amd::Os::fileSeparator() + headerIncludeName;
headerFileNames[i] = headerFullName;
f.open(headerFullName.c_str(), std::fstream::out);
// Should we allow asserts
assert(!f.fail() && "failed creating header file!");
f.write(headers[i]->c_str(), headers[i]->length());
f.close();
}
// Create Binary
binaryElf_ = g_complibApi._aclBinaryInit(sizeof(aclBinary), &target, &binOpts_, &errorCode);
if (errorCode != ACL_SUCCESS) {
buildLog_ +=
"Error while compiling opencl source:\
aclBinary init failure \n";
LogWarning("aclBinaryInit failed");
return false;
}
// Insert opencl into binary
errorCode = g_complibApi._aclInsertSection(device().compiler(), binaryElf_, sourceCode.c_str(),
strlen(sourceCode.c_str()), aclSOURCE);
if (errorCode != ACL_SUCCESS) {
buildLog_ +=
"Error while converting to BRIG: \
Inserting openCl Source \n";
}
// Set the options for the compiler
// Set the include path for the temp folder that contains the includes
if (!headers.empty()) {
this->compileOptions_.append(" -I");
this->compileOptions_.append(tempFolder);
}
// Add only for CL2.0 and later
if (options->oVariables->CLStd[2] >= '2') {
std::stringstream opts;
opts << " -D"
<< "CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE=" << device().info().maxGlobalVariableSize_;
compileOptions_.append(opts.str());
}
// Compile source to IR
this->compileOptions_.append(preprocessorOptions(options));
this->compileOptions_.append(codegenOptions(options));
errorCode = g_complibApi._aclCompile(device().compiler(), binaryElf_,
//"-Wf,--support_all_extensions",
this->compileOptions_.c_str(), ACL_TYPE_OPENCL,
ACL_TYPE_LLVMIR_BINARY, logFunction);
buildLog_ += g_complibApi._aclGetCompilerLog(device().compiler());
if (errorCode != ACL_SUCCESS) {
LogWarning("aclCompile failed");
buildLog_ +=
"Error while compiling \
opencl source: Compiling CL to IR";
return false;
}
// Save the binary in the interface class
saveBinaryAndSetType(TYPE_COMPILED);
return true;
#endif // !defined(WITH_LIGHTNING_COMPILER)
}
#if defined(WITH_LIGHTNING_COMPILER)
#if defined(ATI_OS_LINUX)
static pthread_once_t once = PTHREAD_ONCE_INIT;
@@ -396,7 +388,7 @@ static void checkLLVM_BIN() {
}
#endif // defined(ATI_OS_LINUX)
amd::opencl_driver::Compiler* HSAILProgram::newCompilerInstance() {
amd::opencl_driver::Compiler* LightningProgram::newCompilerInstance() {
#if defined(ATI_OS_LINUX)
pthread_once(&once, checkLLVM_BIN);
#endif // defined(ATI_OS_LINUX)
-63
Zobrazit soubor
@@ -1,63 +0,0 @@
#include "roccompilerlib.hpp"
#include "utils/flags.hpp"
#include "acl.h"
namespace roc {
void* g_complibModule = nullptr;
struct CompLibApi g_complibApi;
//
// g_complibModule is defined in LoadCompLib(). This macro must be used only in LoadCompLib()
// function.
//
#if defined(BUILD_HSA_TARGET)
#define LOADSYMBOL(api) \
g_complibApi._##api = (pfn_##api)amd::Os::getSymbol(g_complibModule, #api); \
if (g_complibApi._##api == nullptr) { \
LogError("amd::Os::getSymbol() for exported func " #api " failed."); \
amd::Os::unloadLibrary(g_complibModule); \
return false; \
}
#else // !defined(BUILD_HSA_TARGET)
#define LOADSYMBOL(api) g_complibApi._##api = (pfn_##api)&(api);
#endif // !defined(BUILD_HSA_TARGET)
bool LoadCompLib(bool offline) {
#if defined(BUILD_HSA_TARGET)
g_complibModule = amd::Os::loadLibrary("amdhsacl" LP64_SWITCH(LINUX_SWITCH("32", ""), "64"));
if (g_complibModule == nullptr) {
if (!offline) {
LogError("amd::Os::loadLibrary() for loading of amdhsacl.dll failed.");
}
return false;
}
#endif // defined(BUILD_HSA_TARGET)
LOADSYMBOL(aclCompilerInit)
LOADSYMBOL(aclGetTargetInfo)
LOADSYMBOL(aclBinaryInit)
LOADSYMBOL(aclInsertSection)
LOADSYMBOL(aclCompile)
LOADSYMBOL(aclCompilerFini)
LOADSYMBOL(aclBinaryFini)
LOADSYMBOL(aclWriteToMem)
LOADSYMBOL(aclQueryInfo)
LOADSYMBOL(aclExtractSymbol)
LOADSYMBOL(aclGetCompilerLog)
LOADSYMBOL(aclCreateFromBinary)
LOADSYMBOL(aclReadFromMem)
LOADSYMBOL(aclBinaryVersion)
LOADSYMBOL(aclLink)
return true;
}
void UnloadCompLib() {
if (g_complibModule) {
amd::Os::unloadLibrary(g_complibModule);
}
}
} // namespace roc
-94
Zobrazit soubor
@@ -1,94 +0,0 @@
#pragma once
//
// This file hsa the code for explicity loading amdoclcl.dll.
// Exported functions from amdoclcl.dll can be added for usage as need-basis.
// With explicit/dynamic loading roc will not have any linkage to amdoclcl.lib.
//
#include "thread/thread.hpp"
#include "acl.h"
#include "utils/debug.hpp"
#if defined(WITH_LIGHTNING_COMPILER)
#error Should not include this file
#endif // defined(WITH_LIGHTNING_COMPILER)
using namespace amd;
namespace roc {
//
// To use any new exported function from amdhsacl.dll please add/make that function specific changes
// in typedef below, struct CompLibApi and in hsacompilerLib.cpp::LoadCompLib() function.
//
//
// Convention: The typedefed function name must be prefixed with pfn_
//
typedef aclCompiler*(ACL_API_ENTRY* pfn_aclCompilerInit)(aclCompilerOptions* opts,
acl_error* error_code);
typedef aclTargetInfo(ACL_API_ENTRY* pfn_aclGetTargetInfo)(const char*, const char*, acl_error*);
typedef aclBinary*(ACL_API_ENTRY* pfn_aclBinaryInit)(size_t, const aclTargetInfo*,
const aclBinaryOptions*, acl_error*);
typedef acl_error(ACL_API_ENTRY* pfn_aclInsertSection)(aclCompiler* cl, aclBinary* binary,
const void* data, size_t data_size,
aclSections id);
typedef acl_error(ACL_API_ENTRY* pfn_aclCompile)(aclCompiler* cl, aclBinary* bin,
const char* options, aclType from, aclType to,
aclLogFunction compile_callback);
typedef acl_error(ACL_API_ENTRY* pfn_aclCompilerFini)(aclCompiler* cl);
typedef acl_error(ACL_API_ENTRY* pfn_aclBinaryFini)(aclBinary* bin);
typedef acl_error(ACL_API_ENTRY* pfn_aclWriteToMem)(aclBinary* bin, void** mem, size_t* size);
typedef acl_error(ACL_API_ENTRY* pfn_aclQueryInfo)(aclCompiler* cl, const aclBinary* binary,
aclQueryType query, const char* kernel,
void* data_ptr, size_t* ptr_size);
typedef const void*(ACL_API_ENTRY* pfn_aclExtractSymbol)(aclCompiler* cl, const aclBinary* binary,
size_t* size, aclSections id,
const char* symbol, acl_error* error_code);
typedef aclBinary*(ACL_API_ENTRY* pfn_aclReadFromMem)(void* mem, size_t size,
acl_error* error_code);
typedef char*(ACL_API_ENTRY* pfn_aclGetCompilerLog)(aclCompiler* cl);
typedef aclBinary*(ACL_API_ENTRY* pfn_aclCreateFromBinary)(const aclBinary* binary,
aclBIFVersion version);
typedef aclBIFVersion(ACL_API_ENTRY* pfn_aclBinaryVersion)(const aclBinary* binary);
typedef acl_error(ACL_API_ENTRY* pfn_aclLink)(aclCompiler* cl, aclBinary* src_bin,
unsigned int num_libs, aclBinary** libs,
aclType link_mode, const char* options,
aclLogFunction link_callback);
//
// Convention: prefix struct member variable with with underscore '_'
// would be nice if there was no underscore prfix, but on Linux the token
// pasting in the macro is srtict and his is the workaround.
//
struct CompLibApi {
pfn_aclCompilerInit _aclCompilerInit;
pfn_aclGetTargetInfo _aclGetTargetInfo;
pfn_aclBinaryInit _aclBinaryInit;
pfn_aclInsertSection _aclInsertSection;
pfn_aclCompile _aclCompile;
pfn_aclCompilerFini _aclCompilerFini;
pfn_aclBinaryFini _aclBinaryFini;
pfn_aclWriteToMem _aclWriteToMem;
pfn_aclQueryInfo _aclQueryInfo;
pfn_aclExtractSymbol _aclExtractSymbol;
pfn_aclReadFromMem _aclReadFromMem;
pfn_aclGetCompilerLog _aclGetCompilerLog;
pfn_aclCreateFromBinary _aclCreateFromBinary;
pfn_aclBinaryVersion _aclBinaryVersion;
pfn_aclLink _aclLink;
};
//
// Use g_ prefix for all global variables.
//
extern void* g_complibModule;
extern CompLibApi g_complibApi;
// Note: initializes global variable g_complibApi.
// Not sure what error values we have, for now returning false on failure.
bool LoadCompLib(bool isOfflineDevice = false);
void UnloadCompLib();
} // namespace roc
+19 -25
Zobrazit soubor
@@ -9,6 +9,7 @@
#include "os/os.hpp"
#include "utils/debug.hpp"
#include "utils/flags.hpp"
#include "utils/options.hpp"
#include "utils/versions.hpp"
#include "thread/monitor.hpp"
#include "CL/cl_ext.h"
@@ -20,9 +21,7 @@
#include "device/rocm/rocprogram.hpp"
#if defined(WITH_LIGHTNING_COMPILER)
#include "driver/AmdCompiler.h"
#else // !defined(WITH_LIGHTNING_COMPILER)
#include "device/rocm/roccompilerlib.hpp"
#endif // !defined(WITH_LIGHTNING_COMPILER)
#endif // defined(WITH_LIGHTNING_COMPILER)
#include "device/rocm/rocmemory.hpp"
#include "device/rocm/rocglinterop.hpp"
#ifdef WITH_AMDGPU_PRO
@@ -191,46 +190,34 @@ Device::~Device() {
}
}
bool NullDevice::initCompiler(bool isOffline) {
#if !defined(WITH_LIGHTNING_COMPILER)
// Initializes g_complibModule and g_complibApi if they were not initialized
if (g_complibModule == nullptr) {
if (!LoadCompLib(isOffline)) {
if (!isOffline) {
LogError("Error - could not find the compiler library");
}
return false;
}
}
// Initialize the compiler handle if has already not been initialized
// This is destroyed in Device::teardown
acl_error error;
if (!compilerHandle_) {
compilerHandle_ = g_complibApi._aclCompilerInit(nullptr, &error);
aclCompilerOptions opts = {
sizeof(aclCompilerOptions_0_8),
IF(IS_LIGHTNING, "libamdoclcl64.so", NULL),
NULL, NULL, NULL, NULL, NULL, NULL
};
compilerHandle_ = aclCompilerInit(&opts, &error);
if (error != ACL_SUCCESS) {
#if !defined(WITH_LIGHTNING_COMPILER)
LogError("Error initializing the compiler handle");
return false;
#endif // !defined(WITH_LIGHTNING_COMPILER)
}
}
#endif // !defined(WITH_LIGHTNING_COMPILER)
return true;
}
bool NullDevice::destroyCompiler() {
#if defined(WITH_LIGHTNING_COMPILER)
delete compilerHandle_;
compilerHandle_ = nullptr;
#else // !defined(WITH_LIGHTNING_COMPILER)
if (compilerHandle_ != nullptr) {
acl_error error = g_complibApi._aclCompilerFini(compilerHandle_);
acl_error error = aclCompilerFini(compilerHandle_);
if (error != ACL_SUCCESS) {
LogError("Error closing the compiler");
return false;
}
}
if (g_complibModule != nullptr) {
UnloadCompLib();
}
#endif // !defined(WITH_LIGHTNING_COMPILER)
return true;
}
@@ -682,6 +669,11 @@ device::Program* NullDevice::createProgram(amd::option::Options* options) {
}
device::Program* Device::createProgram(amd::option::Options* options) {
#if defined(WITH_LIGHTNING_COMPILER)
if (!compilerHandle_ || !options->oVariables->Legacy) {
return new roc::LightningProgram(*this);
}
#endif // defined(WITH_LIGHTNING_COMPILER)
return new roc::HSAILProgram(*this);
}
@@ -965,7 +957,9 @@ bool Device::populateOCLDeviceConstants() {
return false;
}
std::stringstream ss;
ss << AMD_BUILD_STRING " (HSA" << major << "." << minor << "," IF(IS_LIGHTNING, "LC", "HSAIL") ")";
ss << AMD_BUILD_STRING " (HSA" << major << "." << minor << "," IF(IS_LIGHTNING, "LC", "HSAIL");
if (IS_LIGHTNING && compilerHandle_) ss << "*,HSAIL";
ss << ")";
strcpy(info_.driverVersion_, ss.str().c_str());
info_.version_ = "OpenCL " /*OPENCL_VERSION_STR*/"1.2" " ";
+16 -21
Zobrazit soubor
@@ -498,7 +498,7 @@ static inline cl_kernel_arg_type_qualifier GetOclTypeQual(const aclArgData* argI
return rv;
}
void Kernel::initArguments(const aclArgData* aclArg) {
void HSAILKernel::initArguments(const aclArgData* aclArg) {
device::Kernel::parameters_t params;
// Iterate through the arguments and insert into parameterList
@@ -562,7 +562,7 @@ void Kernel::initArguments(const aclArgData* aclArg) {
}
#if defined(WITH_LIGHTNING_COMPILER)
void Kernel::initArguments_LC(const KernelMD& kernelMD) {
void LightningKernel::initArguments(const KernelMD& kernelMD) {
device::Kernel::parameters_t params;
size_t offset = 0;
@@ -632,7 +632,7 @@ void Kernel::initArguments_LC(const KernelMD& kernelMD) {
}
#endif // defined(WITH_LIGHTNING_COMPILER)
Kernel::Kernel(std::string name, HSAILProgram* prog, const uint64_t& kernelCodeHandle,
Kernel::Kernel(std::string name, Program* prog, const uint64_t& kernelCodeHandle,
const uint32_t workgroupGroupSegmentByteSize,
const uint32_t workitemPrivateSegmentByteSize, const uint32_t kernargSegmentByteSize,
const uint32_t kernargSegmentAlignment)
@@ -645,7 +645,6 @@ Kernel::Kernel(std::string name, HSAILProgram* prog, const uint64_t& kernelCodeH
kernargSegmentAlignment_(kernargSegmentAlignment) {}
#if defined(WITH_LIGHTNING_COMPILER)
static const KernelMD* FindKernelMetadata(const CodeObjectMD* programMD, const std::string& name) {
for (const KernelMD& kernelMD : programMD->mKernels) {
if (kernelMD.mName == name) {
@@ -655,18 +654,18 @@ static const KernelMD* FindKernelMetadata(const CodeObjectMD* programMD, const s
return nullptr;
}
bool Kernel::init_LC() {
bool LightningKernel::init() {
hsa_agent_t hsaDevice = program_->hsaDevice();
// Pull out metadata from the ELF
const CodeObjectMD* programMD = program_->metadata();
const CodeObjectMD* programMD = static_cast<LightningProgram*>(program_)->metadata();
assert(programMD != nullptr);
const KernelMD* kernelMD = FindKernelMetadata(programMD, name());
if (kernelMD == nullptr) {
return false;
}
initArguments_LC(*kernelMD);
initArguments(*kernelMD);
// Set the workgroup information for the kernel
workGroupInfo_.availableLDSSize_ = program_->dev().info().localMemSizePerCU_;
@@ -721,16 +720,13 @@ bool Kernel::init_LC() {
return false;
}
initPrintf_LC(programMD->mPrintf);
initPrintf(programMD->mPrintf);
return true;
}
#endif // defined(WITH_LIGHTNING_COMPILER)
bool Kernel::init() {
#if defined(WITH_LIGHTNING_COMPILER)
return init_LC();
#else // !defined(WITH_LIGHTNING_COMPILER)
bool HSAILKernel::init() {
acl_error errorCode;
// compile kernel down to ISA
hsa_agent_t hsaDevice = program_->hsaDevice();
@@ -738,13 +734,13 @@ bool Kernel::init() {
size_t sizeOfArgList;
aclCompiler* compileHandle = program_->dev().compiler();
std::string openClKernelName("&__OpenCL_" + name() + "_kernel");
errorCode = g_complibApi._aclQueryInfo(compileHandle, program_->binaryElf(), RT_ARGUMENT_ARRAY,
errorCode = aclQueryInfo(compileHandle, program_->binaryElf(), RT_ARGUMENT_ARRAY,
openClKernelName.c_str(), nullptr, &sizeOfArgList);
if (errorCode != ACL_SUCCESS) {
return false;
}
std::unique_ptr<char[]> argList(new char[sizeOfArgList]);
errorCode = g_complibApi._aclQueryInfo(compileHandle, program_->binaryElf(), RT_ARGUMENT_ARRAY,
errorCode = aclQueryInfo(compileHandle, program_->binaryElf(), RT_ARGUMENT_ARRAY,
openClKernelName.c_str(), argList.get(), &sizeOfArgList);
if (errorCode != ACL_SUCCESS) {
return false;
@@ -760,12 +756,12 @@ bool Kernel::init() {
workGroupInfo_.availableSGPRs_ = 104;
workGroupInfo_.availableVGPRs_ = 256;
size_t sizeOfWorkGroupSize;
errorCode = g_complibApi._aclQueryInfo(compileHandle, program_->binaryElf(), RT_WORK_GROUP_SIZE,
errorCode = aclQueryInfo(compileHandle, program_->binaryElf(), RT_WORK_GROUP_SIZE,
openClKernelName.c_str(), nullptr, &sizeOfWorkGroupSize);
if (errorCode != ACL_SUCCESS) {
return false;
}
errorCode = g_complibApi._aclQueryInfo(compileHandle, program_->binaryElf(), RT_WORK_GROUP_SIZE,
errorCode = aclQueryInfo(compileHandle, program_->binaryElf(), RT_WORK_GROUP_SIZE,
openClKernelName.c_str(), workGroupInfo_.compileSize_,
&sizeOfWorkGroupSize);
if (errorCode != ACL_SUCCESS) {
@@ -810,7 +806,7 @@ bool Kernel::init() {
// Pull out printf metadata from the ELF
size_t sizeOfPrintfList;
errorCode = g_complibApi._aclQueryInfo(compileHandle, program_->binaryElf(), RT_GPU_PRINTF_ARRAY,
errorCode = aclQueryInfo(compileHandle, program_->binaryElf(), RT_GPU_PRINTF_ARRAY,
openClKernelName.c_str(), nullptr, &sizeOfPrintfList);
if (errorCode != ACL_SUCCESS) {
return false;
@@ -822,7 +818,7 @@ bool Kernel::init() {
if (!aclPrintfList) {
return false;
}
errorCode = g_complibApi._aclQueryInfo(compileHandle, program_->binaryElf(),
errorCode = aclQueryInfo(compileHandle, program_->binaryElf(),
RT_GPU_PRINTF_ARRAY, openClKernelName.c_str(),
aclPrintfList.get(), &sizeOfPrintfList);
if (errorCode != ACL_SUCCESS) {
@@ -833,11 +829,10 @@ bool Kernel::init() {
initPrintf(reinterpret_cast<aclPrintfFmt*>(aclPrintfList.get()));
}
return true;
#endif // !defined(WITH_LIGHTNING_COMPILER)
}
#if defined(WITH_LIGHTNING_COMPILER)
void Kernel::initPrintf_LC(const std::vector<std::string>& printfInfoStrings) {
void LightningKernel::initPrintf(const std::vector<std::string>& printfInfoStrings) {
for (auto str : printfInfoStrings) {
std::vector<std::string> tokens;
@@ -928,7 +923,7 @@ void Kernel::initPrintf_LC(const std::vector<std::string>& printfInfoStrings) {
}
#endif // defined(WITH_LIGHTNING_COMPILER)
void Kernel::initPrintf(const aclPrintfFmt* aclPrintf) {
void HSAILKernel::initPrintf(const aclPrintfFmt* aclPrintf) {
PrintfInfo info;
uint index = 0;
for (; aclPrintf->struct_size != 0; aclPrintf++) {
+50 -22
Zobrazit soubor
@@ -85,7 +85,7 @@ class Kernel : public device::Kernel {
ROC_ACCESS_TYPE access_; //!< Access type for the argument
};
Kernel(std::string name, HSAILProgram* prog, const uint64_t& kernelCodeHandle,
Kernel(std::string name, Program* prog, const uint64_t& kernelCodeHandle,
const uint32_t workgroupGroupSegmentByteSize,
const uint32_t workitemPrivateSegmentByteSize, const uint32_t kernargSegmentByteSize,
const uint32_t kernargSegmentAlignment);
@@ -103,13 +103,9 @@ class Kernel : public device::Kernel {
~Kernel();
//! Initializes the metadata required for this kernel
bool init();
#if defined(WITH_LIGHTNING_COMPILER)
//! Initializes the metadata required for this kernel
bool init_LC();
#endif // defined(WITH_LIGHTNING_COMPILER)
virtual bool init() = 0;
const HSAILProgram* program() const { return static_cast<const HSAILProgram*>(program_); }
const Program* program() const { return static_cast<const Program*>(program_); }
//! Returns the kernel argument list
const std::vector<Argument*>& hsailArgs() const { return hsailArgList_; }
@@ -131,7 +127,7 @@ class Kernel : public device::Kernel {
//! set internal kernel flag
void setInternalKernelFlag(bool flag) { flags_.internalKernel_ = flag; }
private:
protected:
union Flags {
struct {
uint internalKernel_ : 1; //!< Is a blit kernel?
@@ -140,21 +136,8 @@ class Kernel : public device::Kernel {
Flags() : value_(0) {}
} flags_;
//! Populates hsailArgList_
void initArguments(const aclArgData* aclArg);
#if defined(WITH_LIGHTNING_COMPILER)
//! Initializes Hsail Argument metadata and info for LC
void initArguments_LC(const KernelMD& kernelMD);
#endif // defined(WITH_LIGHTNING_COMPILER)
//! Initializes HSAIL Printf metadata and info
void initPrintf(const aclPrintfFmt* aclPrintf);
#if defined(WITH_LIGHTNING_COMPILER)
//! Initializes HSAIL Printf metadata and info for LC
void initPrintf_LC(const std::vector<std::string>& printfInfoStrings);
#endif // defined(WITH_LIGHTNING_COMPILER)
HSAILProgram* program_; //!< The roc::HSAILProgram context
Program* program_; //!< The roc::Program context
std::vector<Argument*> hsailArgList_; //!< Vector list of HSAIL Arguments
uint64_t kernelCodeHandle_; //!< Kernel code handle (aka amd_kernel_code_t)
const uint32_t workgroupGroupSegmentByteSize_;
@@ -165,6 +148,51 @@ class Kernel : public device::Kernel {
std::vector<PrintfInfo> printf_;
};
class HSAILKernel : public roc::Kernel {
public:
HSAILKernel(std::string name, Program* prog, const uint64_t& kernelCodeHandle,
const uint32_t workgroupGroupSegmentByteSize,
const uint32_t workitemPrivateSegmentByteSize,
const uint32_t kernargSegmentByteSize,
const uint32_t kernargSegmentAlignment)
: roc::Kernel(name, prog, kernelCodeHandle, workgroupGroupSegmentByteSize,
workitemPrivateSegmentByteSize, kernargSegmentByteSize, kernargSegmentAlignment) {
}
//! Initializes the metadata required for this kernel
virtual bool init() final;
private:
//! Populates hsailArgList_
void initArguments(const aclArgData* aclArg);
//! Initializes HSAIL Printf metadata and info
void initPrintf(const aclPrintfFmt* aclPrintf);
};
#if defined(WITH_LIGHTNING_COMPILER)
class LightningKernel : public roc::Kernel {
public:
LightningKernel(std::string name, Program* prog, const uint64_t& kernelCodeHandle,
const uint32_t workgroupGroupSegmentByteSize,
const uint32_t workitemPrivateSegmentByteSize,
const uint32_t kernargSegmentByteSize,
const uint32_t kernargSegmentAlignment)
: roc::Kernel(name, prog, kernelCodeHandle, workgroupGroupSegmentByteSize,
workitemPrivateSegmentByteSize, kernargSegmentByteSize, kernargSegmentAlignment) {
}
//! Initializes the metadata required for this kernel
virtual bool init() final;
private:
//! Initializes Hsail Argument metadata and info for LC
void initArguments(const KernelMD& kernelMD);
//! Initializes HSAIL Printf metadata and info for LC
void initPrintf(const std::vector<std::string>& printfInfoStrings);
};
#endif // defined(WITH_LIGHTNING_COMPILER)
} // namespace roc
#endif // WITHOUT_HSA_BACKEND
Rozdílový obsah nebyl zobrazen, protože je příliš veliký Načíst rozdílové porovnání
+73 -52
Zobrazit soubor
@@ -6,9 +6,6 @@
#ifndef WITHOUT_HSA_BACKEND
#include "rocbinary.hpp"
#if !defined(WITH_LIGHTNING_COMPILER)
#include "roccompilerlib.hpp"
#endif // !defined(WITH_LIGHTNING_COMPILER)
#include "acl.h"
#include <string>
#include <sstream>
@@ -29,15 +26,18 @@ typedef llvm::AMDGPU::HSAMD::Kernel::Arg::Metadata KernelArgMD;
//! \namespace roc HSA Device Implementation
namespace roc {
class HSAILProgram;
class LightningProgram;
//! \class empty program
class HSAILProgram : public device::Program {
class Program : public device::Program {
friend class ClBinary;
public:
//! Default constructor
HSAILProgram(roc::NullDevice& device);
Program(roc::NullDevice& device);
//! Default destructor
~HSAILProgram();
~Program();
// Initialize Binary for GPU (used only for clCreateProgramWithBinary()).
virtual bool initClBinary(char* binaryIn, size_t size);
@@ -45,11 +45,6 @@ class HSAILProgram : public device::Program {
//! Returns the aclBinary associated with the program
const aclBinary* binaryElf() const { return static_cast<const aclBinary*>(binaryElf_); }
#if defined(WITH_LIGHTNING_COMPILER)
//! Returns the program metadata.
const CodeObjectMD* metadata() const { return metadata_; }
#endif // defined(WITH_LIGHTNING_COMPILER)
//! Return a typecasted GPU device
const NullDevice& dev() const { return static_cast<const NullDevice&>(device()); }
@@ -65,23 +60,6 @@ class HSAILProgram : public device::Program {
//! post-compile setup for GPU
virtual bool finiBuild(bool isBuildGood);
/*! \brief Compiles GPU CL program to LLVM binary (compiler frontend)
*
* \return True if we successfully compiled a GPU program
*/
virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
const std::vector<const std::string*>& headers,
const char** headerIncludeNames,
amd::option::Options* options //!< compile options's object
);
#if defined(WITH_LIGHTNING_COMPILER)
virtual bool compileImpl_LC(const std::string& sourceCode, //!< the program's source code
const std::vector<const std::string*>& headers,
const char** headerIncludeNames,
amd::option::Options* options //!< compile options's object
);
#endif // defined(WITH_LIGHTNING_COMPILER)
/*! \brief Compiles LLVM binary to HSAIL code (compiler backend: link+opt+codegen)
*
* \return The build error code
@@ -89,22 +67,7 @@ class HSAILProgram : public device::Program {
int compileBinaryToHSAIL(amd::option::Options* options //!< options for compilation
);
virtual bool linkImpl(amd::option::Options* options);
#if defined(WITH_LIGHTNING_COMPILER)
virtual bool linkImpl_LC(amd::option::Options* options);
bool setKernels_LC(amd::option::Options* options, void* binary, size_t binSize);
#endif // defined(WITH_LIGHTNING_COMPILER)
//! Link the device programs.
virtual bool linkImpl(const std::vector<Program*>& inputPrograms, amd::option::Options* options,
bool createLibrary);
#if defined(WITH_LIGHTNING_COMPILER)
virtual bool linkImpl_LC(const std::vector<Program*>& inputPrograms,
amd::option::Options* options, bool createLibrary);
#endif // defined(WITH_LIGHTNING_COMPILER)
virtual bool createBinary(amd::option::Options* options);
virtual bool createBinary(amd::option::Options* options) = 0;
//! Initialize Binary
virtual bool initClBinary();
@@ -127,28 +90,27 @@ class HSAILProgram : public device::Program {
return static_cast<const ClBinary*>(device::Program::clBinary());
}
private:
protected:
/* \brief Returns the next stage to compile from, based on sections in binary,
* also returns completeStages in a vector, which contains at least ACL_TYPE_DEFAULT,
* sets needOptionsCheck to true if options check is needed to decide whether or not to recompile
*/
aclType getCompilationStagesFromBinary(std::vector<aclType>& completeStages,
bool& needOptionsCheck);
virtual aclType getCompilationStagesFromBinary(std::vector<aclType>& completeStages,
bool& needOptionsCheck) = 0;
/* \brief Returns the next stage to compile from, based on sections and options in binary
*/
aclType getNextCompilationStageFromBinary(amd::option::Options* options);
bool saveBinaryAndSetType(type_t type, void* binary = nullptr, size_t size = 0);
//! Disable default copy constructor
HSAILProgram(const HSAILProgram&) = delete;
Program(const Program&) = delete;
//! Disable operator=
HSAILProgram& operator=(const HSAILProgram&) = delete;
Program& operator=(const Program&) = delete;
protected:
//! Returns all the options to be appended while passing to the
// compiler
std::string preprocessorOptions(amd::option::Options* options);
std::string codegenOptions(amd::option::Options* options);
// aclBinary and aclCompiler - for the compiler library
aclBinary* binaryElf_; //!< Binary for the new compiler library
@@ -158,13 +120,72 @@ class HSAILProgram : public device::Program {
/* HSA executable */
hsa_executable_t hsaExecutable_; //!< Handle to HSA executable
hsa_code_object_reader_t hsaCodeObjectReader_; //!< Handle to HSA code reader
};
class HSAILProgram : public roc::Program {
public:
HSAILProgram(roc::NullDevice& device);
virtual ~HSAILProgram();
protected:
virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
const std::vector<const std::string*>& headers,
const char** headerIncludeNames,
amd::option::Options* options //!< compile options's object
) final;
virtual bool linkImpl(amd::option::Options* options) final;
virtual bool linkImpl(const std::vector<device::Program*>& inputPrograms,
amd::option::Options* options, bool createLibrary) final;
virtual bool createBinary(amd::option::Options* options) final;
private:
std::string codegenOptions(amd::option::Options* options);
virtual aclType getCompilationStagesFromBinary(std::vector<aclType>& completeStages,
bool& needOptionsCheck) final;
bool saveBinaryAndSetType(type_t type);
};
#if defined(WITH_LIGHTNING_COMPILER)
class LightningProgram : public roc::Program {
public:
LightningProgram(roc::NullDevice& device);
virtual ~LightningProgram();
//! Returns the program metadata.
const CodeObjectMD* metadata() const { return metadata_; }
protected:
virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
const std::vector<const std::string*>& headers,
const char** headerIncludeNames,
amd::option::Options* options //!< compile options's object
) final;
virtual bool linkImpl(amd::option::Options* options) final;
virtual bool linkImpl(const std::vector<device::Program*>& inputPrograms,
amd::option::Options* options, bool createLibrary) final;
virtual bool createBinary(amd::option::Options* options) final;
private:
bool saveBinaryAndSetType(type_t type, void* rawBinary, size_t size);
virtual aclType getCompilationStagesFromBinary(std::vector<aclType>& completeStages,
bool& needOptionsCheck) final;
bool setKernels(amd::option::Options* options, void* binary, size_t binSize);
CodeObjectMD* metadata_; //!< Runtime metadata
//! Return a new transient compiler instance.
static amd::opencl_driver::Compiler* newCompilerInstance();
#endif // defined(WITH_LIGHTNING_COMPILER)
};
#endif // defined(WITH_LIGHTNING_COMPILER)
/*@}*/} // namespace roc
+16 -18
Zobrazit soubor
@@ -49,18 +49,14 @@ const Symbol* Program::findSymbol(const char* kernelName) const {
cl_int Program::addDeviceProgram(Device& device, const void* image, size_t length,
amd::option::Options* options) {
#if defined(WITH_LIGHTNING_COMPILER)
// LC binary must be in ELF format
if (image != NULL && !amd::isElfMagic((const char*)image)) {
if (image != NULL && !amd::isElfMagic((const char*)image)
#if !defined(WITH_LIGHTNING_COMPILER)
&& !aclValidateBinaryImage(
image, length, isSPIRV_ ? BINARY_TYPE_SPIRV : BINARY_TYPE_ELF | BINARY_TYPE_LLVM)
#endif // !defined(WITH_LIGHTNING_COMPILER)
) {
return CL_INVALID_BINARY;
}
#else // !defined(WITH_LIGHTNING_COMPILER)
if (image != NULL &&
!aclValidateBinaryImage(image, length,
isSPIRV_ ? BINARY_TYPE_SPIRV : BINARY_TYPE_ELF | BINARY_TYPE_LLVM)) {
return CL_INVALID_BINARY;
}
#endif // !defined(WITH_LIGHTNING_COMPILER)
// Check if the device is already associated with this program
if (deviceList_.find(&device) != deviceList_.end()) {
@@ -80,7 +76,6 @@ cl_int Program::addDeviceProgram(Device& device, const void* image, size_t lengt
emptyOptions = true;
}
#if !defined(WITH_LIGHTNING_COMPILER)
if (image != NULL && length != 0 && aclValidateBinaryImage(image, length, BINARY_TYPE_ELF)) {
acl_error errorCode;
aclBinary* binary = aclReadFromMem(image, length, &errorCode);
@@ -102,10 +97,11 @@ cl_int Program::addDeviceProgram(Device& device, const void* image, size_t lengt
return CL_INVALID_COMPILER_OPTIONS;
}
}
options->oVariables->Legacy = isAMDILTarget(*aclutGetTargetInfo(binary));
options->oVariables->Legacy = !IS_LIGHTNING ?
isAMDILTarget(*aclutGetTargetInfo(binary)) :
isHSAILTarget(*aclutGetTargetInfo(binary));
aclBinaryFini(binary);
}
#endif // !defined(WITH_LIGHTNING_COMPILER)
options->oVariables->BinaryIsSpirv = isSPIRV_;
device::Program* program = rootDev.createProgram(options);
if (program == NULL) {
@@ -133,7 +129,7 @@ cl_int Program::addDeviceProgram(Device& device, const void* image, size_t lengt
return CL_INVALID_BINARY;
}
#if defined(WITH_LIGHTNING_COMPILER)
#if 0 && defined(WITH_LIGHTNING_COMPILER)
// load the compiler options from the binary if it is not provided
std::string sBinOptions = program->compileOptions();
if (!sBinOptions.empty() && emptyOptions) {
@@ -143,7 +139,7 @@ cl_int Program::addDeviceProgram(Device& device, const void* image, size_t lengt
return CL_INVALID_COMPILER_OPTIONS;
}
}
#endif
#endif // defined(WITH_LIGHTNING_COMPILER)
}
devicePrograms_[&rootDev] = program;
@@ -300,8 +296,8 @@ cl_int Program::link(const std::vector<Device*>& devices, size_t numInputs,
// Check the binary's target for the first found device program.
// TODO: Revise these binary's target checks
// and possibly remove them after switching to HSAIL by default.
#if !defined(WITH_LIGHTNING_COMPILER)
if (!found && binary.first != NULL && binary.second > 0) {
if (!found && binary.first != NULL && binary.second > 0 &&
aclValidateBinaryImage(binary.first, binary.second, BINARY_TYPE_ELF)) {
acl_error errorCode = ACL_SUCCESS;
void* mem = const_cast<void*>(binary.first);
aclBinary* aclBin = aclReadFromMem(mem, binary.second, &errorCode);
@@ -311,12 +307,14 @@ cl_int Program::link(const std::vector<Device*>& devices, size_t numInputs,
}
if (isHSAILTarget(*aclutGetTargetInfo(aclBin))) {
parsedOptions.oVariables->Frontend = "clang";
#if defined(WITH_LIGHTNING_COMPILER)
parsedOptions.oVariables->Legacy = true;
#endif // defined(WITH_LIGHTNING_COMPILER)
} else if (isAMDILTarget(*aclutGetTargetInfo(aclBin))) {
parsedOptions.oVariables->Frontend = "edg";
}
aclBinaryFini(aclBin);
}
#endif // !defined(WITH_LIGHTNING_COMPILER)
found = true;
}
if (inputDevPrograms.size() == 0) {