Decode collection attributes in exec env

Add support for decoding required work group size and work gorup walk
order dimensions in zebin.

Related-To: NEO-6088
Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
Krystian Chmielewski
2021-07-26 12:09:15 +00:00
committed by Compute-Runtime-Automation
parent 7c6c45f5b5
commit 7dea397f22
2 changed files with 81 additions and 0 deletions

View File

@@ -216,6 +216,23 @@ bool readZeInfoValueChecked(const NEO::Yaml::YamlParser &parser, const NEO::Yaml
return false;
}
template <typename DestinationT, size_t Len>
bool readZeInfoValueCollectionChecked(DestinationT (&vec)[Len], const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node, ConstStringRef context, std::string &outErrReason) {
auto collectionNodes = parser.createChildrenRange(node);
size_t index = 0U;
bool isValid = true;
for (const auto &elementNd : collectionNodes) {
isValid &= readZeInfoValueChecked(parser, elementNd, vec[index++], context, outErrReason);
}
if (index != Len) {
outErrReason.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : wrong size of collection " + parser.readKey(node).str() + " in context of : " + context.str() + ". Got : " + std::to_string(index) + " expected : " + std::to_string(Len) + "\n");
isValid = false;
}
return isValid;
}
DecodeError readZeInfoExecutionEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
NEO::Elf::ZebinKernelMetadata::Types::Kernel::ExecutionEnv::ExecutionEnvBaseT &outExecEnv,
ConstStringRef context,
@@ -251,12 +268,16 @@ DecodeError readZeInfoExecutionEnvironment(const NEO::Yaml::YamlParser &parser,
validExecEnv = validExecEnv & readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.offsetToSkipSetFfidGp, context, outErrReason);
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::ExecutionEnv::requiredSubGroupSize == key) {
validExecEnv = validExecEnv & readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.requiredSubGroupSize, context, outErrReason);
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::ExecutionEnv::requiredWorkGroupSize == key) {
validExecEnv = validExecEnv & readZeInfoValueCollectionChecked(outExecEnv.requiredWorkGroupSize, parser, execEnvMetadataNd, context, outErrReason);
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::ExecutionEnv::simdSize == key) {
validExecEnv = validExecEnv & readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.simdSize, context, outErrReason);
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::ExecutionEnv::slmSize == key) {
validExecEnv = validExecEnv & readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.slmSize, context, outErrReason);
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::ExecutionEnv::subgroupIndependentForwardProgress == key) {
validExecEnv = validExecEnv & readZeInfoValueChecked(parser, execEnvMetadataNd, outExecEnv.subgroupIndependentForwardProgress, context, outErrReason);
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::ExecutionEnv::workGroupWalkOrderDimensions == key) {
validExecEnv = validExecEnv & readZeInfoValueCollectionChecked(outExecEnv.workgroupWalkOrderDimensions, parser, execEnvMetadataNd, context, outErrReason);
} else {
outWarning.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unknown entry \"" + key.str() + "\" in context of " + context.str() + "\n");
}
@@ -965,6 +986,12 @@ NEO::DecodeError populateKernelDescriptor(NEO::ProgramInfo &dst, NEO::Elf::Elf<N
kernelDescriptor.kernelAttributes.simdSize = execEnv.simdSize;
kernelDescriptor.kernelAttributes.slmInlineSize = execEnv.slmSize;
kernelDescriptor.kernelAttributes.flags.requiresSubgroupIndependentForwardProgress = execEnv.subgroupIndependentForwardProgress;
kernelDescriptor.kernelAttributes.requiredWorkgroupSize[0] = static_cast<uint16_t>(execEnv.requiredWorkGroupSize[0]);
kernelDescriptor.kernelAttributes.requiredWorkgroupSize[1] = static_cast<uint16_t>(execEnv.requiredWorkGroupSize[1]);
kernelDescriptor.kernelAttributes.requiredWorkgroupSize[2] = static_cast<uint16_t>(execEnv.requiredWorkGroupSize[2]);
kernelDescriptor.kernelAttributes.workgroupWalkOrder[0] = static_cast<uint8_t>(execEnv.workgroupWalkOrderDimensions[0]);
kernelDescriptor.kernelAttributes.workgroupWalkOrder[1] = static_cast<uint8_t>(execEnv.workgroupWalkOrderDimensions[1]);
kernelDescriptor.kernelAttributes.workgroupWalkOrder[2] = static_cast<uint8_t>(execEnv.workgroupWalkOrderDimensions[2]);
if ((kernelDescriptor.kernelAttributes.simdSize != 1) && (kernelDescriptor.kernelAttributes.simdSize != 8) && (kernelDescriptor.kernelAttributes.simdSize != 16) && (kernelDescriptor.kernelAttributes.simdSize != 32)) {
outErrReason.append("DeviceBinaryFormat::Zebin : Invalid simd size : " + std::to_string(kernelDescriptor.kernelAttributes.simdSize) + " in context of : " + kernelDescriptor.kernelMetadata.kernelName + ". Expected 1, 8, 16 or 32. Got : " + std::to_string(kernelDescriptor.kernelAttributes.simdSize) + "\n");

View File

@@ -940,6 +940,14 @@ kernels:
simd_size : 32
slm_size : 1024
subgroup_independent_forward_progress : true
required_work_group_size:
- 8
- 2
- 1
work_group_walk_order_dimensions:
- 0
- 1
- 2
...
)===";
@@ -973,6 +981,12 @@ kernels:
EXPECT_EQ(32, execEnv.simdSize);
EXPECT_EQ(1024, execEnv.slmSize);
EXPECT_TRUE(execEnv.subgroupIndependentForwardProgress);
EXPECT_EQ(8, execEnv.requiredWorkGroupSize[0]);
EXPECT_EQ(2, execEnv.requiredWorkGroupSize[1]);
EXPECT_EQ(1, execEnv.requiredWorkGroupSize[2]);
EXPECT_EQ(0, execEnv.workgroupWalkOrderDimensions[0]);
EXPECT_EQ(1, execEnv.workgroupWalkOrderDimensions[1]);
EXPECT_EQ(2, execEnv.workgroupWalkOrderDimensions[2]);
}
TEST(ReadZeInfoExecutionEnvironment, GivenUnknownEntryThenEmmitsWarning) {
@@ -1025,6 +1039,32 @@ kernels:
EXPECT_STREQ("DeviceBinaryFormat::Zebin::.ze_info : could not read actual_kernel_start_offset from : [true] in context of : some_kernel\n", errors.c_str());
}
TEST(ReadZeInfoExecutionEnvironment, GivenInvalidLengthForKnownCollectionEntryThenFails) {
NEO::ConstStringRef yaml = R"===(---
kernels:
- name: some_kernel
execution_env:
required_work_group_size:
- 5
- 2
...
)===";
std::string parserErrors;
std::string parserWarnings;
NEO::Yaml::YamlParser parser;
bool success = parser.parse(yaml, parserErrors, parserWarnings);
ASSERT_TRUE(success);
auto &execEnvNode = *parser.findNodeWithKeyDfs("execution_env");
std::string errors;
std::string warnings;
NEO::Elf::ZebinKernelMetadata::Types::Kernel::ExecutionEnv::ExecutionEnvBaseT execEnv;
auto err = NEO::readZeInfoExecutionEnvironment(parser, execEnvNode, execEnv, "some_kernel", errors, warnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, err);
EXPECT_TRUE(warnings.empty()) << warnings;
EXPECT_STREQ("DeviceBinaryFormat::Zebin::.ze_info : wrong size of collection required_work_group_size in context of : some_kernel. Got : 2 expected : 3\n", errors.c_str());
}
TEST(ReadEnumCheckedArgType, GivenValidStringRepresentationThenParseItCorrectly) {
using namespace NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::ArgType;
using namespace NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PerThreadPayloadArgument::ArgType;
@@ -3216,6 +3256,14 @@ kernels:
simd_size : 32
slm_size : 1024
subgroup_independent_forward_progress : true
required_work_group_size:
- 8
- 2
- 1
work_group_walk_order_dimensions:
- 0
- 1
- 2
)===";
NEO::ProgramInfo programInfo;
ZebinTestData::ValidEmptyProgram zebin;
@@ -3255,6 +3303,12 @@ kernels:
EXPECT_EQ(32U, kernelDescriptor.kernelAttributes.simdSize);
EXPECT_EQ(1024U, kernelDescriptor.kernelAttributes.slmInlineSize);
EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresSubgroupIndependentForwardProgress);
EXPECT_EQ(8U, kernelDescriptor.kernelAttributes.requiredWorkgroupSize[0]);
EXPECT_EQ(2U, kernelDescriptor.kernelAttributes.requiredWorkgroupSize[1]);
EXPECT_EQ(1U, kernelDescriptor.kernelAttributes.requiredWorkgroupSize[2]);
EXPECT_EQ(0U, kernelDescriptor.kernelAttributes.workgroupWalkOrder[0]);
EXPECT_EQ(1U, kernelDescriptor.kernelAttributes.workgroupWalkOrder[1]);
EXPECT_EQ(2U, kernelDescriptor.kernelAttributes.workgroupWalkOrder[2]);
}
TEST(PopulateArgDescriptorPerThreadPayload, GivenArgTypeLocalIdWhenOffsetIsNonZeroThenFail) {