diff --git a/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp b/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp index a79a17d149..1b6935420e 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp @@ -2259,61 +2259,120 @@ if_aclQueryInfo(aclCompiler *cl, if (!size) { return ACL_ERROR; } + bifbase *elfBin = reinterpret_cast(binary->bin); + if (!elfBin) { + return ACL_ELF_ERROR; + } const oclBIFSymbolStruct* sym = findBIF30SymStruct(symOpenclMeta); assert(sym && "symbol not found"); aclSections secID = sym->sections[0]; std::string pre = std::string(sym->str[PRE]); std::string post = std::string(sym->str[POST]); - if (RT_KERNEL_NAMES == query) { - bifbase *elfBin = reinterpret_cast(binary->bin); - if (!elfBin) { - return ACL_ELF_ERROR; - } - bifbase::SymbolVector symbols, kernels; - elfBin->getSectionSymbols(secID, symbols); - size_t totSize = 0; - if (!symbols.empty()) { - std::size_t beg = 0, begKernel = 0, end = 0, endKernel = 0, endSize = 0; - const oclBIFSymbolStruct* symKernel = findBIF30SymStruct(symOpenclKernel); - assert(symKernel && "symbol not found"); - std::string preKernel = std::string(symKernel->str[PRE]); - std::string postKernel = std::string(symKernel->str[POST]); - for (bifbase::SymbolVector::iterator it = symbols.begin(); it != symbols.end(); ++it) { - beg = (*it).find(pre); - if (std::string::npos == beg) continue; - beg += pre.size(); - begKernel = (*it).find(preKernel, beg); - if (std::string::npos != begKernel) { - beg = begKernel + preKernel.size(); - end = (*it).rfind(postKernel); - endSize = postKernel.size(); - } else { - end = (*it).rfind(post); + switch (query) { + default: + break; + case RT_CONTAINS_LLVMIR: + if (!ptr) { + *size = sizeof(bool); + return ACL_SUCCESS; + } else if (*size >= sizeof(bool)) { + bool contains = elfBin->isSection(aclLLVMIR); + memcpy(ptr, &contains, sizeof(bool)); + return ACL_SUCCESS; + } + return ACL_ERROR; + case RT_CONTAINS_OPTIONS: + if (!ptr) { + *size = sizeof(bool); + return ACL_SUCCESS; + } else if (*size >= sizeof(bool)) { + bool contains = elfBin->isSection(aclCOMMENT); + memcpy(ptr, &contains, sizeof(bool)); + return ACL_SUCCESS; + } + return ACL_ERROR; + case RT_CONTAINS_HSAIL: + if (!ptr) { + *size = sizeof(bool); + return ACL_SUCCESS; + } else if (*size >= sizeof(bool)) { + bool contains = elfBin->isSection(aclCODEGEN); + memcpy(ptr, &contains, sizeof(bool)); + return ACL_SUCCESS; + } + return ACL_ERROR; + case RT_CONTAINS_BRIG: + if (!ptr) { + *size = sizeof(bool); + return ACL_SUCCESS; + } else if (*size >= sizeof(bool)) { + bool contains = elfBin->isSection(aclBRIGcode) && + elfBin->isSection(aclBRIGoprs) && + elfBin->isSection(aclBRIGstrs); + memcpy(ptr, &contains, sizeof(bool)); + return ACL_SUCCESS; + } + return ACL_ERROR; + case RT_CONTAINS_ISA: + if (!ptr) { + *size = sizeof(bool); + return ACL_SUCCESS; + } else if (*size >= sizeof(bool)) { + bool contains = elfBin->isSection(aclTEXT); + memcpy(ptr, &contains, sizeof(bool)); + return ACL_SUCCESS; + } + return ACL_ERROR; + case RT_KERNEL_NAMES:{ + bifbase::SymbolVector symbols, kernels; + elfBin->getSectionSymbols(secID, symbols); + size_t totSize = 0; + if (!symbols.empty()) { + std::size_t beg = 0, begKernel = 0, end = 0, endKernel = 0, endSize = 0; + const oclBIFSymbolStruct* symKernel = findBIF30SymStruct(symOpenclKernel); + assert(symKernel && "symbol not found"); + std::string preKernel = std::string(symKernel->str[PRE]); + std::string postKernel = std::string(symKernel->str[POST]); + for (bifbase::SymbolVector::iterator it = symbols.begin(); it != symbols.end(); ++it) { + beg = (*it).find(pre); + if (std::string::npos == beg) continue; + beg += pre.size(); + begKernel = (*it).find(preKernel, beg); + if (std::string::npos != begKernel) { + beg = begKernel + preKernel.size(); + end = (*it).rfind(postKernel); + endSize = postKernel.size(); + } else { + end = (*it).rfind(post); + } + if (std::string::npos == end) continue; + endSize += post.size(); + if (end <= beg || end != (*it).size() - endSize) continue; + std::string kernel((*it).substr(beg, (*it).size() - beg - endSize) + " "); + totSize += kernel.size(); + kernels.push_back(kernel); } - if (std::string::npos == end) continue; - endSize += post.size(); - if (end <= beg || end != (*it).size() - endSize) continue; - std::string kernel((*it).substr(beg, (*it).size() - beg - endSize) + " "); - totSize += kernel.size(); - kernels.push_back(kernel); } - } - if (!ptr) { - *size = totSize > 0 ? totSize + 1 : 0; - return ACL_SUCCESS; - } else if (*size >= totSize && totSize > 0) { - char* tmp = reinterpret_cast(ptr); - for (bifbase::SymbolVector::iterator it = kernels.begin(); it != kernels.end(); ++it) { - memcpy(tmp, (*it).c_str(), (*it).size()); - tmp += (*it).size(); + if (!ptr) { + *size = totSize > 0 ? totSize + 1 : 0; + return ACL_SUCCESS; + } else if (*size >= totSize && totSize > 0) { + char* tmp = reinterpret_cast(ptr); + for (bifbase::SymbolVector::iterator it = kernels.begin(); it != kernels.end(); ++it) { + memcpy(tmp, (*it).c_str(), (*it).size()); + tmp += (*it).size(); + } + *(tmp++) = '\0'; + return ACL_SUCCESS; } - *(tmp++) = '\0'; - return ACL_SUCCESS; + return ACL_ERROR; } - return ACL_ERROR; } size_t roSize; acl_error error_code; + if (!kernel) { + return ACL_INVALID_ARG; + } std::string symbol = pre + std::string(kernel) + post; const void* roSec = cl->clAPI.extSym(cl, binary, &roSize, secID, symbol.c_str(), &error_code); if (error_code != ACL_SUCCESS) return error_code; diff --git a/projects/clr/rocclr/compiler/lib/include/v0_8/aclEnums.h b/projects/clr/rocclr/compiler/lib/include/v0_8/aclEnums.h index 451ff72126..993a038f8b 100644 --- a/projects/clr/rocclr/compiler/lib/include/v0_8/aclEnums.h +++ b/projects/clr/rocclr/compiler/lib/include/v0_8/aclEnums.h @@ -202,7 +202,12 @@ typedef enum _rt_query_types_enum_0_8 { RT_KERNEL_INDEX = 12, RT_KERNEL_NAME = 13, RT_KERNEL_NAMES = 14, - RT_LAST_TYPE = 15 + RT_CONTAINS_LLVMIR = 15, + RT_CONTAINS_OPTIONS = 16, + RT_CONTAINS_BRIG = 17, + RT_CONTAINS_HSAIL = 18, + RT_CONTAINS_ISA = 19, + RT_LAST_TYPE = 20 } aclQueryType_0_8; //! An enumeration for the various GPU capabilities diff --git a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp index 777e1a6ade..9769fafecc 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp @@ -1921,57 +1921,37 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector& completeStage completeStages.clear(); aclType from = ACL_TYPE_DEFAULT; needOptionsCheck = true; + size_t boolSize = sizeof(bool); //! @todo Should we also check for ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT? - // Checking llvmir in .llvmir section - bool isLlvmirText = true; - const void *llvmirText = aclExtractSection(dev().hsaCompiler(), - binaryElf_, &secSize, aclLLVMIR, &errorCode); + bool containsLlvmirText = true; + errorCode = aclQueryInfo(dev().hsaCompiler(), binaryElf_, RT_CONTAINS_LLVMIR, NULL, &containsLlvmirText, &boolSize); if (errorCode != ACL_SUCCESS) { - isLlvmirText = false; + containsLlvmirText = false; } // Checking compile & link options in .comment section - bool isOpts = true; - const void* opts = aclExtractSection(dev().hsaCompiler(), - binaryElf_, &secSize, aclCOMMENT, &errorCode); + bool containsOpts = true; + errorCode = aclQueryInfo(dev().hsaCompiler(), binaryElf_, RT_CONTAINS_OPTIONS, NULL, &containsOpts, &boolSize); if (errorCode != ACL_SUCCESS) { - isOpts = false; + containsOpts = false; } - if (isLlvmirText && isOpts) { + if (containsLlvmirText && containsOpts) { completeStages.push_back(from); from = ACL_TYPE_LLVMIR_BINARY; } - bool isHsailText = true; // Checking HSAIL in .cg section - const void *hsailText = aclExtractSection(dev().hsaCompiler(), - binaryElf_, &secSize, aclCODEGEN, &errorCode); + bool containsHsailText = true; + errorCode = aclQueryInfo(dev().hsaCompiler(), binaryElf_, RT_CONTAINS_HSAIL, NULL, &containsHsailText, &boolSize); if (errorCode != ACL_SUCCESS) { - isHsailText = false; + containsHsailText = false; } - // Checking BRIG STRTAB in .brig_strtab section - bool isBrigStrtab = true; - const void *brigStrtab = aclExtractSection(dev().hsaCompiler(), - binaryElf_, &secSize, aclBRIGstrs, &errorCode); + // Checking BRIG sections + bool containsBrig = true; + errorCode = aclQueryInfo(dev().hsaCompiler(), binaryElf_, RT_CONTAINS_BRIG, NULL, &containsBrig, &boolSize); if (errorCode != ACL_SUCCESS) { - isBrigStrtab = false; + containsBrig = false; } - // Checking BRIG CODE in .brig_code section - bool isBrigCode = true; - const void *brigCode = aclExtractSection(dev().hsaCompiler(), - binaryElf_, &secSize, aclBRIGcode, &errorCode); - if (errorCode != ACL_SUCCESS) { - isBrigCode = false; - } - // Checking BRIG OPERANDS in .brig_operands section - bool isBrigOps = true; - const void *brigOps = aclExtractSection(dev().hsaCompiler(), - binaryElf_, &secSize, aclBRIGoprs, &errorCode); - if (errorCode != ACL_SUCCESS) { - isBrigOps = false; - } - bool isBrig = false; - if (isBrigStrtab && isBrigCode && isBrigOps) { - isBrig = true; + if (containsBrig) { completeStages.push_back(from); from = ACL_TYPE_HSAIL_BINARY; // Here we should check that CG stage was done. @@ -1980,23 +1960,22 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector& completeStage // 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 only 2. - if (isHsailText) { + if (containsHsailText) { completeStages.push_back(from); from = ACL_TYPE_CG; } } - else if (isHsailText) { + else if (containsHsailText) { completeStages.push_back(from); from = ACL_TYPE_HSAIL_TEXT; } // Checking ISA in .text section - bool isShaderIsa = true; - const void *shaderIsa = aclExtractSection(dev().hsaCompiler(), - binaryElf_, &secSize, aclTEXT, &errorCode); + bool containsShaderIsa = true; + errorCode = aclQueryInfo(dev().hsaCompiler(), binaryElf_, RT_CONTAINS_ISA, NULL, &containsShaderIsa, &boolSize); if (errorCode != ACL_SUCCESS) { - isShaderIsa = false; + containsShaderIsa = false; } - if (isShaderIsa) { + if (containsShaderIsa) { completeStages.push_back(from); from = ACL_TYPE_ISA; } @@ -2010,25 +1989,23 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector& completeStage break; case ACL_TYPE_HSAIL_BINARY: case ACL_TYPE_CG: - // do not check options, if LLVMIR is absent or might be absent - if (curOptions.oVariables->BinLLVMIR || !isLlvmirText) { + // do not check options, if LLVMIR is absent or might be absent or options are absent + if (curOptions.oVariables->BinLLVMIR || !containsLlvmirText || !containsOpts) { needOptionsCheck = false; } break; case ACL_TYPE_ISA: - // do not check options, if LLVMIR is absent or might be absent - if (curOptions.oVariables->BinLLVMIR || !isLlvmirText) { + // do not check options, if LLVMIR is absent or might be absent or options are absent + if (curOptions.oVariables->BinLLVMIR || !containsLlvmirText || !containsOpts) { needOptionsCheck = false; } - if (isBrig && isHsailText) { - if (curOptions.oVariables->BinHSAIL) { - needOptionsCheck = false; - } + if (containsBrig && containsHsailText && curOptions.oVariables->BinHSAIL) { + needOptionsCheck = false; // recompile from prev. stage, if BRIG || HSAIL are absent } else { - from = completeStages.back(); - completeStages.pop_back(); - needOptionsCheck = true; + from = completeStages.back(); + completeStages.pop_back(); + needOptionsCheck = true; } break; // recompilation might be needed