P4 to Git Change 1084465 by emankov@em-hsa-amd on 2014/10/06 10:30:04
ECR #333753 - Compiler Lib/RT/Performance: Replace aclExtractSymbol/Section with aclQueryInfo for symbol/section detection.
The replaced calls in RT previously performed actual extraction of the sections from the BIF with memory allocation and copying. But what is needed in fact is only to determine whether the section exists in BIF or not to make a further decision on needed recompilations. With aclQueryInfo and new added enums RT_CONTAINS_LLVMIR, RT_CONTAINS_OPTIONS, RT_CONTAINS_BRIG, RT_CONTAINS_HSAIL, RT_CONTAINS_ISA Runtime starts querying not the whole sections but the bool flag which indicates the existance of the corresponding section(s) without any memory allocations. Every compilation on RT starting from LLVMIR is affected by the change including compilation of blit kernels.
Side Effects: performance improvement, memory consumption reduction
Testing: pre check-in, ocl conformance (api, basic, compiler), ocltst complib
Reviewers: Brian Sumner, German Andryeyev, Artem Tamazov
Affected files ...
... //depot/stg/opencl/drivers/opencl/compiler/lib/api/v0_8/acl.cpp#21 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/v0_8/if_acl.cpp#52 edit
... //depot/stg/opencl/drivers/opencl/compiler/lib/include/v0_8/aclEnums.h#14 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#180 edit
... //depot/stg/opencl/drivers/opencl/tests/ocltst/module/complib/CLEnumCheck.cpp#38 edit
[ROCm/clr commit: 936e8f603d]
Цей коміт міститься в:
@@ -2259,61 +2259,120 @@ if_aclQueryInfo(aclCompiler *cl,
|
||||
if (!size) {
|
||||
return ACL_ERROR;
|
||||
}
|
||||
bifbase *elfBin = reinterpret_cast<bifbase*>(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<bifbase*>(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<char*>(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<char*>(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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1921,57 +1921,37 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector<aclType>& 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<aclType>& 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<aclType>& 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
|
||||
|
||||
Посилання в новій задачі
Заблокувати користувача