diff --git a/shared/source/device_binary_format/elf/zebin_elf.h b/shared/source/device_binary_format/elf/zebin_elf.h index 76fb60dbe9..aaa59ef54f 100644 --- a/shared/source/device_binary_format/elf/zebin_elf.h +++ b/shared/source/device_binary_format/elf/zebin_elf.h @@ -121,6 +121,7 @@ constexpr ConstStringRef kernels("kernels"); constexpr ConstStringRef version("version"); constexpr ConstStringRef globalHostAccessTable("global_host_access_table"); constexpr ConstStringRef functions("functions"); +constexpr ConstStringRef kernelMiscInfo("kernels_misc_info"); namespace Kernel { constexpr ConstStringRef attributes("user_attributes"); @@ -365,6 +366,19 @@ constexpr ConstStringRef executionEnv("execution_env"); using namespace Kernel::ExecutionEnv; } // namespace Function +namespace KernelMiscInfo { +constexpr ConstStringRef name("name"); +constexpr ConstStringRef argsInfo("args_info"); +namespace ArgsInfo { +constexpr ConstStringRef index("index"); +constexpr ConstStringRef name("name"); +constexpr ConstStringRef addressQualifier("address_qualifier"); +constexpr ConstStringRef accessQualifier("access_qualifier"); +constexpr ConstStringRef typeName("type_name"); +constexpr ConstStringRef typeQualifiers("type_qualifiers"); +} // namespace ArgsInfo +} // namespace KernelMiscInfo + } // namespace Tags namespace Types { @@ -772,6 +786,20 @@ namespace ExecutionEnv { using namespace Kernel::ExecutionEnv; } } // namespace Function + +namespace Miscellaneous { +using ArgIndexT = uint32_t; +struct KernelArgMiscInfoT { + ArgIndexT index; + std::string kernelName; + std::string argName; + std::string accessQualifier; + std::string addressQualifier; + std::string typeName; + std::string typeQualifiers; +}; +} // namespace Miscellaneous + } // namespace Types } // namespace ZebinKernelMetadata diff --git a/shared/source/device_binary_format/zebin_decoder.cpp b/shared/source/device_binary_format/zebin_decoder.cpp index 76e8a220a3..43c3d0e150 100644 --- a/shared/source/device_binary_format/zebin_decoder.cpp +++ b/shared/source/device_binary_format/zebin_decoder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -26,6 +26,10 @@ namespace NEO { +void setKernelMiscInfoPosition(ConstStringRef metadata, NEO::ProgramInfo &dst) { + dst.kernelMiscInfoPos = metadata.str().find(Elf::ZebinKernelMetadata::Tags::kernelMiscInfo.str()); +} + template <> bool isDeviceBinaryFormat(const ArrayRef binary) { auto isValidZebinHeader = [](auto header) { @@ -1316,7 +1320,6 @@ NEO::DecodeError populateKernelDescriptor(NEO::ProgramInfo &dst, NEO::Elf::Elf(metadataString.begin() + dst.kernelMiscInfoPos), metadataString.size() - dst.kernelMiscInfoPos); + NEO::KernelInfo *kernelInfo = nullptr; + + NEO::Yaml::YamlParser parser; + bool parseSuccess = parser.parse(kernelMiscInfoString, outErrReason, outWarning); + if (false == parseSuccess) { + return DecodeError::InvalidBinary; + } + + auto kernelMiscInfoSectionNode = parser.createChildrenRange(*parser.getRoot()); + auto validMetadata = true; + using KernelArgsMiscInfoVec = std::vector>; + KernelArgsMiscInfoVec kernelArgsMiscInfoVec; + + for (const auto &kernelMiscInfoNode : parser.createChildrenRange(*kernelMiscInfoSectionNode.begin())) { + std::string kernelName{}; + KernelMiscArgInfos miscArgInfosVec; + for (const auto &kernelMiscInfoNodeMetadata : parser.createChildrenRange(kernelMiscInfoNode)) { + auto key = parser.readKey(kernelMiscInfoNodeMetadata); + if (key == Elf::ZebinKernelMetadata::Tags::KernelMiscInfo::name) { + validMetadata &= readZeInfoValueChecked(parser, kernelMiscInfoNodeMetadata, kernelName, Elf::ZebinKernelMetadata::Tags::kernelMiscInfo, outErrReason); + } else if (key == Elf::ZebinKernelMetadata::Tags::KernelMiscInfo::argsInfo) { + validMetadata &= (DecodeError::Success == readKernelMiscArgumentInfos(parser, kernelMiscInfoNodeMetadata, miscArgInfosVec, outErrReason, outWarning)); + } else { + outWarning.append("DeviceBinaryFormat::Zebin : Unrecognized entry: " + key.str() + " in " + Elf::ZebinKernelMetadata::Tags::kernelMiscInfo.str() + " zeInfo's section.\n"); + } + } + if (kernelName.empty()) { + outErrReason.append("DeviceBinaryFormat::Zebin : Error : Missing kernel name in " + Elf::ZebinKernelMetadata::Tags::kernelMiscInfo.str() + " section.\n"); + validMetadata = false; + } + kernelArgsMiscInfoVec.emplace_back(std::make_pair(std::move(kernelName), miscArgInfosVec)); + } + if (false == validMetadata) { + return DecodeError::InvalidBinary; + } + for (auto &[kName, miscInfos] : kernelArgsMiscInfoVec) { + for (auto dstKernelInfo : dst.kernelInfos) { + if (dstKernelInfo->kernelDescriptor.kernelMetadata.kernelName == kName) { + kernelInfo = dstKernelInfo; + break; + } + } + if (nullptr == kernelInfo) { + outErrReason.append("DeviceBinaryFormat::Zebin : Error : Cannot found kernel info for kernel " + kName + ".\n"); + return DecodeError::InvalidBinary; + } + populateKernelMiscInfo(kernelInfo->kernelDescriptor, miscInfos, outErrReason, outWarning); + } + return DecodeError::Success; +} + template NEO::DecodeError decodeZebin(ProgramInfo &dst, NEO::Elf::Elf &elf, std::string &outErrReason, std::string &outWarning); template NEO::DecodeError decodeZebin(ProgramInfo &dst, NEO::Elf::Elf &elf, std::string &outErrReason, std::string &outWarning); template @@ -1589,7 +1698,13 @@ NEO::DecodeError decodeZebin(ProgramInfo &dst, NEO::Elf::Elf &elf, std: } auto metadataSectionData = zebinSections.zeInfoSections[0]->data; + ConstStringRef metadataString(reinterpret_cast(metadataSectionData.begin()), metadataSectionData.size()); + setKernelMiscInfoPosition(metadataString, dst); + if (std::string::npos != dst.kernelMiscInfoPos) { + metadataString = metadataString.substr(static_cast(0), dst.kernelMiscInfoPos); + } + NEO::Yaml::YamlParser yamlParser; bool parseSuccess = yamlParser.parse(metadataString, outErrReason, outWarning); if (false == parseSuccess) { diff --git a/shared/source/device_binary_format/zebin_decoder.h b/shared/source/device_binary_format/zebin_decoder.h index 6945ce1ef9..5369e62ed5 100644 --- a/shared/source/device_binary_format/zebin_decoder.h +++ b/shared/source/device_binary_format/zebin_decoder.h @@ -146,4 +146,13 @@ NEO::DecodeError populateKernelSourceAttributes(NEO::KernelDescriptor &dst, NEO: template NEO::DecodeError decodeZebin(ProgramInfo &dst, NEO::Elf::Elf &elf, std::string &outErrReason, std::string &outWarning); +void setKernelMiscInfoPosition(ConstStringRef metadata, NEO::ProgramInfo &dst); + +using KernelMiscArgInfos = StackVec; +NEO::DecodeError readKernelMiscArgumentInfos(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node, KernelMiscArgInfos &kernelMiscArgInfosVec, std::string &outErrReason, std::string &outWarning); + +void populateKernelMiscInfo(KernelDescriptor &dst, KernelMiscArgInfos &kernelMiscArgInfosVec, std::string &outErrReason, std::string &outWarning); + +NEO::DecodeError decodeAndPopulateKernelMiscInfo(ProgramInfo &dst, ConstStringRef metadataString, std::string &outErrReason, std::string &outWarning); + } // namespace NEO diff --git a/shared/source/program/program_info.h b/shared/source/program/program_info.h index d180e21f01..270f4729cd 100644 --- a/shared/source/program/program_info.h +++ b/shared/source/program/program_info.h @@ -47,6 +47,7 @@ struct ProgramInfo { std::vector kernelInfos; uint32_t grfSize = 32U; uint32_t minScratchSpaceSize = 0U; + size_t kernelMiscInfoPos = std::string::npos; }; size_t getMaxInlineSlmNeeded(const ProgramInfo &programInfo); diff --git a/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp b/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp index e8226a0c8f..2e1b874a01 100644 --- a/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp +++ b/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp @@ -516,6 +516,369 @@ kernels: EXPECT_EQ("per_thread_memory_buffers", parser.readKey(*kernelSections.perThreadMemoryBuffersNd[0])) << parser.readKey(*kernelSections.perThreadMemoryBuffersNd[0]).str(); } +TEST(DecodeKernelMiscInfo, givenValidKernelMiscInfoSecionThenExplicitArgsExtendedMetadataIsProperlyPopulated) { + NEO::ConstStringRef zeInfo = R"===(--- +version: '1.19' +kernels: + - name: kernel1 + execution_env: + simd_size: 32 + payload_arguments: + // SOME PAYLOAD ARGUMENTS + // IT SHOULD NOT GET PARSED + - name: kernel2 + execution_env: + simd_size: 32 + payload_arguments: + // SOME PAYLOAD ARGUMENTS + // IT SHOULD NOT GET PARSED +kernels_misc_info: + - name: kernel1 + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE + - name: kernel2 + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE + - index: 1 + name: b + address_qualifier: __private + access_qualifier: NONE + type_name: 'int;4' + type_qualifiers: NONE + - index: 2 + name: c + address_qualifier: __global + access_qualifier: NONE + type_name: 'uint*;8' + type_qualifiers: const + - index: 3 + name: imageA + address_qualifier: __global + access_qualifier: __read_only + type_name: 'image2d_t;8' + type_qualifiers: NONE +... +)==="; + NEO::ProgramInfo programInfo; + setKernelMiscInfoPosition(zeInfo, programInfo); + EXPECT_NE(std::string::npos, programInfo.kernelMiscInfoPos); + + auto kernel1Info = new KernelInfo(); + kernel1Info->kernelDescriptor.kernelMetadata.kernelName = "kernel1"; + auto kernel2Info = new KernelInfo(); + kernel2Info->kernelDescriptor.kernelMetadata.kernelName = "kernel2"; + + programInfo.kernelInfos.reserve(2); + programInfo.kernelInfos.push_back(kernel1Info); + programInfo.kernelInfos.push_back(kernel2Info); + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, zeInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::Success, res); + EXPECT_TRUE(outErrors.empty()); + EXPECT_TRUE(outWarnings.empty()); + + EXPECT_EQ(1u, kernel1Info->kernelDescriptor.explicitArgsExtendedMetadata.size()); + const auto &kernel1ArgInfo1 = kernel1Info->kernelDescriptor.explicitArgsExtendedMetadata.at(0); + EXPECT_STREQ(kernel1ArgInfo1.argName.c_str(), "a"); + EXPECT_STREQ(kernel1ArgInfo1.addressQualifier.c_str(), "__global"); + EXPECT_STREQ(kernel1ArgInfo1.accessQualifier.c_str(), "NONE"); + EXPECT_STREQ(kernel1ArgInfo1.type.c_str(), "'int*;8'"); + EXPECT_STREQ(kernel1ArgInfo1.typeQualifiers.c_str(), "NONE"); + + EXPECT_EQ(4u, kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.size()); + const auto &kernel2ArgInfo1 = kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.at(0); + EXPECT_STREQ(kernel2ArgInfo1.argName.c_str(), "a"); + EXPECT_STREQ(kernel2ArgInfo1.addressQualifier.c_str(), "__global"); + EXPECT_STREQ(kernel2ArgInfo1.accessQualifier.c_str(), "NONE"); + EXPECT_STREQ(kernel2ArgInfo1.type.c_str(), "'int*;8'"); + EXPECT_STREQ(kernel2ArgInfo1.typeQualifiers.c_str(), "NONE"); + + const auto &kernel2ArgInfo2 = kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.at(1); + EXPECT_STREQ(kernel2ArgInfo2.argName.c_str(), "b"); + EXPECT_STREQ(kernel2ArgInfo2.addressQualifier.c_str(), "__private"); + EXPECT_STREQ(kernel2ArgInfo2.accessQualifier.c_str(), "NONE"); + EXPECT_STREQ(kernel2ArgInfo2.type.c_str(), "'int;4'"); + EXPECT_STREQ(kernel2ArgInfo2.typeQualifiers.c_str(), "NONE"); + + const auto &kernel2ArgInfo3 = kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.at(2); + EXPECT_STREQ(kernel2ArgInfo3.argName.c_str(), "c"); + EXPECT_STREQ(kernel2ArgInfo3.addressQualifier.c_str(), "__global"); + EXPECT_STREQ(kernel2ArgInfo3.accessQualifier.c_str(), "NONE"); + EXPECT_STREQ(kernel2ArgInfo3.type.c_str(), "'uint*;8'"); + EXPECT_STREQ(kernel2ArgInfo3.typeQualifiers.c_str(), "const"); + + const auto &kernel2ArgInfo4 = kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.at(3); + EXPECT_STREQ(kernel2ArgInfo4.argName.c_str(), "imageA"); + EXPECT_STREQ(kernel2ArgInfo4.addressQualifier.c_str(), "__global"); + EXPECT_STREQ(kernel2ArgInfo4.accessQualifier.c_str(), "__read_only"); + EXPECT_STREQ(kernel2ArgInfo4.type.c_str(), "'image2d_t;8'"); + EXPECT_STREQ(kernel2ArgInfo4.typeQualifiers.c_str(), "NONE"); +} + +TEST(DecodeKernelMiscInfo, givenUnrecognizedEntryInKernelsMiscInfoSectionWhenDecodingItThenEmitWarning) { + NEO::ConstStringRef kernelMiscInfoUnrecognized = R"===(--- +kernels_misc_info: + - name: some_kernel + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE + pickle: pickle +... +)==="; + auto kernelInfo = new KernelInfo(); + kernelInfo->kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + programInfo.kernelInfos.push_back(kernelInfo); + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfoUnrecognized, outErrors, outWarnings); + EXPECT_EQ(DecodeError::Success, res); + EXPECT_TRUE(outErrors.empty()); + + auto expectedWarning = "DeviceBinaryFormat::Zebin : Unrecognized entry: pickle in kernels_misc_info zeInfo's section.\n"; + EXPECT_STREQ(outWarnings.c_str(), expectedWarning); +} + +TEST(DecodeKernelMiscInfo, givenUnrecognizedEntryInArgsInfoWhenDecodingKernelsMiscInfoSectionThenEmitWarning) { + NEO::ConstStringRef kernelMiscInfoUnrecognizedArgInfo = R"===(--- +kernels_misc_info: + - name: some_kernel + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE + pickle: pickle +... +)==="; + auto kernelInfo = new KernelInfo(); + kernelInfo->kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + programInfo.kernelInfos.push_back(kernelInfo); + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfoUnrecognizedArgInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::Success, res); + EXPECT_TRUE(outErrors.empty()); + + auto expectedWarning = "DeviceBinaryFormat::Zebin : KernelMiscInfo : Unrecognized argsInfo member pickle\n"; + EXPECT_STREQ(outWarnings.c_str(), expectedWarning); +} + +TEST(DecodeKernelMiscInfo, givenKeysWithInvalidValuesInKernelsMiscInfoWhenDecodingKernelsMiscInfoSectionThenReturnErrorForEachInvalidValue) { + NEO::ConstStringRef kernelMiscInfoUnrecognizedArgInfo = R"===(--- +kernels_misc_info: + - name: - + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE + - name: - + args_info: + - index: 0 + name: b + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE +... +)==="; + auto kernelInfo = new KernelInfo(); + kernelInfo->kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + programInfo.kernelInfos.push_back(kernelInfo); + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfoUnrecognizedArgInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::InvalidBinary, res); + + EXPECT_NE(std::string::npos, outErrors.find("DeviceBinaryFormat::Zebin::.ze_info : could not read name from : [-] in context of : kernels_misc_info\n")); + EXPECT_NE(std::string::npos, outErrors.find("DeviceBinaryFormat::Zebin::.ze_info : could not read name from : [-] in context of : kernels_misc_info\n")); +} + +TEST(DecodeKernelMiscInfo, givenKeysWithInvalidValuesInArgsInfoWhenDecodingKernelsMiscInfoSectionThenReturnErrorForEachInvalidValue) { + NEO::ConstStringRef kernelMiscInfoUnrecognizedArgInfo = R"===(--- +kernels_misc_info: + - name: kernel_1 + args_info: + - index: 0 + name: a + address_qualifier: - + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE + - name: kernel_2 + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: - + type_name: 'int*;8' + type_qualifiers: NONE +... +)==="; + auto kernelInfo = new KernelInfo(); + kernelInfo->kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + programInfo.kernelInfos.push_back(kernelInfo); + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfoUnrecognizedArgInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::InvalidBinary, res); + + EXPECT_NE(std::string::npos, outErrors.find("DeviceBinaryFormat::Zebin::.ze_info : could not read address_qualifier from : [-] in context of : kernels_misc_info\n")); + EXPECT_NE(std::string::npos, outErrors.find("DeviceBinaryFormat::Zebin::.ze_info : could not read access_qualifier from : [-] in context of : kernels_misc_info\n")); +} + +TEST(DecodeKernelMiscInfo, givenArgsInfoEntryWithMissingMembersWhenDecodingKernelsMiscInfoSectionThenEmitWarningForEachMissingMember) { + NEO::ConstStringRef kernelMiscInfoEmptyArgsInfo = R"===(--- +kernels_misc_info: + - name: some_kernel + args_info: + - index: 0 +... +)==="; + + auto kernelInfo = new KernelInfo(); + kernelInfo->kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + programInfo.kernelInfos.push_back(kernelInfo); + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfoEmptyArgsInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::Success, res); + EXPECT_TRUE(outErrors.empty()); + std::array missingMembers = { + "name", + "address_qualifier", + "access_qualifier", + "type_name", + "type_qualifiers"}; + for (const auto &missingMember : missingMembers) { + auto expectedWarning = "DeviceBinaryFormat::Zebin : KernelMiscInfo : ArgInfo member \"" + missingMember + "\" missing. Ignoring.\n"; + EXPECT_NE(std::string::npos, outWarnings.find(expectedWarning)); + } +} + +TEST(DecodeKernelMiscInfo, whenDecodingKernelsMiscInfoSectionAndParsingErrorIsEncounteredThenReturnError) { + NEO::ConstStringRef kernelMiscInfo = R"===(--- +kernels_misc_info: + args_info: +// ENFORCE PARSING ERROR +... +)==="; + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::InvalidBinary, res); +} + +TEST(DecodeKernelMiscInfo, givenKernelMiscInfoEntryWithMissingKernelNameWhenDecodingKernelsMiscInfoSectionThenErrorIsReturned) { + NEO::ConstStringRef kernelMiscInfo = R"===(--- +kernels_misc_info: + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE +... +)==="; + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::InvalidBinary, res); + + auto expectedError{"DeviceBinaryFormat::Zebin : Error : Missing kernel name in kernels_misc_info section.\n"}; + EXPECT_STREQ(outErrors.c_str(), expectedError); +} + +TEST(DecodeKernelMiscInfo, givenKernelMiscInfoEntryAndProgramInfoWihoutCorrespondingKernelInfoWhenDecodingKernelsMiscInfoSectionThenErrorIsReturned) { + NEO::ConstStringRef kernelMiscInfo = R"===(--- +kernels_misc_info: + - name: some_kernel + args_info: + - index: 0 + name: a + address_qualifier: __global + access_qualifier: NONE + type_name: 'int*;8' + type_qualifiers: NONE +... +)==="; + NEO::ProgramInfo programInfo; + programInfo.kernelMiscInfoPos = 0u; + auto kernelInfo = new KernelInfo(); + kernelInfo->kernelDescriptor.kernelMetadata.kernelName = "invalid_kernel_name"; + programInfo.kernelInfos.push_back(kernelInfo); + + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, kernelMiscInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::InvalidBinary, res); + + auto expectedError{"DeviceBinaryFormat::Zebin : Error : Cannot found kernel info for kernel some_kernel.\n"}; + EXPECT_STREQ(outErrors.c_str(), expectedError); +} + +TEST(DecodeKernelMiscInfo, givenNoKernelMiscInfoSectionAvailableWhenParsingItThenEmitWarningAndReturn) { + NEO::ConstStringRef zeInfo = R"===(--- +version: '1.19' +kernels: + - name: kernel1 + execution_env: + simd_size: 32 + payload_arguments: + - arg_type: global_id_offset + offset: 0 + size: 12 +)==="; + + NEO::ProgramInfo programInfo; + setKernelMiscInfoPosition(zeInfo, programInfo); + EXPECT_EQ(std::string::npos, programInfo.kernelMiscInfoPos); + std::string outWarnings, outErrors; + auto res = decodeAndPopulateKernelMiscInfo(programInfo, zeInfo, outErrors, outWarnings); + + EXPECT_EQ(DecodeError::InvalidBinary, res); + auto expectedError{"DeviceBinaryFormat::Zebin : Position of kernels_misc_info not set - may be missing in zeInfo.\n"}; + EXPECT_STREQ(outErrors.c_str(), expectedError); +} + TEST(ExtractZeInfoKernelSections, GivenExperimentalPropertyInKnownSectionsThenSectionIsCapturedProperly) { NEO::ConstStringRef yaml = R"===(--- kernels: @@ -2719,6 +3082,43 @@ functions: EXPECT_TRUE(decodeWarnings.empty()) << decodeWarnings; } +TEST(DecodeSingleDeviceBinaryZebin, givenZeInfoWithKernelsMiscInfoSectionWhenDecodingBinaryThenDoNotParseThisSection) { + std::string zeInfo = std::string("version :\'") + versionToString(zeInfoDecoderVersion) + R"===(' +kernels: + - name: kernel1 + execution_env: + simd_size: 32 + payload_arguments: + - arg_type: arg_bypointer + offset: 0 + size: 0 + arg_index: 0 + addrmode: stateful + addrspace: global + access_type: readwrite +kernels_misc_info: + // DO NOT PARSE + // ANYTHING IN THIS SECTION + // OTHERWISE, YOU WILL GET PARSING ERROR +... +)==="; + ZebinTestData::ValidEmptyProgram zebin; + zebin.removeSection(NEO::Elf::SHT_ZEBIN::SHT_ZEBIN_ZEINFO, NEO::Elf::SectionsNamesZebin::zeInfo); + zebin.appendSection(NEO::Elf::SHT_ZEBIN::SHT_ZEBIN_ZEINFO, NEO::Elf::SectionsNamesZebin::zeInfo, ArrayRef::fromAny(zeInfo.data(), zeInfo.size())); + zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "kernel1", {}); + + NEO::ProgramInfo programInfo; + NEO::SingleDeviceBinary singleBinary; + singleBinary.deviceBinary = {zebin.storage.data(), zebin.storage.size()}; + std::string decodeErrors; + std::string decodeWarnings; + auto error = NEO::decodeSingleDeviceBinary(programInfo, singleBinary, decodeErrors, decodeWarnings); + EXPECT_EQ(NEO::DecodeError::Success, error); + EXPECT_TRUE(decodeWarnings.empty()); + EXPECT_TRUE(decodeErrors.empty()); + EXPECT_NE(std::string::npos, programInfo.kernelMiscInfoPos); +} + TEST(PopulateKernelDescriptor, GivenMinimalExecutionEnvThenPopulateKernelDescriptorWithDefaults) { std::string zeinfo = R"===( kernels: