From e132af9cad3c1a86f1bb4c3d3b690dca049d5cf4 Mon Sep 17 00:00:00 2001
From: foreman
Date: Wed, 19 Sep 2018 17:06:20 -0400
Subject: [PATCH] P4 to Git Change 1608319 by gandryey@gera-lnx-rcf-lc on
2018/09/19 16:55:11
SWDEV-79445 - OCL generic changes and code clean-up
Program compilation clean-up. Step#2:
- Combine PAL and ROCr implementations of compilation under common methods in device::Program for HSAIL and LC.
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#319 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/devprogram.cpp#2 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/devprogram.hpp#2 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.hpp#74 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palcompiler.cpp#26 delete
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.hpp#34 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.cpp#73 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.hpp#30 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompiler.cpp#46 delete
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.hpp#31 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#87 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.hpp#36 edit
---
rocclr/runtime/device/device.hpp | 9 +
rocclr/runtime/device/devprogram.cpp | 418 ++++++++++++++++++++-
rocclr/runtime/device/devprogram.hpp | 57 ++-
rocclr/runtime/device/gpu/gpuprogram.hpp | 2 +
rocclr/runtime/device/pal/palcompiler.cpp | 404 --------------------
rocclr/runtime/device/pal/paldevice.hpp | 8 -
rocclr/runtime/device/pal/palprogram.cpp | 9 +
rocclr/runtime/device/pal/palprogram.hpp | 35 +-
rocclr/runtime/device/rocm/roccompiler.cpp | 401 --------------------
rocclr/runtime/device/rocm/rocdevice.hpp | 9 +-
rocclr/runtime/device/rocm/rocprogram.cpp | 8 +-
rocclr/runtime/device/rocm/rocprogram.hpp | 16 +-
12 files changed, 504 insertions(+), 872 deletions(-)
delete mode 100644 rocclr/runtime/device/pal/palcompiler.cpp
delete mode 100644 rocclr/runtime/device/rocm/roccompiler.cpp
diff --git a/rocclr/runtime/device/device.hpp b/rocclr/runtime/device/device.hpp
index ed5ce51a29..36dfe95d8e 100644
--- a/rocclr/runtime/device/device.hpp
+++ b/rocclr/runtime/device/device.hpp
@@ -68,6 +68,7 @@ class SvmUnmapMemoryCommand;
class TransferBufferFileCommand;
class HwDebugManager;
class Device;
+class CacheCompilation;
struct KernelParameterDescriptor;
struct Coord3D;
@@ -1300,6 +1301,10 @@ class Device : public RuntimeObject {
// P2P devices that are accessible from the current device
std::vector p2pDevices_;
+#if defined(WITH_LIGHTNING_COMPILER)
+ amd::CacheCompilation* cacheCompilation() const { return cacheCompilation_.get(); }
+#endif
+
protected:
//! Enable the specified extension
char* getExtensionString();
@@ -1310,6 +1315,10 @@ class Device : public RuntimeObject {
BlitProgram* blitProgram_; //!< Blit program info
static AppProfile appProfile_; //!< application profile
HwDebugManager* hwDebugMgr_; //!< Hardware Debug manager
+#if defined(WITH_LIGHTNING_COMPILER)
+ //! Compilation with cache support
+ std::unique_ptr cacheCompilation_;
+#endif
private:
bool IsTypeMatching(cl_device_type type, bool offlineDevices);
diff --git a/rocclr/runtime/device/devprogram.cpp b/rocclr/runtime/device/devprogram.cpp
index 23c5bd697e..27875b0cd0 100644
--- a/rocclr/runtime/device/devprogram.cpp
+++ b/rocclr/runtime/device/devprogram.cpp
@@ -11,11 +11,25 @@
#include "utils/bif_section_labels.hpp"
#include "utils/libUtils.h"
-#include "spirv/spirvUtils.h"
-
+#if defined(WITH_LIGHTNING_COMPILER)
+#include "driver/AmdCompiler.h"
+#include "opencl1.2-c.amdgcn.inc"
+#include "opencl2.0-c.amdgcn.inc"
+#endif // !defined(WITH_LIGHTNING_COMPILER)
+#include
+#include
+#include
#include
#include
+#include
+
+#if defined(ATI_OS_LINUX)
+#include
+#include
+#endif // defined(ATI_OS_LINUX)
+
+#include "spirv/spirvUtils.h"
#include "acl.h"
#if defined(WITH_LIGHTNING_COMPILER)
@@ -40,6 +54,7 @@ Program::Program(amd::Device& device)
lastBuildOptionsArg_(),
buildStatus_(CL_BUILD_NONE),
buildError_(CL_SUCCESS),
+ machineTarget_(nullptr),
globalVariableTotalSize_(0),
programOptions_(nullptr)
{
@@ -63,6 +78,405 @@ void Program::clear() {
kernels_.clear();
}
+// ================================================================================================
+bool Program::compileImpl(const std::string& sourceCode,
+ const std::vector& headers,
+ const char** headerIncludeNames, amd::option::Options* options) {
+ if (isLC()) {
+ return compileImplLC(sourceCode, headers, headerIncludeNames, options);
+ } else {
+ return compileImplHSAIL(sourceCode, headers, headerIncludeNames, options);
+ }
+}
+
+// ================================================================================================
+#if defined(WITH_LIGHTNING_COMPILER)
+static std::string llvmBin_(amd::Os::getEnvironment("LLVM_BIN"));
+
+#if defined(ATI_OS_WIN)
+static BOOL CALLBACK checkLLVM_BIN(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* lpContex) {
+ if (llvmBin_.empty()) {
+ HMODULE hm = nullptr;
+ if (GetModuleHandleExA(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ (LPCSTR)&amd::Device::init, &hm)) {
+ char path[1024];
+ GetModuleFileNameA(hm, path, sizeof(path));
+ llvmBin_ = path;
+ size_t pos = llvmBin_.rfind('\\');
+ if (pos != std::string::npos) {
+ llvmBin_.resize(pos);
+ }
+ }
+ }
+ return TRUE;
+}
+#endif // defined (ATI_OS_WINDOWS)
+
+#if defined(ATI_OS_LINUX)
+static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+static void checkLLVM_BIN() {
+ if (llvmBin_.empty()) {
+ Dl_info info;
+ if (dladdr((const void*)&amd::Device::init, &info)) {
+ char* str = strdup(info.dli_fname);
+ if (str) {
+ llvmBin_ = dirname(str);
+ free(str);
+ size_t pos = llvmBin_.rfind("lib");
+ if (pos != std::string::npos) {
+ llvmBin_.replace(pos, 3, "bin");
+ }
+ }
+ }
+ }
+#if defined(DEBUG)
+ static const std::string tools[] = { "clang", "llvm-link", "ld.lld" };
+
+ for (const std::string tool : tools) {
+ std::string exePath(llvmBin_ + "/" + tool);
+ struct stat buf;
+ if (stat(exePath.c_str(), &buf)) {
+ std::string msg(exePath + " not found");
+ LogWarning(msg.c_str());
+ }
+ else if ((buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) {
+ std::string msg("Cannot execute " + exePath);
+ LogWarning(msg.c_str());
+ }
+ }
+#endif // defined(DEBUG)
+}
+#endif // defined(ATI_OS_LINUX)
+
+std::unique_ptr Program::newCompilerInstance() {
+#if defined(ATI_OS_WIN)
+ static INIT_ONCE initOnce;
+ InitOnceExecuteOnce(&initOnce, checkLLVM_BIN, nullptr, nullptr);
+#endif // defined(ATI_OS_WIN)
+#if defined(ATI_OS_LINUX)
+ pthread_once(&once, checkLLVM_BIN);
+#endif // defined(ATI_OS_LINUX)
+#if defined(DEBUG)
+ std::string clangExe(llvmBin_ + LINUX_SWITCH("/clang", "\\clang.exe"));
+ struct stat buf;
+ if (stat(clangExe.c_str(), &buf)) {
+ std::string msg("Could not find the Clang binary in " + llvmBin_);
+ LogWarning(msg.c_str());
+ }
+#endif // defined(DEBUG)
+
+ return std::unique_ptr(
+ amd::opencl_driver::CompilerFactory().CreateAMDGPUCompiler(llvmBin_));
+}
+#endif // defined(WITH_LIGHTNING_COMPILER)
+
+// ================================================================================================
+bool Program::compileImplLC(const std::string& sourceCode,
+ const std::vector& headers,
+ const char** headerIncludeNames, amd::option::Options* options) {
+#if defined(WITH_LIGHTNING_COMPILER)
+ const char* xLang = options->oVariables->XLang;
+ if (xLang != nullptr) {
+ if (strcmp(xLang, "asm") == 0) {
+ clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
+ return true;
+ }
+ else if (!strcmp(xLang, "cl")) {
+ buildLog_ += "Unsupported language: \"" + std::string(xLang) + "\".\n";
+ return false;
+ }
+ }
+
+ using namespace amd::opencl_driver;
+ std::unique_ptr C(newCompilerInstance());
+ std::vector inputs;
+
+ Data* input = C->NewBufferReference(DT_CL, sourceCode.c_str(), sourceCode.length());
+ if (input == nullptr) {
+ buildLog_ += "Error while creating data from source code";
+ return false;
+ }
+
+ inputs.push_back(input);
+
+ amd::opencl_driver::Buffer* output = C->NewBuffer(DT_LLVM_BC);
+ if (output == nullptr) {
+ buildLog_ += "Error while creating buffer for the LLVM bitcode";
+ return false;
+ }
+
+ // Set the options for the compiler
+ // Some options are set in Clang AMDGPUToolChain (like -m64)
+ std::ostringstream ostrstr;
+ std::copy(options->clangOptions.begin(), options->clangOptions.end(),
+ std::ostream_iterator(ostrstr, " "));
+
+ std::string driverOptions(ostrstr.str());
+
+ // Setting the language
+ driverOptions.append(" -cl-std=").append(options->oVariables->CLStd);
+
+ // Set the -O#
+ std::ostringstream optLevel;
+ optLevel << " -O" << options->oVariables->OptLevel;
+ driverOptions.append(optLevel.str());
+
+ // Set the machine target
+ driverOptions.append(" -mcpu=");
+ driverOptions.append(machineTarget_);
+
+ // Set xnack option if needed
+ if (xnackEnabled_) {
+ driverOptions.append(" -mxnack");
+ }
+
+ driverOptions.append(options->llvmOptions);
+ driverOptions.append(ProcessOptions(options));
+
+ // Set whole program mode
+ driverOptions.append(" -mllvm -amdgpu-early-inline-all -mllvm -amdgpu-prelink");
+
+ // Find the temp folder for the OS
+ std::string tempFolder = amd::Os::getTempPath();
+
+ // Iterate through each source code and dump it into tmp
+ std::fstream f;
+ std::vector headerFileNames(headers.size());
+ std::vector 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 (auto& it : headerIncludeName) {
+ 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();
+
+ Data* inc = C->NewFileReference(DT_CL_HEADER, headerFileNames[i]);
+ if (inc == nullptr) {
+ buildLog_ += "Error while creating data from headers";
+ return false;
+ }
+ inputs.push_back(inc);
+ }
+
+ // Set the include path for the temp folder that contains the includes
+ if (!headers.empty()) {
+ driverOptions.append(" -I");
+ driverOptions.append(tempFolder);
+ }
+
+ if (options->isDumpFlagSet(amd::option::DUMP_CL)) {
+ std::ofstream f(options->getDumpFileName(".cl").c_str(), std::ios::trunc);
+ if (f.is_open()) {
+ f << "/* Compiler options:\n"
+ "-c -emit-llvm -target amdgcn-amd-amdhsa -x cl "
+ << driverOptions << " -include opencl-c.h "
+ << "\n*/\n\n"
+ << sourceCode;
+ f.close();
+ }
+ else {
+ buildLog_ += "Warning: opening the file to dump the OpenCL source failed.\n";
+ }
+ }
+
+ // FIXME_lmoriche: has the CL option been validated?
+ uint clcStd =
+ (options->oVariables->CLStd[2] - '0') * 100 + (options->oVariables->CLStd[4] - '0') * 10;
+
+ std::pair hdr;
+ switch (clcStd) {
+ case 100:
+ case 110:
+ case 120:
+ hdr = { opencl1_2_c_amdgcn, opencl1_2_c_amdgcn_size };
+ break;
+ case 200:
+ hdr = { opencl2_0_c_amdgcn, opencl2_0_c_amdgcn_size };
+ break;
+ default:
+ buildLog_ += "Unsupported requested OpenCL C version (-cl-std).\n";
+ return false;
+ }
+
+ File* pch = C->NewTempFile(DT_CL_HEADER);
+ if (pch == nullptr || !pch->WriteData((const char*)hdr.first, hdr.second)) {
+ buildLog_ += "Error while opening the opencl-c header ";
+ return false;
+ }
+
+ driverOptions.append(" -include-pch " + pch->Name());
+ driverOptions.append(" -Xclang -fno-validate-pch");
+
+ // Tokenize the options string into a vector of strings
+ std::istringstream istrstr(driverOptions);
+ std::istream_iterator sit(istrstr), end;
+ std::vector params(sit, end);
+
+ // Compile source to IR
+ bool ret =
+ device().cacheCompilation()->compileToLLVMBitcode(C.get(), inputs, output, params, buildLog_);
+ buildLog_ += C->Output();
+ if (!ret) {
+ buildLog_ += "Error: Failed to compile opencl source (from CL to LLVM IR).\n";
+ return false;
+ }
+
+ llvmBinary_.assign(output->Buf().data(), output->Size());
+ elfSectionType_ = amd::OclElf::LLVMIR;
+
+ if (options->isDumpFlagSet(amd::option::DUMP_BC_ORIGINAL)) {
+ std::ofstream f(options->getDumpFileName("_original.bc").c_str(),
+ std::ios::binary | std::ios::trunc);
+ if (f.is_open()) {
+ f.write(llvmBinary_.data(), llvmBinary_.size());
+ f.close();
+ }
+ else {
+ buildLog_ += "Warning: opening the file to dump the compiled IR failed.\n";
+ }
+ }
+
+ if (clBinary()->saveSOURCE()) {
+ clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
+ }
+ if (clBinary()->saveLLVMIR()) {
+ clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
+ false);
+ // store the original compile options
+ clBinary()->storeCompileOptions(compileOptions_);
+ }
+#endif // defined(WITH_LIGHTNING_COMPILER)
+ return true;
+}
+
+// ================================================================================================
+static void logFunction(const char* msg, size_t size) {
+ std::cout << "Compiler Log: " << msg << std::endl;
+}
+
+// ================================================================================================
+bool Program::compileImplHSAIL(const std::string& sourceCode,
+ const std::vector& headers,
+ const char** headerIncludeNames, amd::option::Options* options) {
+#if defined(WITH_COMPILER_LIB) || !defined(WITH_LIGHTNING_COMPILER)
+ acl_error errorCode;
+ aclTargetInfo target;
+
+ std::string arch = LP64_SWITCH("hsail", "hsail64");
+ target = aclGetTargetInfo(arch.c_str(), machineTarget_, &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::getTempPath();
+
+ // Iterate through each source code and dump it into tmp
+ std::fstream f;
+ std::vector 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 (auto& it : headerIncludeName) {
+ 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;
+ 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: 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: Inserting openCl Source to binary\n";
+ }
+
+ // Set the options for the compiler
+ // Set the include path for the temp folder that contains the includes
+ if (!headers.empty()) {
+ compileOptions_.append(" -I");
+ compileOptions_.append(tempFolder);
+ }
+
+#if !defined(_LP64) && defined(ATI_OS_LINUX)
+ if (options->origOptionStr.find("-cl-std=CL2.0") != std::string::npos) {
+ errorCode = ACL_UNSUPPORTED;
+ LogWarning("aclCompile failed");
+ return false;
+ }
+#endif
+
+ // Compile source to IR
+ compileOptions_.append(ProcessOptions(options));
+ errorCode = aclCompile(device().compiler(), binaryElf_, compileOptions_.c_str(), ACL_TYPE_OPENCL,
+ ACL_TYPE_LLVMIR_BINARY, nullptr /* logFunction */);
+ buildLog_ += aclGetCompilerLog(device().compiler());
+ if (errorCode != ACL_SUCCESS) {
+ LogWarning("aclCompile failed");
+ buildLog_ += "Error: Compiling CL to IR\n";
+ return false;
+ }
+
+ clBinary()->storeCompileOptions(compileOptions_);
+
+ // Save the binary in the interface class
+ saveBinaryAndSetType(TYPE_COMPILED);
+#endif // defined(WITH_COMPILER_LIB) || !defined(WITH_LIGHTNING_COMPILER)
+ return true;
+}
+
// ================================================================================================
bool Program::initClBinary() {
if (clBinary_ == nullptr) {
diff --git a/rocclr/runtime/device/devprogram.hpp b/rocclr/runtime/device/devprogram.hpp
index 8e358d761a..1da4767553 100644
--- a/rocclr/runtime/device/devprogram.hpp
+++ b/rocclr/runtime/device/devprogram.hpp
@@ -10,13 +10,20 @@
#include "devwavelimiter.hpp"
#if defined(WITH_LIGHTNING_COMPILER)
+#include "driver/AmdCompiler.h"
+//#include "llvm/Support/AMDGPUMetadata.h"
+
namespace llvm {
namespace AMDGPU {
namespace HSAMD {
namespace Kernel {
struct Metadata;
}}}}
+
+//typedef llvm::AMDGPU::HSAMD::Metadata CodeObjectMD;
typedef llvm::AMDGPU::HSAMD::Kernel::Metadata KernelMD;
+//typedef llvm::AMDGPU::HSAMD::Kernel::Arg::Metadata KernelArgMD;
+
#endif // defined(WITH_LIGHTNING_COMPILER)
namespace amd {
@@ -64,9 +71,8 @@ class Program : public amd::HeapObject {
//! The device target for this binary.
amd::SharedReference device_;
- kernels_t kernels_; //!< The kernel entry points this binary.
-
- type_t type_; //!< type of this program
+ kernels_t kernels_; //!< The kernel entry points this binary.
+ type_t type_; //!< type of this program
protected:
union {
@@ -75,6 +81,7 @@ class Program : public amd::HeapObject {
uint32_t internal_ : 1; //!< Internal blit program
uint32_t isLC_ : 1; //!< LC was used for the program compilation
uint32_t hasGlobalStores_ : 1; //!< Program has writable program scope variables
+ uint32_t xnackEnabled_ : 1; //!< Xnack was enabled during compilation
};
uint32_t flags_; //!< Program flags
};
@@ -86,15 +93,16 @@ class Program : public amd::HeapObject {
std::string linkOptions_; //!< link options.
//!< the option arg passed in to clCompileProgram(), clLinkProgram(),
//! or clBuildProgram(), whichever is called last
- aclBinaryOptions binOpts_; //!< Binary options to create aclBinary
- aclBinary* binaryElf_; //!< Binary for the new compiler library
+ aclBinaryOptions binOpts_; //!< Binary options to create aclBinary
+ aclBinary* binaryElf_; //!< Binary for the new compiler library
std::string lastBuildOptionsArg_;
- std::string buildLog_; //!< build log.
- cl_int buildStatus_; //!< build status.
- cl_int buildError_; //!< build error
- //! The info target for this binary.
- aclTargetInfo info_;
+ std::string buildLog_; //!< build log.
+ cl_int buildStatus_; //!< build status.
+ cl_int buildError_; //!< build error
+
+ const char* machineTarget_; //!< Machine target for this program
+ aclTargetInfo info_; //!< The info target for this binary.
size_t globalVariableTotalSize_;
amd::option::Options* programOptions_;
@@ -179,16 +187,32 @@ class Program : public amd::HeapObject {
bool hasGlobalStores() const { return hasGlobalStores_; }
protected:
+ //! Compile the device program with LC path
+ bool compileImplLC(const std::string& sourceCode,
+ const std::vector& headers,
+ const char** headerIncludeNames, amd::option::Options* options);
+
+ //! Compile the device program with HSAIL path
+ bool compileImplHSAIL(const std::string& sourceCode,
+ const std::vector& headers,
+ const char** headerIncludeNames, amd::option::Options* options);
+
//! pre-compile setup
virtual bool initBuild(amd::option::Options* options);
//! post-compile cleanup
virtual bool finiBuild(bool isBuildGood);
- //! Compile the device program.
- virtual bool compileImpl(const std::string& sourceCode,
+ /*! \brief Compiles GPU CL program to LLVM binary (compiler frontend)
+ *
+ * \return True if we successefully compiled a GPU program
+ */
+ virtual bool compileImpl(
+ const std::string& sourceCode, //!< the program's source code
const std::vector& headers,
- const char** headerIncludeNames, amd::option::Options* options) = 0;
+ const char** headerIncludeNames,
+ amd::option::Options* options //!< compile options's object
+ );
//! Link the device program.
virtual bool linkImpl(amd::option::Options* options) = 0;
@@ -205,6 +229,8 @@ class Program : public amd::HeapObject {
//! Initialize Binary
virtual bool initClBinary();
+ virtual bool saveBinaryAndSetType(type_t type) = 0;
+
//! Release the Binary
void releaseClBinary();
@@ -223,6 +249,11 @@ class Program : public amd::HeapObject {
void setType(type_t newType) { type_ = newType; }
+#if defined(WITH_LIGHTNING_COMPILER)
+ //! Return a new transient compiler instance.
+ static std::unique_ptr newCompilerInstance();
+#endif // defined(WITH_LIGHTNING_COMPILER)
+
private:
//! Disable default copy constructor
Program(const Program&);
diff --git a/rocclr/runtime/device/gpu/gpuprogram.hpp b/rocclr/runtime/device/gpu/gpuprogram.hpp
index 58d61d693a..cbbb4590cd 100644
--- a/rocclr/runtime/device/gpu/gpuprogram.hpp
+++ b/rocclr/runtime/device/gpu/gpuprogram.hpp
@@ -265,6 +265,8 @@ class NullProgram : public device::Program {
virtual const aclTargetInfo& info(const char* str = "");
+ virtual bool saveBinaryAndSetType(type_t type) { return true; }
+
private:
//! Disable default copy constructor
NullProgram(const NullProgram&);
diff --git a/rocclr/runtime/device/pal/palcompiler.cpp b/rocclr/runtime/device/pal/palcompiler.cpp
deleted file mode 100644
index 4077ce22cc..0000000000
--- a/rocclr/runtime/device/pal/palcompiler.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-//
-// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved.
-//
-
-#include
-#include
-#include
-#include
-#include
-
-#include "os/os.hpp"
-#include "device/pal/paldevice.hpp"
-#include "device/pal/palprogram.hpp"
-#include "device/pal/palkernel.hpp"
-#include "utils/options.hpp"
-#if defined(WITH_LIGHTNING_COMPILER)
-#include "driver/AmdCompiler.h"
-#include "opencl1.2-c.amdgcn.inc"
-#include "opencl2.0-c.amdgcn.inc"
-#endif // !defined(WITH_LIGHTNING_COMPILER)
-#include
-
-#if defined(ATI_OS_LINUX)
-#include
-#include
-#endif // defined(ATI_OS_LINUX)
-#if defined(ATI_OS_WIN)
-#include
-#endif // defined(ATI_OS_WIN)
-
-// CLC_IN_PROCESS_CHANGE
-extern int openclFrontEnd(const char* cmdline, std::string*, std::string* typeInfo = nullptr);
-
-namespace pal {
-
-bool HSAILProgram::compileImpl(const std::string& sourceCode,
- const std::vector& headers,
- const char** headerIncludeNames, amd::option::Options* options) {
-#if defined(WITH_LIGHTNING_COMPILER)
- assert(!"Should not reach here");
-#else // !defined(WITH_LIGHTNING_COMPILER)
- acl_error errorCode;
- aclTargetInfo target;
-
- std::string arch = "hsail";
- if (dev().settings().use64BitPtr_) {
- arch += "64";
- }
- target = aclGetTargetInfo(arch.c_str(), dev().hwInfo()->targetName_, &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::getTempPath();
-
- // Iterate through each source code and dump it into tmp
- std::fstream f;
- std::vector 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 (auto& it : headerIncludeName) {
- 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;
- 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: aclBinary init failure\n";
- LogWarning("aclBinaryInit failed");
- return false;
- }
-
- // Insert opencl into binary
- errorCode = aclInsertSection(dev().compiler(), binaryElf_, sourceCode.c_str(),
- strlen(sourceCode.c_str()), aclSOURCE);
- if (errorCode != ACL_SUCCESS) {
- buildLog_ += "Error: Inserting openCl Source to binary\n";
- }
-
- // Set the options for the compiler
- // Set the include path for the temp folder that contains the includes
- if (!headers.empty()) {
- compileOptions_.append(" -I");
- compileOptions_.append(tempFolder);
- }
-
-#if !defined(_LP64) && defined(ATI_OS_LINUX)
- if (options->origOptionStr.find("-cl-std=CL2.0") != std::string::npos &&
- !dev().settings().force32BitOcl20_) {
- errorCode = ACL_UNSUPPORTED;
- LogWarning("aclCompile failed");
- return false;
- }
-#endif
-
- // Compile source to IR
- compileOptions_.append(ProcessOptions(options));
- errorCode = aclCompile(dev().compiler(), binaryElf_, compileOptions_.c_str(), ACL_TYPE_OPENCL,
- ACL_TYPE_LLVMIR_BINARY, nullptr);
- buildLog_ += aclGetCompilerLog(dev().compiler());
- if (errorCode != ACL_SUCCESS) {
- LogWarning("aclCompile failed");
- buildLog_ += "Error: Compiling CL to IR\n";
- return false;
- }
-
- clBinary()->storeCompileOptions(compileOptions_);
-
- // Save the binary in the interface class
- saveBinaryAndSetType(TYPE_COMPILED);
-#endif // !defined(WITH_LIGHTNING_COMPILER)
- return true;
-}
-
-#if defined(WITH_LIGHTNING_COMPILER)
-static std::string llvmBin_(amd::Os::getEnvironment("LLVM_BIN"));
-
-#if defined(ATI_OS_WIN)
-static BOOL CALLBACK checkLLVM_BIN(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* lpContex) {
- if (llvmBin_.empty()) {
- HMODULE hm = NULL;
- if (GetModuleHandleExA(
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- (LPCSTR)&amd::Device::init, &hm)) {
- char path[1024];
- GetModuleFileNameA(hm, path, sizeof(path));
- llvmBin_ = path;
- size_t pos = llvmBin_.rfind('\\');
- if (pos != std::string::npos) {
- llvmBin_.resize(pos);
- }
- }
- }
- return TRUE;
-}
-#endif // defined (ATI_OS_WINDOWS)
-
-#if defined(ATI_OS_LINUX)
-static pthread_once_t once = PTHREAD_ONCE_INIT;
-
-static void checkLLVM_BIN() {
- if (llvmBin_.empty()) {
- Dl_info info;
- if (dladdr((const void*)&amd::Device::init, &info)) {
- char* str = strdup(info.dli_fname);
- if (str) {
- llvmBin_ = dirname(str);
- free(str);
- size_t pos = llvmBin_.rfind("lib");
- if (pos != std::string::npos) {
- llvmBin_.replace(pos, 3, "bin");
- }
- }
- }
- }
-}
-#endif // defined(ATI_OS_LINUX)
-
-std::unique_ptr LightningProgram::newCompilerInstance() {
-#if defined(ATI_OS_WIN)
- static INIT_ONCE initOnce;
- InitOnceExecuteOnce(&initOnce, checkLLVM_BIN, NULL, NULL);
-#endif // defined(ATI_OS_WIN)
-#if defined(ATI_OS_LINUX)
- pthread_once(&once, checkLLVM_BIN);
-#endif // defined(ATI_OS_LINUX)
-#if defined(DEBUG)
- std::string clangExe(llvmBin_ + LINUX_SWITCH("/clang", "\\clang.exe"));
- struct stat buf;
- if (stat(clangExe.c_str(), &buf)) {
- std::string msg("Could not find the Clang binary in " + llvmBin_);
- LogWarning(msg.c_str());
- }
-#endif // defined(DEBUG)
-
- return std::unique_ptr(
- amd::opencl_driver::CompilerFactory().CreateAMDGPUCompiler(llvmBin_));
-}
-
-bool LightningProgram::compileImpl(const std::string& sourceCode,
- const std::vector& headers,
- const char** headerIncludeNames, amd::option::Options* options) {
- using namespace amd::opencl_driver;
- std::unique_ptr C(newCompilerInstance());
- std::vector inputs;
-
- Data* input = C->NewBufferReference(DT_CL, sourceCode.c_str(), sourceCode.length());
- if (input == NULL) {
- buildLog_ += "Error while creating data from source code";
- return false;
- }
-
- inputs.push_back(input);
-
- amd::opencl_driver::Buffer* output = C->NewBuffer(DT_LLVM_BC);
- if (output == NULL) {
- buildLog_ += "Error while creating buffer for the LLVM bitcode";
- return false;
- }
-
- // Set the options for the compiler
- // Some options are set in Clang AMDGPUToolChain (like -m64)
- std::ostringstream ostrstr;
- std::copy(options->clangOptions.begin(), options->clangOptions.end(),
- std::ostream_iterator(ostrstr, " "));
-
- std::string driverOptions(ostrstr.str());
-
- const char* xLang = options->oVariables->XLang;
- if (xLang != NULL && strcmp(xLang, "cl")) {
- buildLog_ += "Unsupported OpenCL language.\n";
- }
-
- // FIXME_Nikolay: the program manager should be setting the language
- // driverOptions.append(" -x cl");
-
- driverOptions.append(" -cl-std=").append(options->oVariables->CLStd);
-
- // Set the -O#
- std::ostringstream optLevel;
- optLevel << " -O" << options->oVariables->OptLevel;
- driverOptions.append(optLevel.str());
-
- // Set the machine target
- std::ostringstream mCPU;
- mCPU << " -mcpu=gfx" << dev().hwInfo()->gfxipVersion_;
- driverOptions.append(mCPU.str());
-
- // Set xnack option if needed
- if (dev().hwInfo()->xnackEnabled_) {
- driverOptions.append(" -mxnack");
- }
-
- driverOptions.append(options->llvmOptions);
- driverOptions.append(ProcessOptions(options));
-
- // Set whole program mode
- driverOptions.append(" -mllvm -amdgpu-early-inline-all -mllvm -amdgpu-prelink");
-
- // 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 headerFileNames(headers.size());
- std::vector 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 (auto& it : headerIncludeName) {
- 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();
-
- Data* inc = C->NewFileReference(DT_CL_HEADER, headerFileNames[i]);
- if (inc == NULL) {
- buildLog_ += "Error while creating data from headers";
- return false;
- }
- inputs.push_back(inc);
- }
-
- // Set the include path for the temp folder that contains the includes
- if (!headers.empty()) {
- driverOptions.append(" -I");
- driverOptions.append(tempFolder);
- }
-
- if (options->isDumpFlagSet(amd::option::DUMP_CL)) {
- std::ofstream f(options->getDumpFileName(".cl").c_str(), std::ios::trunc);
- if (f.is_open()) {
- f << "/* Compiler options:\n"
- "-c -emit-llvm -target amdgcn-amd-amdhsa -x cl "
- << driverOptions << " -include opencl-c.h "
- << "\n*/\n\n"
- << sourceCode;
- f.close();
- } else {
- buildLog_ += "Warning: opening the file to dump the OpenCL source failed.\n";
- }
- }
-
- // FIXME_lmoriche: has the CL option been validated?
- uint clcStd =
- (options->oVariables->CLStd[2] - '0') * 100 + (options->oVariables->CLStd[4] - '0') * 10;
-
- std::pair hdr;
- switch (clcStd) {
- case 100:
- case 110:
- case 120:
- hdr = {opencl1_2_c_amdgcn, opencl1_2_c_amdgcn_size};
- break;
- case 200:
- hdr = {opencl2_0_c_amdgcn, opencl2_0_c_amdgcn_size};
- break;
- default:
- buildLog_ += "Unsupported requested OpenCL C version (-cl-std).\n";
- return false;
- }
-
- File* pch = C->NewTempFile(DT_CL_HEADER);
- if (pch == NULL || !pch->WriteData((const char*)hdr.first, hdr.second)) {
- buildLog_ += "Error while opening the opencl-c header ";
- return false;
- }
-
- driverOptions.append(" -include-pch " + pch->Name());
- driverOptions.append(" -Xclang -fno-validate-pch");
-
- // Tokenize the options string into a vector of strings
- std::istringstream istrstr(driverOptions);
- std::istream_iterator sit(istrstr), end;
- std::vector params(sit, end);
-
- // Compile source to IR
- bool ret =
- dev().cacheCompilation()->compileToLLVMBitcode(C.get(), inputs, output, params, buildLog_);
- buildLog_ += C->Output();
- if (!ret) {
- buildLog_ += "Error: Failed to compile opencl source (from CL to LLVM IR).\n";
- return false;
- }
-
- llvmBinary_.assign(output->Buf().data(), output->Size());
- elfSectionType_ = amd::OclElf::LLVMIR;
-
- if (options->isDumpFlagSet(amd::option::DUMP_BC_ORIGINAL)) {
- std::ofstream f(options->getDumpFileName("_original.bc").c_str(),
- std::ios::binary | std::ios::trunc);
- if (f.is_open()) {
- f.write(llvmBinary_.data(), llvmBinary_.size());
- f.close();
- } else {
- buildLog_ += "Warning: opening the file to dump the compiled IR failed.\n";
- }
- }
-
- if (clBinary()->saveSOURCE()) {
- clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
- }
- if (clBinary()->saveLLVMIR()) {
- clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
- false);
- // store the original compile options
- clBinary()->storeCompileOptions(compileOptions_);
- }
- return true;
-}
-#endif // defined(WITH_LIGHTNING_COMPILER)
-
-} // namespace pal
diff --git a/rocclr/runtime/device/pal/paldevice.hpp b/rocclr/runtime/device/pal/paldevice.hpp
index f3fd74fc6b..f27bbd55a7 100644
--- a/rocclr/runtime/device/pal/paldevice.hpp
+++ b/rocclr/runtime/device/pal/paldevice.hpp
@@ -110,10 +110,6 @@ class NullDevice : public amd::Device {
}
virtual void svmFree(void* ptr) const { return; }
-#if defined(WITH_LIGHTNING_COMPILER)
- amd::CacheCompilation* cacheCompilation() const { return cacheCompilation_.get(); }
-#endif
-
void* Alloc(const Util::AllocInfo& allocInfo) { return allocator_.Alloc(allocInfo); }
void Free(const Util::FreeInfo& freeInfo) { allocator_.Free(freeInfo); }
@@ -124,10 +120,6 @@ class NullDevice : public amd::Device {
Pal::GfxIpLevel ipLevel_; //!< Device IP level
const AMDDeviceInfo* hwInfo_; //!< Device HW info structure
-#if defined(WITH_LIGHTNING_COMPILER)
- std::unique_ptr cacheCompilation_; //! Compilation with cache support
-#endif
-
//! Fills OpenCL device info structure
void fillDeviceInfo(const Pal::DeviceProperties& palProp, //!< PAL device properties
const Pal::GpuMemoryHeapProperties heaps[Pal::GpuHeapCount],
diff --git a/rocclr/runtime/device/pal/palprogram.cpp b/rocclr/runtime/device/pal/palprogram.cpp
index 324f217624..071004789b 100644
--- a/rocclr/runtime/device/pal/palprogram.cpp
+++ b/rocclr/runtime/device/pal/palprogram.cpp
@@ -143,6 +143,13 @@ HSAILProgram::HSAILProgram(Device& device)
maxScratchRegs_(0),
executable_(nullptr),
loaderContext_(this) {
+ xnackEnabled_ = dev().hwInfo()->xnackEnabled_;
+ if (dev().properties().revision == Pal::AsicRevision::Bristol) {
+ const static char* Carrizo = "Carrizo";
+ machineTarget_ = Carrizo;
+ } else {
+ machineTarget_ = dev().hwInfo()->targetName_;
+ }
loader_ = amd::hsa::loader::Loader::Create(&loaderContext_);
}
@@ -156,6 +163,8 @@ HSAILProgram::HSAILProgram(NullDevice& device)
executable_(nullptr),
loaderContext_(this) {
isNull_ = true;
+ xnackEnabled_ = dev().hwInfo()->xnackEnabled_;
+ machineTarget_ = dev().hwInfo()->targetName_;
loader_ = amd::hsa::loader::Loader::Create(&loaderContext_);
}
diff --git a/rocclr/runtime/device/pal/palprogram.hpp b/rocclr/runtime/device/pal/palprogram.hpp
index aed9715971..582385a6d6 100644
--- a/rocclr/runtime/device/pal/palprogram.hpp
+++ b/rocclr/runtime/device/pal/palprogram.hpp
@@ -181,16 +181,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 successefully compiled a GPU program
- */
- virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
- const std::vector& headers,
- const char** headerIncludeNames,
- amd::option::Options* options //!< compile options's object
- );
-
/* \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
@@ -251,9 +241,21 @@ class HSAILProgram : public device::Program {
//! \class Lightning Compiler Program
class LightningProgram : public HSAILProgram {
public:
- LightningProgram(NullDevice& device) : HSAILProgram(device), metadata_(nullptr) {}
+ LightningProgram(NullDevice& device)
+ : HSAILProgram(device)
+ , metadata_(nullptr) {
+ isLC_ = true;
+ xnackEnabled_ = dev().hwInfo()->xnackEnabled_;
+ machineTarget_ = dev().hwInfo()->machineTarget_;
+ }
- LightningProgram(Device& device) : HSAILProgram(device), metadata_(nullptr) {}
+ LightningProgram(Device& device)
+ : HSAILProgram(device)
+ , metadata_(nullptr) {
+ isLC_ = true;
+ xnackEnabled_ = dev().hwInfo()->xnackEnabled_;
+ machineTarget_ = dev().hwInfo()->machineTarget_;
+ }
const CodeObjectMD* metadata() const { return metadata_; }
@@ -272,12 +274,6 @@ class LightningProgram : public HSAILProgram {
aclType getNextCompilationStageFromBinary(amd::option::Options* options);
protected:
- virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
- const std::vector& headers,
- const char** headerIncludeNames,
- amd::option::Options* options //!< compile options's object
- ) override;
-
virtual bool linkImpl(amd::option::Options* options) override;
//! Link the device programs.
@@ -288,9 +284,6 @@ class LightningProgram : public HSAILProgram {
virtual bool createBinary(amd::option::Options* options) override;
- //! Return a new transient compiler instance.
- static std::unique_ptr newCompilerInstance();
-
private:
CodeObjectMD* metadata_; //!< Runtime metadata
};
diff --git a/rocclr/runtime/device/rocm/roccompiler.cpp b/rocclr/runtime/device/rocm/roccompiler.cpp
deleted file mode 100644
index c1011b7d35..0000000000
--- a/rocclr/runtime/device/rocm/roccompiler.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-//
-// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved.
-//
-#ifndef WITHOUT_HSA_BACKEND
-
-#include
-#include
-#include
-#include
-
-#include "os/os.hpp"
-#include "rocdevice.hpp"
-#include "rocprogram.hpp"
-#if defined(WITH_LIGHTNING_COMPILER)
-#include "opencl1.2-c.amdgcn.inc"
-#include "opencl2.0-c.amdgcn.inc"
-#endif // defined(WITH_LIGHTNING_COMPILER)
-#include "utils/options.hpp"
-#include
-#include
-
-#if defined(ATI_OS_LINUX)
-#include
-#include
-#endif // defined(ATI_OS_LINUX)
-
-#define QUOTE(s) #s
-#define STRING(s) QUOTE(s)
-#define AMDGCN_TRIPLE amdgcn-amd-amdhsa
-
-#if defined(WITH_LIGHTNING_COMPILER)
-static std::string llvmBin_(amd::Os::getEnvironment("LLVM_BIN"));
-#endif // defined(WITH_LIGHTNING_COMPILER)
-
-// CLC_IN_PROCESS_CHANGE
-extern int openclFrontEnd(const char* cmdline, std::string*, std::string* typeInfo = nullptr);
-
-namespace roc {
-
-/* Temporary log function for the compiler library */
-static void logFunction(const char* msg, size_t size) {
- std::cout << "Compiler Log: " << msg << std::endl;
-}
-
-static int programsCount = 0;
-
-#if defined(WITH_COMPILER_LIB)
-bool HSAILProgram::compileImpl(const std::string& sourceCode,
- const std::vector& 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 headerFileNames(headers.size());
- std::vector 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 (auto& it : headerIncludeName) {
- 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);
- }
-
- // Compile source to IR
- this->compileOptions_.append(ProcessOptions(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;
-}
-#endif // defined(WITH_COMPILER_LIB)
-
-#if defined(WITH_LIGHTNING_COMPILER)
-bool LightningProgram::compileImpl(const std::string& sourceCode,
- const std::vector& headers,
- const char** headerIncludeNames, amd::option::Options* options) {
- const char* xLang = options->oVariables->XLang;
- if (xLang != nullptr) {
- if (strcmp(xLang,"asm") == 0) {
- clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
- return true;
- } else if (!strcmp(xLang,"cl")) {
- buildLog_ += "Unsupported language: \"" + std::string(xLang) + "\".\n";
- return false;
- }
- }
-
- using namespace amd::opencl_driver;
- amd::opencl_driver::DataType inputType(DT_CL);
- std::unique_ptr C(newCompilerInstance());
- std::vector inputs;
-
- Data* input = C->NewBufferReference(inputType, sourceCode.c_str(), sourceCode.length());
- if (input == nullptr) {
- buildLog_ += "Error while creating data from source code";
- return false;
- }
-
- inputs.push_back(input);
-
- Buffer* output = C->NewBuffer(DT_LLVM_BC);
- if (output == nullptr) {
- buildLog_ += "Error while creating buffer for the LLVM bitcode";
- return false;
- }
-
- // Set the options for the compiler
- // Some options are set in Clang AMDGPUToolChain (like -m64)
- std::ostringstream ostrstr;
- std::copy(options->clangOptions.begin(), options->clangOptions.end(),
- std::ostream_iterator(ostrstr, " "));
-
- std::string driverOptions(ostrstr.str());
-
- // FIXME_Nikolay: the program manager should be setting the language
- // driverOptions.append(" -x cl");
-
- driverOptions.append(" -cl-std=").append(options->oVariables->CLStd);
-
- // Set the -O#
- std::ostringstream optLevel;
- optLevel << " -O" << options->oVariables->OptLevel;
- driverOptions.append(optLevel.str());
-
- // Set the machine target
- driverOptions.append(" -mcpu=");
- driverOptions.append(dev().deviceInfo().machineTarget_);
-
- // Set xnack option if needed
- if (dev().deviceInfo().xnackEnabled_) {
- driverOptions.append(" -mxnack");
- }
-
- driverOptions.append(options->llvmOptions);
-
- // Set whole program mode
- driverOptions.append(" -mllvm -amdgpu-early-inline-all -mllvm -amdgpu-prelink");
-
- driverOptions.append(ProcessOptions(options));
-
- // 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 headerFileNames(headers.size());
- std::vector 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 (auto& it : headerIncludeName) {
- 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();
-
- Data* inc = C->NewFileReference(DT_CL_HEADER, headerFileNames[i]);
- if (inc == nullptr) {
- buildLog_ += "Error while creating data from headers";
- return false;
- }
- inputs.push_back(inc);
- }
-
- // Set the include path for the temp folder that contains the includes
- if (!headers.empty()) {
- driverOptions.append(" -I");
- driverOptions.append(tempFolder);
- }
-
- if (options->isDumpFlagSet(amd::option::DUMP_CL)) {
- std::ofstream f(options->getDumpFileName(".cl").c_str(), std::ios::trunc);
- if (f.is_open()) {
- f << "/* Compiler options:\n"
- "-c -emit-llvm -target " STRING(AMDGCN_TRIPLE) " -x cl "
- << driverOptions << " -include opencl-c.h "
- << "\n*/\n\n"
- << sourceCode;
- } else {
- buildLog_ += "Warning: opening the file to dump the OpenCL source failed.\n";
- }
- }
-
- // FIXME_lmoriche: has the CL option been validated?
- uint clcStd =
- (options->oVariables->CLStd[2] - '0') * 100 + (options->oVariables->CLStd[4] - '0') * 10;
-
- std::pair hdr;
- switch (clcStd) {
- case 100:
- case 110:
- case 120:
- hdr = {opencl1_2_c_amdgcn, opencl1_2_c_amdgcn_size};
- break;
- case 200:
- hdr = {opencl2_0_c_amdgcn, opencl2_0_c_amdgcn_size};
- break;
- default:
- buildLog_ += "Unsupported requested OpenCL C version (-cl-std).\n";
- return false;
- }
-
- File* pch = C->NewTempFile(DT_CL_HEADER);
- if (pch == nullptr || !pch->WriteData((const char*)hdr.first, hdr.second)) {
- buildLog_ += "Error while opening the opencl-c header ";
- return false;
- }
-
- driverOptions.append(" -include-pch " + pch->Name());
- driverOptions.append(" -Xclang -fno-validate-pch");
-
- // Tokenize the options string into a vector of strings
- std::istringstream istrstr(driverOptions);
- std::istream_iterator sit(istrstr), end;
- std::vector params(sit, end);
-
- // Compile source to IR
- bool ret =
- dev().cacheCompilation()->compileToLLVMBitcode(C.get(), inputs, output, params, buildLog_);
- buildLog_ += C->Output();
- if (!ret) {
- buildLog_ += "Error: Failed to compile opencl source (from CL to LLVM IR).\n";
- return false;
- }
-
- llvmBinary_.assign(output->Buf().data(), output->Size());
- elfSectionType_ = amd::OclElf::LLVMIR;
-
- if (options->isDumpFlagSet(amd::option::DUMP_BC_ORIGINAL)) {
- std::ofstream f(options->getDumpFileName("_original.bc").c_str(), std::ios::trunc);
- if (f.is_open()) {
- f.write(llvmBinary_.data(), llvmBinary_.size());
- } else {
- buildLog_ += "Warning: opening the file to dump the compiled IR failed.\n";
- }
- }
-
- if (clBinary()->saveSOURCE()) {
- clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
- }
- if (clBinary()->saveLLVMIR()) {
- clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
- false);
- // store the original compile options
- clBinary()->storeCompileOptions(compileOptions_);
- }
- return true;
-}
-
-#if defined(ATI_OS_LINUX)
-static pthread_once_t once = PTHREAD_ONCE_INIT;
-
-static void checkLLVM_BIN() {
- if (llvmBin_.empty()) {
- Dl_info info;
- if (dladdr((const void*)&amd::Device::init, &info)) {
- char* str = strdup(info.dli_fname);
- if (str) {
- llvmBin_ = dirname(str);
- free(str);
- size_t pos = llvmBin_.rfind("lib");
- if (pos != std::string::npos) {
- llvmBin_.replace(pos, 3, "bin");
- }
- }
- }
- }
-#if defined(DEBUG)
- static const std::string tools[] = {"clang", "llvm-link", "ld.lld"};
-
- for (const std::string tool : tools) {
- std::string exePath(llvmBin_ + "/" + tool);
- struct stat buf;
- if (stat(exePath.c_str(), &buf)) {
- std::string msg(exePath + " not found");
- LogWarning(msg.c_str());
- } else if ((buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) {
- std::string msg("Cannot execute " + exePath);
- LogWarning(msg.c_str());
- }
- }
-#endif // defined(DEBUG)
-}
-#endif // defined(ATI_OS_LINUX)
-
-amd::opencl_driver::Compiler* LightningProgram::newCompilerInstance() {
-#if defined(ATI_OS_LINUX)
- pthread_once(&once, checkLLVM_BIN);
-#endif // defined(ATI_OS_LINUX)
- return amd::opencl_driver::CompilerFactory().CreateAMDGPUCompiler(llvmBin_);
-}
-#endif // defined(WITH_LIGHTNING_COMPILER)
-
-} // namespace roc
-#endif // WITHOUT_GPU_BACKEND
diff --git a/rocclr/runtime/device/rocm/rocdevice.hpp b/rocclr/runtime/device/rocm/rocdevice.hpp
index 7a2c811a93..7ce56222cf 100644
--- a/rocclr/runtime/device/rocm/rocdevice.hpp
+++ b/rocclr/runtime/device/rocm/rocdevice.hpp
@@ -176,10 +176,6 @@ class NullDevice : public amd::Device {
return false;
}
-#if defined(WITH_LIGHTNING_COMPILER)
- amd::CacheCompilation* cacheCompilation() const { return cacheCompilation_.get(); }
-#endif
-
protected:
//! Initialize compiler instance and handle
static bool initCompiler(bool isOffline);
@@ -189,10 +185,7 @@ class NullDevice : public amd::Device {
static Compiler* compilerHandle_;
//! Device Id for an HsaDevice
AMDDeviceInfo deviceInfo_;
-#if defined(WITH_LIGHTNING_COMPILER)
- //! Compilation with cache support
- std::unique_ptr cacheCompilation_;
-#endif
+
private:
static const bool offlineDevice_;
};
diff --git a/rocclr/runtime/device/rocm/rocprogram.cpp b/rocclr/runtime/device/rocm/rocprogram.cpp
index b36664a7f8..526b25ce52 100644
--- a/rocclr/runtime/device/rocm/rocprogram.cpp
+++ b/rocclr/runtime/device/rocm/rocprogram.cpp
@@ -265,6 +265,8 @@ aclType Program::getNextCompilationStageFromBinary(amd::option::Options* options
#if defined(WITH_COMPILER_LIB)
HSAILProgram::HSAILProgram(roc::NullDevice& device) : roc::Program(device) {
+ xnackEnabled_ = dev().deviceInfo().xnackEnabled_;
+ machineTarget_ = dev().deviceInfo().complibTarget_;
}
HSAILProgram::~HSAILProgram() {
@@ -715,7 +717,11 @@ bool HSAILProgram::linkImpl(amd::option::Options* options) {
#endif // defined(WITH_COMPILER_LIB)
#if defined(WITH_LIGHTNING_COMPILER)
-LightningProgram::LightningProgram(roc::NullDevice& device) : roc::Program(device) {
+LightningProgram::LightningProgram(roc::NullDevice& device)
+ : roc::Program(device) {
+ isLC_ = true;
+ xnackEnabled_ = dev().deviceInfo().xnackEnabled_;
+ machineTarget_ = dev().deviceInfo().machineTarget_;
metadata_ = nullptr;
}
diff --git a/rocclr/runtime/device/rocm/rocprogram.hpp b/rocclr/runtime/device/rocm/rocprogram.hpp
index 61b87659e5..182258c532 100644
--- a/rocclr/runtime/device/rocm/rocprogram.hpp
+++ b/rocclr/runtime/device/rocm/rocprogram.hpp
@@ -101,12 +101,6 @@ class HSAILProgram : public roc::Program {
virtual ~HSAILProgram();
protected:
- virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
- const std::vector& 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& inputPrograms,
@@ -134,12 +128,6 @@ public:
const CodeObjectMD* metadata() const { return metadata_; }
protected:
- virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
- const std::vector& 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& inputPrograms,
@@ -147,6 +135,8 @@ protected:
virtual bool createBinary(amd::option::Options* options) final;
+ bool saveBinaryAndSetType(type_t type) { return true; }
+
private:
bool saveBinaryAndSetType(type_t type, void* rawBinary, size_t size);
@@ -156,8 +146,6 @@ private:
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)