feature(zebin): add support for spill/private size in execution env

add fallback to previous logic based on zeinfo version

Related-To: NEO-9944
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski 2024-01-22 15:17:44 +00:00 committed by Compute-Runtime-Automation
parent c0686da2d6
commit dd7083d710
4 changed files with 114 additions and 37 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2023 Intel Corporation * Copyright (C) 2023-2024 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@ -65,6 +65,8 @@ inline constexpr ConstStringRef roundRobin("round_robin");
inline constexpr ConstStringRef roundRobinStall("round_robin_stall"); inline constexpr ConstStringRef roundRobinStall("round_robin_stall");
} // namespace ThreadSchedulingMode } // namespace ThreadSchedulingMode
inline constexpr ConstStringRef indirectStatelessCount("indirect_stateless_count"); inline constexpr ConstStringRef indirectStatelessCount("indirect_stateless_count");
inline constexpr ConstStringRef privateSize("private_size");
inline constexpr ConstStringRef spillSize("spill_size");
} // namespace ExecutionEnv } // namespace ExecutionEnv
namespace Attributes { namespace Attributes {
@ -342,6 +344,8 @@ using WorkgroupWalkOrderDimensionsT = int32_t[3];
using ThreadSchedulingModeT = ThreadSchedulingMode; using ThreadSchedulingModeT = ThreadSchedulingMode;
using IndirectStatelessCountT = int32_t; using IndirectStatelessCountT = int32_t;
using HasSampleT = bool; using HasSampleT = bool;
using PrivateSizeT = int32_t;
using SpillSizeT = int32_t;
namespace Defaults { namespace Defaults {
inline constexpr BarrierCountT barrierCount = 0; inline constexpr BarrierCountT barrierCount = 0;
@ -371,6 +375,8 @@ inline constexpr WorkgroupWalkOrderDimensionsT workgroupWalkOrderDimensions = {0
inline constexpr ThreadSchedulingModeT threadSchedulingMode = ThreadSchedulingModeUnknown; inline constexpr ThreadSchedulingModeT threadSchedulingMode = ThreadSchedulingModeUnknown;
inline constexpr IndirectStatelessCountT indirectStatelessCount = 0; inline constexpr IndirectStatelessCountT indirectStatelessCount = 0;
inline constexpr HasSampleT hasSample = false; inline constexpr HasSampleT hasSample = false;
inline constexpr PrivateSizeT privateSize = 0;
inline constexpr SpillSizeT spillSize = 0;
} // namespace Defaults } // namespace Defaults
inline constexpr ConstStringRef required[] = { inline constexpr ConstStringRef required[] = {
@ -404,6 +410,8 @@ struct ExecutionEnvBaseT {
ThreadSchedulingModeT threadSchedulingMode = Defaults::threadSchedulingMode; ThreadSchedulingModeT threadSchedulingMode = Defaults::threadSchedulingMode;
IndirectStatelessCountT indirectStatelessCount = Defaults::indirectStatelessCount; IndirectStatelessCountT indirectStatelessCount = Defaults::indirectStatelessCount;
HasSampleT hasSample = Defaults::hasSample; HasSampleT hasSample = Defaults::hasSample;
PrivateSizeT privateSize = Defaults::privateSize;
SpillSizeT spillSize = Defaults::spillSize;
}; };
struct ExperimentalPropertiesBaseT { struct ExperimentalPropertiesBaseT {

View File

@ -420,7 +420,8 @@ DecodeError decodeZeInfo(ProgramInfo &dst, ConstStringRef zeInfo, std::string &o
return DecodeError::invalidBinary; return DecodeError::invalidBinary;
} }
auto zeInfoDecodeError = decodeZeInfoVersion(yamlParser, zeInfoSections, outErrReason, outWarning); Types::Version zeInfoVersion{};
auto zeInfoDecodeError = decodeZeInfoVersion(yamlParser, zeInfoSections, outErrReason, outWarning, zeInfoVersion);
if (DecodeError::success != zeInfoDecodeError) { if (DecodeError::success != zeInfoDecodeError) {
return zeInfoDecodeError; return zeInfoDecodeError;
} }
@ -435,7 +436,7 @@ DecodeError decodeZeInfo(ProgramInfo &dst, ConstStringRef zeInfo, std::string &o
return zeInfoDecodeError; return zeInfoDecodeError;
} }
zeInfoDecodeError = decodeZeInfoKernels(dst, yamlParser, zeInfoSections, outErrReason, outWarning); zeInfoDecodeError = decodeZeInfoKernels(dst, yamlParser, zeInfoSections, outErrReason, outWarning, zeInfoVersion);
if (DecodeError::success != zeInfoDecodeError) { if (DecodeError::success != zeInfoDecodeError) {
return zeInfoDecodeError; return zeInfoDecodeError;
} }
@ -443,18 +444,18 @@ DecodeError decodeZeInfo(ProgramInfo &dst, ConstStringRef zeInfo, std::string &o
return DecodeError::success; return DecodeError::success;
} }
DecodeError decodeZeInfoVersion(Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning) { DecodeError decodeZeInfoVersion(Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning, Types::Version &srcZeInfoVersion) {
if (false == zeInfoSections.version.empty()) { if (false == zeInfoSections.version.empty()) {
Types::Version zeInfoVersion; auto err = readZeInfoVersionFromZeInfo(srcZeInfoVersion, parser, *zeInfoSections.version[0], outErrReason, outWarning);
auto err = readZeInfoVersionFromZeInfo(zeInfoVersion, parser, *zeInfoSections.version[0], outErrReason, outWarning);
if (DecodeError::success != err) { if (DecodeError::success != err) {
return err; return err;
} }
err = validateZeInfoVersion(zeInfoVersion, outErrReason, outWarning); err = validateZeInfoVersion(srcZeInfoVersion, outErrReason, outWarning);
if (DecodeError::success != err) { if (DecodeError::success != err) {
return err; return err;
} }
} else { } else {
srcZeInfoVersion = zeInfoDecoderVersion;
outWarning.append("DeviceBinaryFormat::zebin::.ze_info : No version info provided (i.e. no " + Tags::version.str() + " entry in global scope of DeviceBinaryFormat::zebin::.ze_info) - will use decoder's default : \'" + std::to_string(zeInfoDecoderVersion.major) + "." + std::to_string(zeInfoDecoderVersion.minor) + "\'\n"); outWarning.append("DeviceBinaryFormat::zebin::.ze_info : No version info provided (i.e. no " + Tags::version.str() + " entry in global scope of DeviceBinaryFormat::zebin::.ze_info) - will use decoder's default : \'" + std::to_string(zeInfoDecoderVersion.major) + "." + std::to_string(zeInfoDecoderVersion.minor) + "\'\n");
} }
return DecodeError::success; return DecodeError::success;
@ -487,11 +488,11 @@ DecodeError decodeZeInfoFunctions(ProgramInfo &dst, Yaml::YamlParser &parser, co
return DecodeError::success; return DecodeError::success;
} }
DecodeError decodeZeInfoKernels(ProgramInfo &dst, Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning) { DecodeError decodeZeInfoKernels(ProgramInfo &dst, Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion) {
UNRECOVERABLE_IF(zeInfoSections.kernels.size() != 1U); UNRECOVERABLE_IF(zeInfoSections.kernels.size() != 1U);
for (const auto &kernelNd : parser.createChildrenRange(*zeInfoSections.kernels[0])) { for (const auto &kernelNd : parser.createChildrenRange(*zeInfoSections.kernels[0])) {
auto kernelInfo = std::make_unique<KernelInfo>(); auto kernelInfo = std::make_unique<KernelInfo>();
auto zeInfoErr = decodeZeInfoKernelEntry(kernelInfo->kernelDescriptor, parser, kernelNd, dst.grfSize, dst.minScratchSpaceSize, outErrReason, outWarning); auto zeInfoErr = decodeZeInfoKernelEntry(kernelInfo->kernelDescriptor, parser, kernelNd, dst.grfSize, dst.minScratchSpaceSize, outErrReason, outWarning, srcZeInfoVersion);
if (DecodeError::success != zeInfoErr) { if (DecodeError::success != zeInfoErr) {
return zeInfoErr; return zeInfoErr;
} }
@ -504,7 +505,7 @@ DecodeError decodeZeInfoKernels(ProgramInfo &dst, Yaml::YamlParser &parser, cons
return DecodeError::success; return DecodeError::success;
} }
DecodeError decodeZeInfoKernelEntry(NEO::KernelDescriptor &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &kernelNd, uint32_t grfSize, uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning) { DecodeError decodeZeInfoKernelEntry(NEO::KernelDescriptor &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &kernelNd, uint32_t grfSize, uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion) {
ZeInfoKernelSections zeInfokernelSections; ZeInfoKernelSections zeInfokernelSections;
extractZeInfoKernelSections(yamlParser, kernelNd, zeInfokernelSections, ".ze_info", outWarning); extractZeInfoKernelSections(yamlParser, kernelNd, zeInfokernelSections, ".ze_info", outWarning);
auto extractError = validateZeInfoKernelSectionsCount(zeInfokernelSections, outErrReason, outWarning); auto extractError = validateZeInfoKernelSectionsCount(zeInfokernelSections, outErrReason, outWarning);
@ -515,7 +516,7 @@ DecodeError decodeZeInfoKernelEntry(NEO::KernelDescriptor &dst, NEO::Yaml::YamlP
dst.kernelAttributes.binaryFormat = DeviceBinaryFormat::zebin; dst.kernelAttributes.binaryFormat = DeviceBinaryFormat::zebin;
dst.kernelMetadata.kernelName = yamlParser.readValueNoQuotes(*zeInfokernelSections.nameNd[0]).str(); dst.kernelMetadata.kernelName = yamlParser.readValueNoQuotes(*zeInfokernelSections.nameNd[0]).str();
auto decodeError = decodeZeInfoKernelExecutionEnvironment(dst, yamlParser, zeInfokernelSections, outErrReason, outWarning); auto decodeError = decodeZeInfoKernelExecutionEnvironment(dst, yamlParser, zeInfokernelSections, outErrReason, outWarning, srcZeInfoVersion);
if (DecodeError::success != decodeError) { if (DecodeError::success != decodeError) {
return decodeError; return decodeError;
} }
@ -545,7 +546,7 @@ DecodeError decodeZeInfoKernelEntry(NEO::KernelDescriptor &dst, NEO::Yaml::YamlP
return decodeError; return decodeError;
} }
decodeError = decodeZeInfoKernelPerThreadMemoryBuffers(dst, yamlParser, zeInfokernelSections, minScratchSpaceSize, outErrReason, outWarning); decodeError = decodeZeInfoKernelPerThreadMemoryBuffers(dst, yamlParser, zeInfokernelSections, minScratchSpaceSize, outErrReason, outWarning, srcZeInfoVersion);
if (DecodeError::success != decodeError) { if (DecodeError::success != decodeError) {
return decodeError; return decodeError;
} }
@ -580,13 +581,13 @@ DecodeError decodeZeInfoKernelEntry(NEO::KernelDescriptor &dst, NEO::Yaml::YamlP
return DecodeError::success; return DecodeError::success;
} }
DecodeError decodeZeInfoKernelExecutionEnvironment(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning) { DecodeError decodeZeInfoKernelExecutionEnvironment(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion) {
KernelExecutionEnvBaseT execEnv; KernelExecutionEnvBaseT execEnv;
auto execEnvErr = readZeInfoExecutionEnvironment(parser, *kernelSections.executionEnvNd[0], execEnv, dst.kernelMetadata.kernelName, outErrReason, outWarning); auto execEnvErr = readZeInfoExecutionEnvironment(parser, *kernelSections.executionEnvNd[0], execEnv, dst.kernelMetadata.kernelName, outErrReason, outWarning);
if (DecodeError::success != execEnvErr) { if (DecodeError::success != execEnvErr) {
return execEnvErr; return execEnvErr;
} }
populateKernelExecutionEnvironment(dst, execEnv); populateKernelExecutionEnvironment(dst, execEnv, srcZeInfoVersion);
return DecodeError::success; return DecodeError::success;
} }
@ -647,6 +648,10 @@ DecodeError readZeInfoExecutionEnvironment(const Yaml::YamlParser &parser, const
validExecEnv &= readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.indirectStatelessCount, context, outErrReason); validExecEnv &= readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.indirectStatelessCount, context, outErrReason);
} else if (Tags::Kernel::ExecutionEnv::hasSample == key) { } else if (Tags::Kernel::ExecutionEnv::hasSample == key) {
validExecEnv &= readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.hasSample, context, outErrReason); validExecEnv &= readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.hasSample, context, outErrReason);
} else if (Tags::Kernel::ExecutionEnv::privateSize == key) {
validExecEnv &= readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.privateSize, context, outErrReason);
} else if (Tags::Kernel::ExecutionEnv::spillSize == key) {
validExecEnv &= readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.spillSize, context, outErrReason);
} else { } else {
outWarning.append("DeviceBinaryFormat::zebin::.ze_info : Unknown entry \"" + key.str() + "\" in context of " + context.str() + "\n"); outWarning.append("DeviceBinaryFormat::zebin::.ze_info : Unknown entry \"" + key.str() + "\" in context of " + context.str() + "\n");
} }
@ -664,7 +669,7 @@ DecodeError readZeInfoExecutionEnvironment(const Yaml::YamlParser &parser, const
return DecodeError::success; return DecodeError::success;
} }
void populateKernelExecutionEnvironment(KernelDescriptor &dst, const KernelExecutionEnvBaseT &execEnv) { void populateKernelExecutionEnvironment(KernelDescriptor &dst, const KernelExecutionEnvBaseT &execEnv, const Types::Version &srcZeInfoVersion) {
dst.entryPoints.skipPerThreadDataLoad = execEnv.offsetToSkipPerThreadDataLoad; dst.entryPoints.skipPerThreadDataLoad = execEnv.offsetToSkipPerThreadDataLoad;
dst.entryPoints.skipSetFFIDGP = execEnv.offsetToSkipSetFfidGp; dst.entryPoints.skipSetFFIDGP = execEnv.offsetToSkipSetFfidGp;
dst.kernelAttributes.flags.passInlineData = (execEnv.inlineDataPayloadSize != 0); dst.kernelAttributes.flags.passInlineData = (execEnv.inlineDataPayloadSize != 0);
@ -692,6 +697,10 @@ void populateKernelExecutionEnvironment(KernelDescriptor &dst, const KernelExecu
dst.kernelAttributes.workgroupWalkOrder[2] = static_cast<uint8_t>(execEnv.workgroupWalkOrderDimensions[2]); dst.kernelAttributes.workgroupWalkOrder[2] = static_cast<uint8_t>(execEnv.workgroupWalkOrderDimensions[2]);
dst.kernelAttributes.hasIndirectStatelessAccess = (execEnv.indirectStatelessCount > 0); dst.kernelAttributes.hasIndirectStatelessAccess = (execEnv.indirectStatelessCount > 0);
dst.kernelAttributes.numThreadsRequired = static_cast<uint32_t>(execEnv.euThreadCount); dst.kernelAttributes.numThreadsRequired = static_cast<uint32_t>(execEnv.euThreadCount);
if (isScratchMemoryUsageDefinedInExecutionEnvironment(srcZeInfoVersion)) {
dst.kernelAttributes.privateScratchMemorySize = static_cast<uint32_t>(execEnv.privateSize);
dst.kernelAttributes.spillFillScratchMemorySize = static_cast<uint32_t>(execEnv.spillSize);
}
using ThreadSchedulingMode = Types::Kernel::ExecutionEnv::ThreadSchedulingMode; using ThreadSchedulingMode = Types::Kernel::ExecutionEnv::ThreadSchedulingMode;
switch (execEnv.threadSchedulingMode) { switch (execEnv.threadSchedulingMode) {
@ -1471,7 +1480,7 @@ DecodeError populateKernelInlineSampler(KernelDescriptor &dst, const KernelInlin
return DecodeError::success; return DecodeError::success;
} }
DecodeError decodeZeInfoKernelPerThreadMemoryBuffers(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning) { DecodeError decodeZeInfoKernelPerThreadMemoryBuffers(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion) {
if (false == kernelSections.perThreadMemoryBuffersNd.empty()) { if (false == kernelSections.perThreadMemoryBuffersNd.empty()) {
KernelPerThreadMemoryBuffers perThreadMemoryBuffers{}; KernelPerThreadMemoryBuffers perThreadMemoryBuffers{};
auto perThreadMemoryBuffersErr = readZeInfoPerThreadMemoryBuffers(parser, *kernelSections.perThreadMemoryBuffersNd[0], perThreadMemoryBuffers, auto perThreadMemoryBuffersErr = readZeInfoPerThreadMemoryBuffers(parser, *kernelSections.perThreadMemoryBuffersNd[0], perThreadMemoryBuffers,
@ -1480,7 +1489,7 @@ DecodeError decodeZeInfoKernelPerThreadMemoryBuffers(KernelDescriptor &dst, Yaml
return perThreadMemoryBuffersErr; return perThreadMemoryBuffersErr;
} }
for (const auto &memBuff : perThreadMemoryBuffers) { for (const auto &memBuff : perThreadMemoryBuffers) {
auto decodeErr = populateKernelPerThreadMemoryBuffer(dst, memBuff, minScratchSpaceSize, outErrReason, outWarning); auto decodeErr = populateKernelPerThreadMemoryBuffer(dst, memBuff, minScratchSpaceSize, outErrReason, outWarning, srcZeInfoVersion);
if (DecodeError::success != decodeErr) { if (DecodeError::success != decodeErr) {
return decodeErr; return decodeErr;
} }
@ -1514,7 +1523,7 @@ DecodeError readZeInfoPerThreadMemoryBuffers(const Yaml::YamlParser &parser, con
return validBuffer ? DecodeError::success : DecodeError::invalidBinary; return validBuffer ? DecodeError::success : DecodeError::invalidBinary;
} }
DecodeError populateKernelPerThreadMemoryBuffer(KernelDescriptor &dst, const KernelPerThreadMemoryBufferBaseT &src, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning) { DecodeError populateKernelPerThreadMemoryBuffer(KernelDescriptor &dst, const KernelPerThreadMemoryBufferBaseT &src, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion) {
using namespace Types::Kernel::PerThreadMemoryBuffer; using namespace Types::Kernel::PerThreadMemoryBuffer;
using namespace Tags::Kernel::PerThreadMemoryBuffer::AllocationType; using namespace Tags::Kernel::PerThreadMemoryBuffer::AllocationType;
using namespace Tags::Kernel::PerThreadMemoryBuffer::MemoryUsage; using namespace Tags::Kernel::PerThreadMemoryBuffer::MemoryUsage;
@ -1540,15 +1549,18 @@ DecodeError populateKernelPerThreadMemoryBuffer(KernelDescriptor &dst, const Ker
dst.kernelAttributes.perHwThreadPrivateMemorySize = size; dst.kernelAttributes.perHwThreadPrivateMemorySize = size;
break; break;
case AllocationTypeScratch: case AllocationTypeScratch:
if (src.slot > 1) {
if (src.slot == 0) {
dst.kernelAttributes.spillFillScratchMemorySize = src.size;
} else if (src.slot == 1) {
dst.kernelAttributes.privateScratchMemorySize = src.size;
} else {
outErrReason.append("DeviceBinaryFormat::zebin : Invalid scratch buffer slot " + std::to_string(src.slot) + " in context of : " + dst.kernelMetadata.kernelName + ". Expected 0 or 1.\n"); outErrReason.append("DeviceBinaryFormat::zebin : Invalid scratch buffer slot " + std::to_string(src.slot) + " in context of : " + dst.kernelMetadata.kernelName + ". Expected 0 or 1.\n");
return DecodeError::invalidBinary; return DecodeError::invalidBinary;
} }
if (!isScratchMemoryUsageDefinedInExecutionEnvironment(srcZeInfoVersion)) {
if (src.slot == 0) {
dst.kernelAttributes.spillFillScratchMemorySize = src.size;
} else { // slot 1
dst.kernelAttributes.privateScratchMemorySize = src.size;
}
}
if (0 != dst.kernelAttributes.perThreadScratchSize[src.slot]) { if (0 != dst.kernelAttributes.perThreadScratchSize[src.slot]) {
outErrReason.append("DeviceBinaryFormat::zebin : Invalid duplicated scratch buffer entry " + std::to_string(src.slot) + " in context of : " + dst.kernelMetadata.kernelName + ".\n"); outErrReason.append("DeviceBinaryFormat::zebin : Invalid duplicated scratch buffer entry " + std::to_string(src.slot) + " in context of : " + dst.kernelMetadata.kernelName + ".\n");
return DecodeError::invalidBinary; return DecodeError::invalidBinary;

View File

@ -17,7 +17,7 @@ struct KernelInfo;
struct ProgramInfo; struct ProgramInfo;
namespace Zebin::ZeInfo { namespace Zebin::ZeInfo {
inline constexpr NEO::Zebin::ZeInfo::Types::Version zeInfoDecoderVersion{1, 38}; inline constexpr NEO::Zebin::ZeInfo::Types::Version zeInfoDecoderVersion{1, 39};
template <typename T> template <typename T>
bool readEnumChecked(ConstStringRef enumString, T &outValue, ConstStringRef kernelName, std::string &outErrReason); bool readEnumChecked(ConstStringRef enumString, T &outValue, ConstStringRef kernelName, std::string &outErrReason);
@ -63,7 +63,7 @@ DecodeError validateZeInfoVersion(const Types::Version &receivedZeInfoVersion, s
DecodeError populateExternalFunctionsMetadata(NEO::ProgramInfo &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &functionNd, std::string &outErrReason, std::string &outWarning); DecodeError populateExternalFunctionsMetadata(NEO::ProgramInfo &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &functionNd, std::string &outErrReason, std::string &outWarning);
DecodeError decodeZeInfoVersion(Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoVersion(Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning, Types::Version &srcZeInfoVersion);
DecodeError readZeInfoVersionFromZeInfo(Types::Version &dst, DecodeError readZeInfoVersionFromZeInfo(Types::Version &dst,
NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &versionNd, std::string &outErrReason, std::string &outWarning); NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &versionNd, std::string &outErrReason, std::string &outWarning);
@ -71,13 +71,13 @@ DecodeError decodeZeInfoGlobalHostAccessTable(ProgramInfo &dst, Yaml::YamlParser
DecodeError decodeZeInfoFunctions(ProgramInfo &dst, Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoFunctions(ProgramInfo &dst, Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning);
DecodeError decodeZeInfoKernels(ProgramInfo &dst, Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoKernels(ProgramInfo &dst, Yaml::YamlParser &parser, const ZeInfoSections &zeInfoSections, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion);
DecodeError decodeZeInfoKernelEntry(KernelDescriptor &dst, Yaml::YamlParser &yamlParser, const Yaml::Node &kernelNd, uint32_t grfSize, uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoKernelEntry(KernelDescriptor &dst, Yaml::YamlParser &yamlParser, const Yaml::Node &kernelNd, uint32_t grfSize, uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion);
using KernelExecutionEnvBaseT = Types::Kernel::ExecutionEnv::ExecutionEnvBaseT; using KernelExecutionEnvBaseT = Types::Kernel::ExecutionEnv::ExecutionEnvBaseT;
DecodeError decodeZeInfoKernelExecutionEnvironment(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoKernelExecutionEnvironment(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion);
DecodeError readZeInfoExecutionEnvironment(const Yaml::YamlParser &parser, const Yaml::Node &node, KernelExecutionEnvBaseT &outExecEnv, ConstStringRef context, std::string &outErrReason, std::string &outWarning); DecodeError readZeInfoExecutionEnvironment(const Yaml::YamlParser &parser, const Yaml::Node &node, KernelExecutionEnvBaseT &outExecEnv, ConstStringRef context, std::string &outErrReason, std::string &outWarning);
void populateKernelExecutionEnvironment(KernelDescriptor &dst, const KernelExecutionEnvBaseT &execEnv); void populateKernelExecutionEnvironment(KernelDescriptor &dst, const KernelExecutionEnvBaseT &execEnv, const Types::Version &srcZeInfoVersion);
using KernelAttributesBaseT = Types::Kernel::Attributes::AttributesBaseT; using KernelAttributesBaseT = Types::Kernel::Attributes::AttributesBaseT;
DecodeError decodeZeInfoKernelUserAttributes(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoKernelUserAttributes(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning);
@ -109,9 +109,9 @@ DecodeError populateKernelInlineSampler(KernelDescriptor &dst, const KernelInlin
using KernelPerThreadMemoryBufferBaseT = Types::Kernel::PerThreadMemoryBuffer::PerThreadMemoryBufferBaseT; using KernelPerThreadMemoryBufferBaseT = Types::Kernel::PerThreadMemoryBuffer::PerThreadMemoryBufferBaseT;
using KernelPerThreadMemoryBuffers = StackVec<KernelPerThreadMemoryBufferBaseT, 8>; using KernelPerThreadMemoryBuffers = StackVec<KernelPerThreadMemoryBufferBaseT, 8>;
DecodeError decodeZeInfoKernelPerThreadMemoryBuffers(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoKernelPerThreadMemoryBuffers(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion);
DecodeError readZeInfoPerThreadMemoryBuffers(const Yaml::YamlParser &parser, const Yaml::Node &node, KernelPerThreadMemoryBuffers &outPerThreadMemoryBuffers, ConstStringRef context, std::string &outErrReason, std::string &outWarning); DecodeError readZeInfoPerThreadMemoryBuffers(const Yaml::YamlParser &parser, const Yaml::Node &node, KernelPerThreadMemoryBuffers &outPerThreadMemoryBuffers, ConstStringRef context, std::string &outErrReason, std::string &outWarning);
DecodeError populateKernelPerThreadMemoryBuffer(KernelDescriptor &dst, const KernelPerThreadMemoryBufferBaseT &src, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning); DecodeError populateKernelPerThreadMemoryBuffer(KernelDescriptor &dst, const KernelPerThreadMemoryBufferBaseT &src, const uint32_t minScratchSpaceSize, std::string &outErrReason, std::string &outWarning, const Types::Version &srcZeInfoVersion);
using KernelExperimentalPropertiesBaseT = Types::Kernel::ExecutionEnv::ExperimentalPropertiesBaseT; using KernelExperimentalPropertiesBaseT = Types::Kernel::ExecutionEnv::ExperimentalPropertiesBaseT;
DecodeError decodeZeInfoKernelExperimentalProperties(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning); DecodeError decodeZeInfoKernelExperimentalProperties(KernelDescriptor &dst, Yaml::YamlParser &parser, const ZeInfoKernelSections &kernelSections, std::string &outErrReason, std::string &outWarning);
@ -130,6 +130,13 @@ void populateKernelMiscInfo(KernelDescriptor &dst, KernelMiscArgInfos &kernelMis
void generateSSHWithBindingTable(KernelDescriptor &dst); void generateSSHWithBindingTable(KernelDescriptor &dst);
void generateDSH(KernelDescriptor &dst); void generateDSH(KernelDescriptor &dst);
inline bool isAtLeastZeInfoVersion(const Types::Version &srcVersion, const Types::Version &expectedVersion) {
return srcVersion.minor >= expectedVersion.minor;
}
inline bool isScratchMemoryUsageDefinedInExecutionEnvironment(const Types::Version &srcVersion) { return isAtLeastZeInfoVersion(srcVersion, {1, 39}); }
} // namespace Zebin::ZeInfo } // namespace Zebin::ZeInfo
} // namespace NEO } // namespace NEO

View File

@ -38,6 +38,10 @@ class DecodeZeInfoKernelEntryFixture {
} }
DecodeError decodeZeInfoKernelEntry(ConstStringRef zeinfo) { DecodeError decodeZeInfoKernelEntry(ConstStringRef zeinfo) {
return decodeZeInfoKernelEntryForSpecificVersion(zeinfo, NEO::Zebin::ZeInfo::zeInfoDecoderVersion);
}
DecodeError decodeZeInfoKernelEntryForSpecificVersion(ConstStringRef zeinfo, const NEO::Zebin::ZeInfo::Types::Version &zeInfoVersion) {
kernelDescriptor = std::make_unique<KernelDescriptor>(); kernelDescriptor = std::make_unique<KernelDescriptor>();
yamlParser = std::make_unique<NEO::Yaml::YamlParser>(); yamlParser = std::make_unique<NEO::Yaml::YamlParser>();
errors.clear(); errors.clear();
@ -50,7 +54,7 @@ class DecodeZeInfoKernelEntryFixture {
auto &kernelNode = *yamlParser->createChildrenRange(*yamlParser->findNodeWithKeyDfs("kernels")).begin(); auto &kernelNode = *yamlParser->createChildrenRange(*yamlParser->findNodeWithKeyDfs("kernels")).begin();
return NEO::Zebin::ZeInfo::decodeZeInfoKernelEntry(*kernelDescriptor, *yamlParser, kernelNode, return NEO::Zebin::ZeInfo::decodeZeInfoKernelEntry(*kernelDescriptor, *yamlParser, kernelNode,
grfSize, minScratchSpaceSize, errors, warnings); grfSize, minScratchSpaceSize, errors, warnings, zeInfoVersion);
} }
protected: protected:
@ -66,6 +70,13 @@ class DecodeZeInfoKernelEntryFixture {
}; };
using namespace NEO::Zebin; using namespace NEO::Zebin;
TEST(ZeInfoVersionSupportTest, whenCheckingSupportedZeInfoVersionThenProperValueIsReturned) {
ZeInfo::Types::Version srcZeInfoVersion{3, 14};
EXPECT_TRUE(ZeInfo::isAtLeastZeInfoVersion(srcZeInfoVersion, {3, 14}));
EXPECT_FALSE(ZeInfo::isAtLeastZeInfoVersion(srcZeInfoVersion, {3, 15}));
EXPECT_TRUE(ZeInfo::isAtLeastZeInfoVersion(srcZeInfoVersion, {3, 13}));
}
TEST(ZebinValidateTargetTest, givenTargetDeviceCreatedUsingHelperFunctionWhenValidatingAgainstAdjustedHwInfoForIgcThenSuccessIsReturned) { TEST(ZebinValidateTargetTest, givenTargetDeviceCreatedUsingHelperFunctionWhenValidatingAgainstAdjustedHwInfoForIgcThenSuccessIsReturned) {
MockExecutionEnvironment executionEnvironment; MockExecutionEnvironment executionEnvironment;
auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0]; auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0];
@ -3588,6 +3599,8 @@ TEST_F(decodeZeInfoKernelEntryTest, GivenMinimalExecutionEnvThenPopulateKernelDe
EXPECT_EQ(kernelDescriptor.kernelAttributes.workgroupWalkOrder[0], static_cast<uint8_t>(Defaults::workgroupWalkOrderDimensions[0])); EXPECT_EQ(kernelDescriptor.kernelAttributes.workgroupWalkOrder[0], static_cast<uint8_t>(Defaults::workgroupWalkOrderDimensions[0]));
EXPECT_EQ(kernelDescriptor.kernelAttributes.workgroupWalkOrder[1], static_cast<uint8_t>(Defaults::workgroupWalkOrderDimensions[1])); EXPECT_EQ(kernelDescriptor.kernelAttributes.workgroupWalkOrder[1], static_cast<uint8_t>(Defaults::workgroupWalkOrderDimensions[1]));
EXPECT_EQ(kernelDescriptor.kernelAttributes.workgroupWalkOrder[2], static_cast<uint8_t>(Defaults::workgroupWalkOrderDimensions[2])); EXPECT_EQ(kernelDescriptor.kernelAttributes.workgroupWalkOrder[2], static_cast<uint8_t>(Defaults::workgroupWalkOrderDimensions[2]));
EXPECT_EQ(kernelDescriptor.kernelAttributes.privateScratchMemorySize, static_cast<uint32_t>(Defaults::privateSize));
EXPECT_EQ(kernelDescriptor.kernelAttributes.spillFillScratchMemorySize, static_cast<uint32_t>(Defaults::spillSize));
EXPECT_EQ(kernelDescriptor.kernelMetadata.requiredSubGroupSize, static_cast<uint8_t>(Defaults::requiredSubGroupSize)); EXPECT_EQ(kernelDescriptor.kernelMetadata.requiredSubGroupSize, static_cast<uint8_t>(Defaults::requiredSubGroupSize));
} }
@ -4039,6 +4052,7 @@ kernels:
- name : some_kernel - name : some_kernel
execution_env: execution_env:
simd_size: 8 simd_size: 8
spill_size: 2048
per_thread_memory_buffers: per_thread_memory_buffers:
- type: scratch - type: scratch
usage: spill_fill_space usage: spill_fill_space
@ -4060,6 +4074,7 @@ kernels:
- name : some_kernel - name : some_kernel
execution_env: execution_env:
simd_size: 8 simd_size: 8
private_size: 2048
per_thread_memory_buffers: per_thread_memory_buffers:
- type: scratch - type: scratch
usage: private_space usage: private_space
@ -4076,23 +4091,58 @@ kernels:
EXPECT_EQ(2048U, kernelDescriptor->kernelAttributes.privateScratchMemorySize); EXPECT_EQ(2048U, kernelDescriptor->kernelAttributes.privateScratchMemorySize);
} }
TEST_F(decodeZeInfoKernelEntryTest, GivenPerThreadMemoryBufferOfSizeSmallerThanMinimalWhenTypeIsScratchThenSetsProperFieldsInDescriptor) { TEST_F(decodeZeInfoKernelEntryTest, GivenPerThreadMemoryForSpillAndPrivateDefinedInSeparateFieldsThenProperFieldsInDescriptorAreSet) {
ConstStringRef zeinfo = R"===( ConstStringRef zeinfo = R"===(
kernels: kernels:
- name : some_kernel - name : some_kernel
execution_env: execution_env:
simd_size: 8 simd_size: 8
private_size: 256
spill_size: 512
per_thread_memory_buffers: per_thread_memory_buffers:
- type: scratch - type: scratch
usage: private_space usage: single_space
size: 512 size: 1024
- type: scratch
usage: single_space
size: 2048
slot: 1
)==="; )===";
auto err = decodeZeInfoKernelEntry(zeinfo); auto err = decodeZeInfoKernelEntry(zeinfo);
EXPECT_EQ(NEO::DecodeError::success, err); EXPECT_EQ(NEO::DecodeError::success, err);
EXPECT_TRUE(errors.empty()) << errors; EXPECT_TRUE(errors.empty()) << errors;
EXPECT_TRUE(warnings.empty()) << warnings; EXPECT_TRUE(warnings.empty()) << warnings;
EXPECT_EQ(1024U, kernelDescriptor->kernelAttributes.perThreadScratchSize[0]); EXPECT_EQ(1024U, kernelDescriptor->kernelAttributes.perThreadScratchSize[0]);
EXPECT_EQ(0U, kernelDescriptor->kernelAttributes.perThreadScratchSize[1]); EXPECT_EQ(2048U, kernelDescriptor->kernelAttributes.perThreadScratchSize[1]);
EXPECT_EQ(256U, kernelDescriptor->kernelAttributes.privateScratchMemorySize);
EXPECT_EQ(512U, kernelDescriptor->kernelAttributes.spillFillScratchMemorySize);
}
TEST_F(decodeZeInfoKernelEntryTest, GivenPerThreadMemoryForSpillAndPrivateDefinedInOlderZeInfoThenFallbackToLegacySlotMeaning) {
ConstStringRef zeinfo = R"===(
kernels:
- name : some_kernel
execution_env:
simd_size: 8
private_size: 256
spill_size: 512
per_thread_memory_buffers:
- type: scratch
usage: single_space
size: 1024
- type: scratch
usage: single_space
size: 2048
slot: 1
)===";
auto err = decodeZeInfoKernelEntryForSpecificVersion(zeinfo, {1, 38});
EXPECT_EQ(NEO::DecodeError::success, err);
EXPECT_TRUE(errors.empty()) << errors;
EXPECT_TRUE(warnings.empty()) << warnings;
EXPECT_EQ(1024U, kernelDescriptor->kernelAttributes.perThreadScratchSize[0]);
EXPECT_EQ(2048U, kernelDescriptor->kernelAttributes.perThreadScratchSize[1]);
EXPECT_EQ(2048U, kernelDescriptor->kernelAttributes.privateScratchMemorySize);
EXPECT_EQ(1024U, kernelDescriptor->kernelAttributes.spillFillScratchMemorySize);
} }
TEST_F(decodeZeInfoKernelEntryTest, GivenPerThreadMemoryBufferOfSizeBiggerThanMinimalWhenTypeIsScratchThenSetsProperFieldsInDescriptor) { TEST_F(decodeZeInfoKernelEntryTest, GivenPerThreadMemoryBufferOfSizeBiggerThanMinimalWhenTypeIsScratchThenSetsProperFieldsInDescriptor) {