diff --git a/opencl/test/unit_test/kernel/kernel_arg_info_tests.cpp b/opencl/test/unit_test/kernel/kernel_arg_info_tests.cpp index 6b7345cdb8..dffbd2834f 100644 --- a/opencl/test/unit_test/kernel/kernel_arg_info_tests.cpp +++ b/opencl/test/unit_test/kernel/kernel_arg_info_tests.cpp @@ -129,4 +129,4 @@ TEST_F(KernelArgInfoTest, GivenParamWhenGettingKernelArgNameThenCorrectValueIsRe nullptr); ASSERT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(0, strcmp(paramValue.get(), expectedArgName)); -} +} \ No newline at end of file diff --git a/opencl/test/unit_test/program/program_tests.cpp b/opencl/test/unit_test/program/program_tests.cpp index 0734d535d6..b7af3cb957 100644 --- a/opencl/test/unit_test/program/program_tests.cpp +++ b/opencl/test/unit_test/program/program_tests.cpp @@ -3426,3 +3426,100 @@ TEST(ProgramInternalOptionsTests, givenProgramWhenForceDefaultGrfCompilationMode CompilerOptions::applyAdditionalOptions(internalOptions); EXPECT_EQ(internalOptionsSize, internalOptions.size()); } + +TEST(ProgramPopulateZebinExtendedArgsMetadataTests, givenNonZebinaryFormatWhenCallingPopulateZebinExtendedArgsMetadataThenMetadataIsNotPopulated) { + MockClDevice device{new MockDevice()}; + MockProgram program(toClDeviceVector(device)); + program.callBasePopulateZebinExtendedArgsMetadataOnce = true; + + constexpr auto mockBinarySize = 0x10; + const auto &rootDeviceIndex = device.getRootDeviceIndex(); + auto &buildInfo = program.buildInfos[rootDeviceIndex]; + buildInfo.unpackedDeviceBinary.reset(new char[mockBinarySize]{0}); + buildInfo.unpackedDeviceBinarySize = mockBinarySize; + + KernelInfo kernelInfo; + kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + buildInfo.kernelInfoArray.push_back(&kernelInfo); + + ASSERT_TRUE(kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.empty()); + program.callPopulateZebinExtendedArgsMetadataOnce(rootDeviceIndex); + EXPECT_TRUE(kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.empty()); + buildInfo.kernelInfoArray.clear(); +} + +TEST(ProgramPopulateZebinExtendedArgsMetadataTests, givenZebinaryFormatAndDecodeErrorOnDecodingArgsMetadataWhenCallingPopulateZebinExtendedArgsMetadataThenMetadataIsNotPopulated) { + MockClDevice device{new MockDevice()}; + MockProgram program(toClDeviceVector(device)); + program.callBasePopulateZebinExtendedArgsMetadataOnce = true; + + const auto &rootDeviceIndex = device.getRootDeviceIndex(); + auto &buildInfo = program.buildInfos[rootDeviceIndex]; + + KernelInfo kernelInfo; + kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + buildInfo.kernelInfoArray.push_back(&kernelInfo); + + NEO::ConstStringRef invalidZeInfo = R"===( +kernels: + - name: some_kernel + simd_size: 32 +... +)==="; + + constexpr auto numBits = is32bit ? Elf::EI_CLASS_32 : Elf::EI_CLASS_64; + MockElfEncoder elfEncoder; + elfEncoder.getElfFileHeader().type = NEO::Elf::ET_REL; + elfEncoder.appendSection(Elf::SHT_ZEBIN::SHT_ZEBIN_ZEINFO, Elf::SectionsNamesZebin::zeInfo, ArrayRef::fromAny(invalidZeInfo.data(), invalidZeInfo.size())); + auto storage = elfEncoder.encode(); + buildInfo.unpackedDeviceBinary.reset(reinterpret_cast(storage.data())); + buildInfo.unpackedDeviceBinarySize = storage.size(); + + ASSERT_TRUE(kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.empty()); + ASSERT_EQ(std::string::npos, buildInfo.kernelMiscInfoPos); + program.callPopulateZebinExtendedArgsMetadataOnce(rootDeviceIndex); + EXPECT_TRUE(kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.empty()); + buildInfo.kernelInfoArray.clear(); + buildInfo.unpackedDeviceBinary.release(); +} + +TEST(ProgramPopulateZebinExtendedArgsMetadataTests, givenZebinaryFormatWithValidZeInfoWhenCallingPopulateExtendedArgsMetadataThenMetadataIsPopulated) { + MockClDevice device{new MockDevice()}; + MockProgram program(toClDeviceVector(device)); + program.callBasePopulateZebinExtendedArgsMetadataOnce = true; + + const auto &rootDeviceIndex = device.getRootDeviceIndex(); + auto &buildInfo = program.buildInfos[rootDeviceIndex]; + + KernelInfo kernelInfo; + kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "some_kernel"; + buildInfo.kernelInfoArray.push_back(&kernelInfo); + + NEO::ConstStringRef zeInfo = R"===( +kernels: + - name: some_kernel + simd_size: 32 +kernels_misc_info: + - name: some_kernel + args_info: + - name: a + index: 0 + address_qualifier: __global +... +)==="; + constexpr auto numBits = is32bit ? Elf::EI_CLASS_32 : Elf::EI_CLASS_64; + MockElfEncoder elfEncoder; + elfEncoder.getElfFileHeader().type = NEO::Elf::ET_REL; + elfEncoder.appendSection(Elf::SHT_ZEBIN::SHT_ZEBIN_ZEINFO, Elf::SectionsNamesZebin::zeInfo, ArrayRef::fromAny(zeInfo.data(), zeInfo.size())); + auto storage = elfEncoder.encode(); + buildInfo.unpackedDeviceBinary.reset(reinterpret_cast(storage.data())); + buildInfo.unpackedDeviceBinarySize = storage.size(); + buildInfo.kernelMiscInfoPos = zeInfo.str().find(Elf::ZebinKernelMetadata::Tags::kernelMiscInfo.str()); + ASSERT_NE(std::string::npos, buildInfo.kernelMiscInfoPos); + + ASSERT_TRUE(kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.empty()); + program.callPopulateZebinExtendedArgsMetadataOnce(rootDeviceIndex); + EXPECT_EQ(1u, kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.size()); + buildInfo.kernelInfoArray.clear(); + buildInfo.unpackedDeviceBinary.release(); +} diff --git a/shared/source/device_binary_format/elf/zebin_elf.h b/shared/source/device_binary_format/elf/zebin_elf.h index 1c0cb37a76..abd0a4001b 100644 --- a/shared/source/device_binary_format/elf/zebin_elf.h +++ b/shared/source/device_binary_format/elf/zebin_elf.h @@ -790,9 +790,9 @@ using namespace Kernel::ExecutionEnv; } // namespace Function namespace Miscellaneous { -using ArgIndexT = uint32_t; +using ArgIndexT = int32_t; struct KernelArgMiscInfoT { - ArgIndexT index; + ArgIndexT index = -1; std::string kernelName; std::string argName; std::string accessQualifier; diff --git a/shared/source/device_binary_format/zebin_decoder.cpp b/shared/source/device_binary_format/zebin_decoder.cpp index 328f0e81e8..070f8a76a1 100644 --- a/shared/source/device_binary_format/zebin_decoder.cpp +++ b/shared/source/device_binary_format/zebin_decoder.cpp @@ -1583,6 +1583,10 @@ NEO::DecodeError readKernelMiscArgumentInfos(const NEO::Yaml::YamlParser &parser outWarning.append("DeviceBinaryFormat::Zebin : KernelMiscInfo : Unrecognized argsInfo member " + key.str() + "\n"); } } + if (-1 == metadataExtended.index) { + outErrReason.append("DeviceBinaryFormat::Zebin : Error : KernelMiscInfo : ArgInfo index missing (has default value -1)"); + return DecodeError::InvalidBinary; + } } return validArgInfo ? DecodeError::Success : DecodeError::InvalidBinary; } @@ -1605,6 +1609,12 @@ void populateKernelMiscInfo(KernelDescriptor &dst, KernelMiscArgInfos &kernelMis populateIfNotEmpty(srcMetadata.typeName, dstMetadata.type, Elf::ZebinKernelMetadata::Tags::KernelMiscInfo::ArgsInfo::typeName, outWarning); populateIfNotEmpty(srcMetadata.typeQualifiers, dstMetadata.typeQualifiers, Elf::ZebinKernelMetadata::Tags::KernelMiscInfo::ArgsInfo::typeQualifiers, outWarning); + ArgTypeTraits dstTypeTraits = {}; + dstTypeTraits.accessQualifier = KernelArgMetadata::parseAccessQualifier(dstMetadata.accessQualifier); + dstTypeTraits.addressQualifier = KernelArgMetadata::parseAddressSpace(dstMetadata.addressQualifier); + dstTypeTraits.typeQualifiers = KernelArgMetadata::parseTypeQualifiers(dstMetadata.typeQualifiers); + + dst.payloadMappings.explicitArgs.at(srcMetadata.index).getTraits() = std::move(dstTypeTraits); dst.explicitArgsExtendedMetadata.at(srcMetadata.index) = std::move(dstMetadata); } } 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 58a7b5c39b..c128c9d655 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 @@ -596,6 +596,13 @@ kernels_misc_info: EXPECT_STREQ(kernel1ArgInfo1.type.c_str(), "'int*;8'"); EXPECT_STREQ(kernel1ArgInfo1.typeQualifiers.c_str(), "NONE"); + const auto &kernel1ArgTraits1 = kernel1Info->kernelDescriptor.payloadMappings.explicitArgs.at(0).getTraits(); + EXPECT_EQ(KernelArgMetadata::AccessNone, kernel1ArgTraits1.accessQualifier); + EXPECT_EQ(KernelArgMetadata::AddrGlobal, kernel1ArgTraits1.addressQualifier); + KernelArgMetadata::TypeQualifiers qual = {}; + qual.unknownQual = true; + EXPECT_EQ(qual.packed, kernel1ArgTraits1.typeQualifiers.packed); + EXPECT_EQ(4u, kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.size()); const auto &kernel2ArgInfo1 = kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.at(0); EXPECT_STREQ(kernel2ArgInfo1.argName.c_str(), "a"); @@ -604,6 +611,13 @@ kernels_misc_info: EXPECT_STREQ(kernel2ArgInfo1.type.c_str(), "'int*;8'"); EXPECT_STREQ(kernel2ArgInfo1.typeQualifiers.c_str(), "NONE"); + const auto &kernel2ArgTraits1 = kernel2Info->kernelDescriptor.payloadMappings.explicitArgs.at(0).getTraits(); + EXPECT_EQ(KernelArgMetadata::AccessNone, kernel2ArgTraits1.accessQualifier); + EXPECT_EQ(KernelArgMetadata::AddrGlobal, kernel2ArgTraits1.addressQualifier); + qual = {}; + qual.unknownQual = true; + EXPECT_EQ(qual.packed, kernel2ArgTraits1.typeQualifiers.packed); + const auto &kernel2ArgInfo2 = kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.at(1); EXPECT_STREQ(kernel2ArgInfo2.argName.c_str(), "b"); EXPECT_STREQ(kernel2ArgInfo2.addressQualifier.c_str(), "__private"); @@ -611,6 +625,13 @@ kernels_misc_info: EXPECT_STREQ(kernel2ArgInfo2.type.c_str(), "'int;4'"); EXPECT_STREQ(kernel2ArgInfo2.typeQualifiers.c_str(), "NONE"); + const auto &kernel2ArgTraits2 = kernel2Info->kernelDescriptor.payloadMappings.explicitArgs.at(1).getTraits(); + EXPECT_EQ(KernelArgMetadata::AccessNone, kernel2ArgTraits2.accessQualifier); + EXPECT_EQ(KernelArgMetadata::AddrPrivate, kernel2ArgTraits2.addressQualifier); + qual = {}; + qual.unknownQual = true; + EXPECT_EQ(qual.packed, kernel2ArgTraits2.typeQualifiers.packed); + const auto &kernel2ArgInfo3 = kernel2Info->kernelDescriptor.explicitArgsExtendedMetadata.at(2); EXPECT_STREQ(kernel2ArgInfo3.argName.c_str(), "c"); EXPECT_STREQ(kernel2ArgInfo3.addressQualifier.c_str(), "__global"); @@ -618,12 +639,26 @@ kernels_misc_info: EXPECT_STREQ(kernel2ArgInfo3.type.c_str(), "'uint*;8'"); EXPECT_STREQ(kernel2ArgInfo3.typeQualifiers.c_str(), "const"); + const auto &kernel2ArgTraits3 = kernel2Info->kernelDescriptor.payloadMappings.explicitArgs.at(2).getTraits(); + EXPECT_EQ(KernelArgMetadata::AccessNone, kernel2ArgTraits3.accessQualifier); + EXPECT_EQ(KernelArgMetadata::AddrGlobal, kernel2ArgTraits3.addressQualifier); + qual = {}; + qual.constQual = true; + EXPECT_EQ(qual.packed, kernel2ArgTraits3.typeQualifiers.packed); + 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"); + + const auto &kernel2ArgTraits4 = kernel2Info->kernelDescriptor.payloadMappings.explicitArgs.at(3).getTraits(); + EXPECT_EQ(KernelArgMetadata::AccessReadOnly, kernel2ArgTraits4.accessQualifier); + EXPECT_EQ(KernelArgMetadata::AddrGlobal, kernel2ArgTraits4.addressQualifier); + qual = {}; + qual.unknownQual = true; + EXPECT_EQ(qual.packed, kernel2ArgTraits4.typeQualifiers.packed); } TEST(DecodeKernelMiscInfo, givenUnrecognizedEntryInKernelsMiscInfoSectionWhenDecodingItThenEmitWarning) { @@ -758,12 +793,13 @@ kernels_misc_info: 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) { +TEST(DecodeKernelMiscInfo, givenArgsInfoEntryWithMissingMembersOtherThanArgIndexWhenDecodingKernelsMiscInfoSectionThenEmitWarningForEachMissingMember) { NEO::ConstStringRef kernelMiscInfoEmptyArgsInfo = R"===(--- kernels_misc_info: - name: some_kernel args_info: - index: 0 + invalid_value: 0 ... )==="; @@ -790,6 +826,34 @@ kernels_misc_info: } } +TEST(DecodeKernelMiscInfo, givenArgsInfoEntryWithMissingArgIndexWhenDecodingKernelsMiscInfoSectionThenReturnError) { + NEO::ConstStringRef kernelMiscInfoEmptyArgsInfo = R"===(--- +kernels_misc_info: + - name: some_kernel + args_info: + - name: a + 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.kernelMiscInfoPos, programInfo.kernelInfos, kernelMiscInfoEmptyArgsInfo, outErrors, outWarnings); + EXPECT_EQ(DecodeError::InvalidBinary, res); + + auto expectedError{"DeviceBinaryFormat::Zebin : Error : KernelMiscInfo : ArgInfo index missing (has default value -1)"}; + EXPECT_STREQ(outErrors.c_str(), expectedError); +} + TEST(DecodeKernelMiscInfo, whenDecodingKernelsMiscInfoSectionAndParsingErrorIsEncounteredThenReturnError) { NEO::ConstStringRef kernelMiscInfo = R"===(--- kernels_misc_info: