From 942888ab4aaf11df7b40262f32abc8a2f642ea05 Mon Sep 17 00:00:00 2001 From: foreman Date: Tue, 16 Sep 2014 12:21:42 -0400 Subject: [PATCH] P4 to Git Change 1077370 by emankov@em-hsa-amd on 2014/09/16 12:02:36 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ECR #333753 - HSA RT: avoiding superfluous recompilations on ORCA RT/HSA path Next compilation stage determination based on binary sections and options (while linkImpl). If current HSAILProgram options are equal to binary’s ones: - Do not generate BRIG if BRIG sections are already presented in binary. - Do not finalize BRIG->ISA if ISA is already presented in binary. - Perform only CG phase if HSAIL is absent in binary. Always perform only brig loading (even in case of ISA presented). Testing: pre check-in, compile & basic ocl conformance 2.0 tests Reviewer: German Andryeyev Affected files ... ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucompiler.cpp#150 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.cpp#264 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.hpp#101 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#177 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.hpp#55 edit [ROCm/clr commit: ff7ab4a0b277cdf56394da99efc74539b755e93b] --- .../rocclr/runtime/device/gpu/gpucompiler.cpp | 1 + .../rocclr/runtime/device/gpu/gpukernel.cpp | 26 +-- .../rocclr/runtime/device/gpu/gpukernel.hpp | 5 +- .../rocclr/runtime/device/gpu/gpuprogram.cpp | 208 +++++++++++------- .../rocclr/runtime/device/gpu/gpuprogram.hpp | 10 +- 5 files changed, 151 insertions(+), 99 deletions(-) diff --git a/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp b/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp index 343876cc0b..1ce777de9c 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp @@ -435,6 +435,7 @@ HSAILProgram::compileImpl( return false; } + clBinary()->storeCompileOptions(compileOptions_); // Save the binary in the interface class size_t size = 0; void* mem = NULL; diff --git a/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp b/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp index 669371938b..7151082db9 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp @@ -3510,26 +3510,26 @@ HSAILKernel::~HSAILKernel() } bool -HSAILKernel::init() +HSAILKernel::init(bool finalize) { acl_error error; //compile kernel down to ISA std::string openClKernelName("&__OpenCL_" + name() + "_kernel"); - - std::string options(compileOptions_.c_str()); - options.append(" -just-kernel="); - options.append(openClKernelName.c_str()); + if (finalize) { + std::string options(compileOptions_.c_str()); + options.append(" -just-kernel="); + options.append(openClKernelName.c_str()); + error = aclCompile(dev().hsaCompiler(), prog().binaryElf(), + options.c_str(), ACL_TYPE_CG, ACL_TYPE_ISA, NULL); + buildLog_ += aclGetCompilerLog(dev().hsaCompiler()); + if (error != ACL_SUCCESS) { + LogError("Failed to finalize"); + return false; + } + } // Get the ISA out size_t size_isa; void* shader_isa = NULL; - error = aclCompile(dev().hsaCompiler(), prog().binaryElf(), - options.c_str(), ACL_TYPE_CG, ACL_TYPE_ISA, NULL); - buildLog_ += aclGetCompilerLog(dev().hsaCompiler()); - if (error != ACL_SUCCESS) { - LogError("Failed to finalize"); - return false; - } - shader_isa = const_cast(aclGetDeviceBinary(dev().hsaCompiler(), prog().binaryElf(), openClKernelName.c_str(), &size_isa, &error)); if (shader_isa == NULL) { diff --git a/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp b/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp index b2558bc3c7..5e5be612a9 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp @@ -835,8 +835,9 @@ public: virtual ~HSAILKernel(); - //! Initializes the metadata required for this kernel - bool init(); + //! Initializes the metadata required for this kernel, + //! finalizes the kernel if needed + bool init(bool finalize = true); //! Returns true if memory is valid for execution virtual bool validateMemory(uint idx, amd::Memory* amdMem) const; diff --git a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp index a2991b3c5c..a3ad5d2a0a 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp @@ -1913,14 +1913,13 @@ HSAILProgram::linkImpl( } aclType -HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_stages) +HSAILProgram::getCompilationStagesFromBinary(std::vector& complete_stages) { acl_error errorCode; size_t secSize = 0; complete_stages.clear(); aclType from = ACL_TYPE_DEFAULT; - //@TODO_HSA: r=emankov: Should we also check here for - // ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT? + //! @todo Should we also check for ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT? // Checking llvmir in .llvmir section bool isLlvmirText = true; @@ -1976,10 +1975,7 @@ HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_s // 1. matadata symbols symOpenclKernel for every kernel. // 2. HSAIL text in aclCODEGEN section. // Unfortunately there is no appropriate way in Compiler Lib to check 1. - // because kernel names are unknown here, therefore 2. - - //@TODO_HSA: r=emankov: Change the HSAIL section check, - // when the solution with kernel names appears in Compiler Lib. + // because kernel names are unknown here, therefore only 2. if (isHsailText) { complete_stages.push_back(from); from = ACL_TYPE_CG; @@ -1996,9 +1992,21 @@ HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_s if (errorCode != ACL_SUCCESS) { isShaderIsa = false; } - if (isShaderIsa && from == ACL_TYPE_LLVMIR_BINARY) { - complete_stages.clear(); - from = ACL_TYPE_DEFAULT; + if (isShaderIsa) { + switch (from) { + case ACL_TYPE_LLVMIR_BINARY: + complete_stages.clear(); + from = ACL_TYPE_DEFAULT; + break; + case ACL_TYPE_HSAIL_BINARY: + case ACL_TYPE_CG: + complete_stages.push_back(from); + from = ACL_TYPE_ISA; + break; + case ACL_TYPE_HSAIL_TEXT: + default: + break; + } } if (complete_stages.empty()) { complete_stages.push_back(from); @@ -2006,101 +2014,139 @@ HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_s return from; } +aclType +HSAILProgram::getNextCompilationStageFromBinary(amd::option::Options* options) { + aclType continueCompileFrom = ACL_TYPE_DEFAULT; + binary_t binary = this->binary(); + // If the binary already exists + if ((binary.first != NULL) && (binary.second > 0)) { + void *mem = const_cast(binary.first); + acl_error errorCode; + binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode); + if (errorCode != ACL_SUCCESS) { + buildLog_ += "Error while BRIG Codegen phase: aclReadFromMem failure \n" ; + LogWarning("aclReadFromMem failed"); + return continueCompileFrom; + } + // Calculate the next stage to compile from, based on sections in binaryElf_; + // No any validity checks here + std::vector complete_stages; + continueCompileFrom = getCompilationStagesFromBinary(complete_stages); + // Saving binary in the interface class, + // which also load compile & link options from binary + setBinary(static_cast(mem), binary.second); + if (!options) { + return continueCompileFrom; + } + bool recompile = false; + //! @todo Should we also check for ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT? + switch (continueCompileFrom) { + case ACL_TYPE_HSAIL_BINARY: + case ACL_TYPE_CG: + case ACL_TYPE_ISA: { + // Compare options loaded from binary with current ones, recompile if differ; + // If compile options are absent in binary, do not compare and recompile + if (compileOptions_.empty()) + break; + const oclBIFSymbolStruct* symbol = findBIF30SymStruct(symOpenclCompilerOptions); + assert(symbol && "symbol not found"); + std::string symName = std::string(symbol->str[PRE]) + std::string(symbol->str[POST]); + size_t symSize = 0; + const void *opts = aclExtractSymbol(dev().hsaCompiler(), + binaryElf_, &symSize, aclCOMMENT, symName.c_str(), &errorCode); + if (errorCode != ACL_SUCCESS) { + recompile = true; + break; + } + std::string sBinOptions = std::string((char*)opts, symSize); + std::string sCurOptions = compileOptions_ + linkOptions_; + amd::option::Options curOptions, binOptions; + amd::option::parseAllOptions(sBinOptions, binOptions); + amd::option::parseAllOptions(sCurOptions, curOptions); + if (!curOptions.equals(binOptions)) { + recompile = true; + } + break; + } + default: + break; + } + if (recompile) { + while (!complete_stages.empty()) { + continueCompileFrom = complete_stages.back(); + if (continueCompileFrom == ACL_TYPE_LLVMIR_BINARY || + continueCompileFrom == ACL_TYPE_DEFAULT) { + break; + } + complete_stages.pop_back(); + } + } + } + return continueCompileFrom; +} + bool HSAILProgram::linkImpl(amd::option::Options* options) { acl_error errorCode; aclType continueCompileFrom = ACL_TYPE_LLVMIR_BINARY; + bool finalize = true; // If !binaryElf_ then program must have been created using clCreateProgramWithBinary if (!binaryElf_) { - binary_t binary = this->binary(); - // If the binary already exists - if ((binary.first != NULL) && (binary.second > 0)) { - void *mem = const_cast(binary.first); - binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode); - if (errorCode != ACL_SUCCESS) { - buildLog_ += "Error while BRIG Codegen phase: aclReadFromMem failure \n" ; - LogWarning("aclReadFromMem failed"); - return false; - } - // Calculate the next stage to compile from, based on sections in binaryElf_; - // No any validity checks here - std::vector complete_stages; - continueCompileFrom = getNextCompilationStageFromBinary(complete_stages); - //@TODO_HSA: r=emankov: Should we also check here for - // ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT to recompile from? - if (ACL_TYPE_DEFAULT == continueCompileFrom) { - buildLog_ += "Error while BRIG Codegen phase: the binary is incomplete \n" ; - return false; - } - if (ACL_TYPE_HSAIL_BINARY == continueCompileFrom) { - // Saving binary in the interface class, - // which also load compile & link options from binary - setBinary(static_cast(mem), binary.second); - // Check the previous completed stage - if (ACL_TYPE_LLVMIR_BINARY == complete_stages.back()) { - // Compare options loaded from binary with current ones - // If they differ then recompile from ACL_TYPE_LLVMIR_BINARY - //@TODO_HSA: r=emankov: Should we need to check options at all? - std::string curOptions = options->origOptionStr + hsailOptions(); - if (compileOptions_ + linkOptions_ != curOptions) { - continueCompileFrom = ACL_TYPE_LLVMIR_BINARY; - } - } - } - } + continueCompileFrom = getNextCompilationStageFromBinary(options); } switch (continueCompileFrom) { - default: + // Compilation from ACL_TYPE_LLVMIR_BINARY to ACL_TYPE_CG in cases: + // 1. if the program is not created with binary; + // 2. if the program is created with binary and contains only .llvmir & .comment + // 3. if the program is created with binary, contains .llvmir, .comment, brig sections, + // but the binary's compile & link options differ from current ones (recompilation); + case ACL_TYPE_LLVMIR_BINARY: + // Compilation from ACL_TYPE_HSAIL_BINARY to ACL_TYPE_CG in cases: + // 1. if the program is created with binary and contains only brig sections + case ACL_TYPE_HSAIL_BINARY: + // Compilation from ACL_TYPE_HSAIL_TEXT to ACL_TYPE_CG in cases: + // 1. if the program is created with binary and contains only hsail text + case ACL_TYPE_HSAIL_TEXT: { + std::string curOptions = options->origOptionStr + hsailOptions(); + errorCode = aclCompile(dev().hsaCompiler(), binaryElf_, + curOptions.c_str(), continueCompileFrom, ACL_TYPE_CG, NULL); + buildLog_ += aclGetCompilerLog(dev().hsaCompiler()); + if (errorCode != ACL_SUCCESS) { + buildLog_ += "Error while BRIG Codegen phase: compilation error \n" ; + return false; + } break; - // Compilation from ACL_TYPE_LLVMIR_BINARY to ACL_TYPE_CG in cases: - // 1. if the program is not created with binary; - // 2. if the program is created with binary and contains only .llvmir & .comment - // 3. if the program is created with binary, contains .llvmir, .comment, brig sections, - // but the binary's compile & link options differ from current ones (recompilation); - case ACL_TYPE_LLVMIR_BINARY: - // Compilation from ACL_TYPE_HSAIL_BINARY to ACL_TYPE_CG in cases: - // 1. if the program is created with binary and contains only brig sections - case ACL_TYPE_HSAIL_BINARY: - // Compilation from ACL_TYPE_HSAIL_TEXT to ACL_TYPE_CG in cases: - // 1. if the program is created with binary and contains only hsail text - case ACL_TYPE_HSAIL_TEXT: - { - std::string curOptions = options->origOptionStr + hsailOptions(); - errorCode = aclCompile(dev().hsaCompiler(), binaryElf_, - curOptions.c_str(), continueCompileFrom, ACL_TYPE_CG, NULL); - buildLog_ += aclGetCompilerLog(dev().hsaCompiler()); - break; - } } - if (errorCode != ACL_SUCCESS) { - buildLog_ += "Error while BRIG Codegen phase: compilation error \n" ; + case ACL_TYPE_CG: + break; + case ACL_TYPE_ISA: + finalize = false; + break; + default: + buildLog_ += "Error while BRIG Codegen phase: the binary is incomplete \n" ; return false; } - + // ACL_TYPE_CG stage is always being performed if (!aclHsaLoader(dev().hsaCompiler(), binaryElf_, this, &AllocateGPUMemory, &DmaMemoryCopy, &GetSamplerObjectParams, &InitializeSamplerObject)) { buildLog_ += "Error while BRIG Codegen phase: loading BRIG globals in the ELF \n"; return false; } // We need to pull out kernels' names for finalizing kernels - //@TODO_HSA: r=emankov: rewrite the below code, - // if another way to obtain kernel names appears in the compiler library - size_t fsailSize; + //! @todo Rewrite the below code, if another way to obtain kernel names + //! appears in the compiler library + size_t hsailSize = 0; const oclBIFSymbolStruct* symbol = findBIF30SymStruct(symHSAILText); assert(symbol && "symbol not found"); std::string symName = symbol->str[PRE] + std::string("main") + symbol->str[POST]; - const void *hsailText = aclExtractSymbol(dev().hsaCompiler(), - binaryElf_, - &fsailSize, - aclCODEGEN, - symName.c_str(), - &errorCode); + const void *hsailText = aclExtractSymbol(dev().hsaCompiler(), binaryElf_, + &hsailSize, aclCODEGEN, symName.c_str(), &errorCode); if (errorCode != ACL_SUCCESS) { buildLog_ += "Error while reading out the HSAIL from the ELF \n" ; return false; } - std::string hsailProgram((char *)hsailText); + std::string hsailProgram((char *)hsailText, hsailSize); HSAILProgram_ = hsailProgram; if (!HSAILProgram_.empty()) { bool dynamicParallelism = false; @@ -2126,7 +2172,7 @@ HSAILProgram::linkImpl(amd::option::Options* options) (kernelNPos + 8 + 9) - 6); HSAILKernel *aKernel = new HSAILKernel(kernelName, this, options->origOptionStr + hsailOptions()); - if (!aKernel->init() ) { + if (!aKernel->init(finalize)) { return false; } buildLog_ += aKernel->buildLog(); @@ -2162,7 +2208,7 @@ HSAILProgram::linkImpl(amd::option::Options* options) bool HSAILProgram::createBinary(amd::option::Options *options) { - return false; + return true; } bool diff --git a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp index 17b9850546..dff3917783 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp @@ -423,10 +423,14 @@ protected: amd::option::Options* options //!< compile options's object ); - /* \brief Return the next stage to compile from, based on sections in binary, - * also return completed stages in vector, which contains at least ACL_TYPE_DEFAULT + /* \brief Returns the next stage to compile from, based on sections in binary, + * also returns completed stages in vector, which contains at least ACL_TYPE_DEFAULT */ - aclType getNextCompilationStageFromBinary(std::vector& complete_stages); + aclType getCompilationStagesFromBinary(std::vector& complete_stages); + + /* \brief Returns the next stage to compile from, based on sections and options in binary + */ + aclType getNextCompilationStageFromBinary(amd::option::Options* options); /*! \brief Compiles LLVM binary to FSAIL code (compiler backend: link+opt+codegen) *