Zebin: set kernel barriers based on ext funcs

This change allows for modifying kernel's barrier count
based on called external functions metadata passed
via zeInfo section in zebin.

Added parsing external functions metadata.
Added resolving external functions call graph.
Added updating kernel barriers based on called external functions.
Added support for L0 dynamic link.

Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
Krystian Chmielewski
2022-02-28 17:44:06 +00:00
committed by Compute-Runtime-Automation
parent bae9e6f5b5
commit 0ccce5a6d7
24 changed files with 1143 additions and 98 deletions

View File

@@ -55,6 +55,7 @@ static constexpr ConstStringRef zeInfo = ".ze_info";
static constexpr ConstStringRef gtpinInfo = ".gtpin_info";
static constexpr ConstStringRef noteIntelGT = ".note.intelgt.compat";
static constexpr ConstStringRef vIsaAsmPrefix = ".visaasm.";
static constexpr ConstStringRef externalFunctions = "Intel_Symbol_Table_Void_Program";
} // namespace SectionsNamesZebin
static constexpr ConstStringRef IntelGtNoteOwnerName = "IntelGT";
@@ -158,6 +159,8 @@ namespace Tags {
static constexpr ConstStringRef kernels("kernels");
static constexpr ConstStringRef version("version");
static constexpr ConstStringRef globalHostAccessTable("global_host_access_table");
static constexpr ConstStringRef functions("functions");
namespace Kernel {
static constexpr ConstStringRef name("name");
static constexpr ConstStringRef executionEnv("execution_env");
@@ -279,10 +282,18 @@ static constexpr ConstStringRef hasNonKernelArgStore("has_non_kernel_arg_store")
static constexpr ConstStringRef hasNonKernelArgAtomic("has_non_kernel_arg_atomic");
} // namespace ExperimentalProperties
} // namespace Kernel
namespace GlobalHostAccessTable {
static constexpr ConstStringRef deviceName("device_name");
static constexpr ConstStringRef hostName("host_name");
} // namespace GlobalHostAccessTable
namespace Function {
static constexpr ConstStringRef name("name");
static constexpr ConstStringRef executionEnv("execution_env");
using namespace Kernel::ExecutionEnv;
} // namespace Function
} // namespace Tags
namespace Types {
@@ -540,6 +551,12 @@ struct globalHostAccessTableT {
std::string hostName;
};
} // namespace GlobalHostAccessTable
namespace Function {
namespace ExecutionEnv {
using namespace Kernel::ExecutionEnv;
}
} // namespace Function
} // namespace Types
} // namespace ZebinKernelMetadata

View File

@@ -1238,6 +1238,38 @@ NEO::DecodeError populateZeInfoVersion(NEO::Elf::ZebinKernelMetadata::Types::Ver
return NEO::DecodeError::Success;
}
NEO::DecodeError populateExternalFunctionsMetadata(NEO::ProgramInfo &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &functionNd, std::string &outErrReason, std::string &outWarning) {
ConstStringRef functionName;
NEO::Elf::ZebinKernelMetadata::Types::Function::ExecutionEnv::ExecutionEnvBaseT execEnv = {};
bool isValid = true;
for (const auto &functionMetadataNd : yamlParser.createChildrenRange(functionNd)) {
auto key = yamlParser.readKey(functionMetadataNd);
if (NEO::Elf::ZebinKernelMetadata::Tags::Function::name == key) {
functionName = yamlParser.readValueNoQuotes(functionMetadataNd);
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Function::executionEnv == key) {
auto execEnvErr = readZeInfoExecutionEnvironment(yamlParser, functionMetadataNd, execEnv, "external functions", outErrReason, outWarning);
if (execEnvErr != DecodeError::Success) {
isValid = false;
}
} else {
outWarning.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unknown entry \"" + yamlParser.readKey(functionMetadataNd).str() + "\" in context of : external functions\n");
}
}
if (isValid) {
NEO::ExternalFunctionInfo extFunInfo;
extFunInfo.functionName = functionName.str();
extFunInfo.barrierCount = static_cast<uint8_t>(execEnv.barrierCount);
extFunInfo.numGrfRequired = static_cast<uint16_t>(execEnv.grfCount);
extFunInfo.simdSize = static_cast<uint8_t>(execEnv.simdSize);
dst.externalFunctions.push_back(extFunInfo);
return DecodeError::Success;
} else {
return DecodeError::InvalidBinary;
}
}
template <>
DecodeError decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ProgramInfo &dst, const SingleDeviceBinary &src, std::string &outErrReason, std::string &outWarning) {
auto elf = Elf::decodeElf<Elf::EI_CLASS_64>(src.deviceBinary, outErrReason, outWarning);
@@ -1299,17 +1331,17 @@ DecodeError decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ProgramInfo
UniqueNode kernelsSectionNodes;
UniqueNode versionSectionNodes;
UniqueNode globalHostAccessTableNodes;
UniqueNode functionsSectionNodes;
for (const auto &globalScopeNd : yamlParser.createChildrenRange(*yamlParser.getRoot())) {
auto key = yamlParser.readKey(globalScopeNd);
if (NEO::Elf::ZebinKernelMetadata::Tags::kernels == key) {
kernelsSectionNodes.push_back(&globalScopeNd);
continue;
} else if (NEO::Elf::ZebinKernelMetadata::Tags::version == key) {
versionSectionNodes.push_back(&globalScopeNd);
continue;
} else if (NEO::Elf::ZebinKernelMetadata::Tags::globalHostAccessTable == key) {
globalHostAccessTableNodes.push_back(&globalScopeNd);
continue;
} else if (NEO::Elf::ZebinKernelMetadata::Tags::functions == key) {
functionsSectionNodes.push_back(&globalScopeNd);
} else {
outWarning.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unknown entry \"" + yamlParser.readKey(globalScopeNd).str() + "\" in global scope of " + NEO::Elf::SectionsNamesZebin::zeInfo.str() + "\n");
}
@@ -1368,6 +1400,20 @@ DecodeError decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ProgramInfo
}
}
if (functionsSectionNodes.size() > 1U) {
outErrReason.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Expected at most one " + NEO::Elf::ZebinKernelMetadata::Tags::functions.str() + " entry in global scope of " + NEO::Elf::SectionsNamesZebin::zeInfo.str() + ", got : " + std::to_string(functionsSectionNodes.size()) + "\n");
return DecodeError::InvalidBinary;
}
if (false == functionsSectionNodes.empty()) {
for (const auto &functionNd : yamlParser.createChildrenRange(*functionsSectionNodes[0])) {
auto zeInfoErr = populateExternalFunctionsMetadata(dst, yamlParser, functionNd, outErrReason, outWarning);
if (DecodeError::Success != zeInfoErr) {
return zeInfoErr;
}
}
}
return DecodeError::Success;
}

View File

@@ -117,4 +117,6 @@ NEO::DecodeError populateKernelDescriptor(NEO::ProgramInfo &dst, NEO::Elf::Elf<N
NEO::DecodeError populateZeInfoVersion(NEO::Elf::ZebinKernelMetadata::Types::Version &dst,
NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &versionNd, std::string &outErrReason, std::string &outWarning);
NEO::DecodeError populateExternalFunctionsMetadata(NEO::ProgramInfo &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &functionNd, std::string &outErrReason, std::string &outWarning);
} // namespace NEO