diff --git a/shared/source/device_binary_format/elf/zebin_elf.h b/shared/source/device_binary_format/elf/zebin_elf.h index f9fc7fe3e1..ca4706180e 100644 --- a/shared/source/device_binary_format/elf/zebin_elf.h +++ b/shared/source/device_binary_format/elf/zebin_elf.h @@ -165,6 +165,7 @@ static constexpr ConstStringRef addrspace("addrspace"); static constexpr ConstStringRef accessType("access_type"); static constexpr ConstStringRef samplerIndex("sampler_index"); static constexpr ConstStringRef sourceOffset("source_offset"); +static constexpr ConstStringRef slmArgAlignment("slm_alignment"); namespace ArgType { static constexpr ConstStringRef localSize("local_size"); static constexpr ConstStringRef groupCount("group_count"); @@ -430,12 +431,12 @@ using ArgIndexT = int32_t; using AddrmodeT = MemoryAddressingMode; using AddrspaceT = AddressSpace; using AccessTypeT = AccessType; -using SlmAlignment = uint8_t; +using SlmAlignmentT = uint8_t; using SamplerIndexT = int32_t; namespace Defaults { static constexpr ArgIndexT argIndex = -1; -static constexpr SlmAlignment slmArgAlignment = 16U; +static constexpr SlmAlignmentT slmArgAlignment = 16U; static constexpr SamplerIndexT samplerIndex = -1; static constexpr SourceOffseT sourceOffset = -1; } // namespace Defaults @@ -450,6 +451,7 @@ struct PayloadArgumentBaseT { AddrspaceT addrspace = AddressSpaceUnknown; AccessTypeT accessType = AccessTypeUnknown; SamplerIndexT samplerIndex = Defaults::samplerIndex; + SlmAlignmentT slmArgAlignment = Defaults::slmArgAlignment; }; } // namespace PayloadArgument diff --git a/shared/source/device_binary_format/zebin_decoder.cpp b/shared/source/device_binary_format/zebin_decoder.cpp index d9b323e8b1..885d703c90 100644 --- a/shared/source/device_binary_format/zebin_decoder.cpp +++ b/shared/source/device_binary_format/zebin_decoder.cpp @@ -582,6 +582,8 @@ DecodeError readZeInfoPayloadArguments(const NEO::Yaml::YamlParser &parser, cons outMaxSamplerIndex = std::max(outMaxSamplerIndex, payloadArgMetadata.samplerIndex); } else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::sourceOffset == key) { validPayload &= readZeInfoValueChecked(parser, payloadArgumentMemberNd, payloadArgMetadata.sourceOffset, context, outErrReason); + } else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::slmArgAlignment == key) { + validPayload &= readZeInfoValueChecked(parser, payloadArgumentMemberNd, payloadArgMetadata.slmArgAlignment, context, outErrReason); } else { outWarning.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unknown entry \"" + key.str() + "\" for payload argument in context of " + context.str() + "\n"); } @@ -840,7 +842,7 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type break; case NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::MemoryAddressingModeSharedLocalMemory: dst.payloadMappings.explicitArgs[src.argIndex].as(false).slmOffset = src.offset; - dst.payloadMappings.explicitArgs[src.argIndex].as(false).requiredSlmAlignment = NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::Defaults::slmArgAlignment; + dst.payloadMappings.explicitArgs[src.argIndex].as(false).requiredSlmAlignment = src.slmArgAlignment; break; } break; 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 4c8023c0c8..85faa5d07d 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 @@ -1993,6 +1993,47 @@ kernels: EXPECT_EQ(2, args[0].argIndex); } +TEST(ReadZeInfoPayloadArguments, GivenArgByPointerWithSlmAddresingModeAndSlmAlignmentThenSetSlmAlignmentAccordingly) { + NEO::ConstStringRef yaml = R"===(--- +kernels: + - name: some_kernel + payload_arguments: + - arg_type : arg_bypointer + offset : 24 + size : 4 + arg_index : 2 + addrmode : slm + - arg_type : arg_bypointer + offset : 16 + size : 8 + arg_index : 1 + addrmode : slm + slm_alignment: 8 +)==="; + + std::string parserErrors; + std::string parserWarnings; + NEO::Yaml::YamlParser parser; + bool success = parser.parse(yaml, parserErrors, parserWarnings); + ASSERT_TRUE(success); + auto &argsNode = *parser.findNodeWithKeyDfs("payload_arguments"); + std::string errors; + std::string warnings; + NEO::ZeInfoPayloadArguments args; + int32_t maxArgIndex = -1; + int32_t maxSmpIndex = -1; + auto err = NEO::readZeInfoPayloadArguments(parser, argsNode, args, maxArgIndex, maxSmpIndex, "some_kernel", errors, warnings); + EXPECT_EQ(NEO::DecodeError::Success, err); + EXPECT_TRUE(errors.empty()) << errors; + EXPECT_TRUE(warnings.empty()) << warnings; + + ASSERT_EQ(2U, args.size()); + EXPECT_EQ(NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeArgBypointer, args[0].argType); + EXPECT_EQ(NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeArgBypointer, args[1].argType); + EXPECT_EQ(16, args[0].slmArgAlignment); + EXPECT_EQ(8, args[1].slmArgAlignment); +} + TEST(ReadZeInfoBindingTableIndices, GivenInvalidValueForKnownEntryThenFails) { NEO::ConstStringRef yaml = R"===(--- kernels: @@ -4744,6 +4785,44 @@ TEST(PopulateArgDescriptorCrossthreadPalyoad, GivenArgTypeEnqueuedLocalSizeWhenA EXPECT_TRUE(warnings.empty()) << warnings; } +TEST(PopulateArgDescriptorCrossthreadPalyoad, GivenArgTypeByPointerWithSlmAlignmentSetThenPopulatesKernelDescriptor) { + NEO::ConstStringRef zeinfo = R"===( + kernels: + - name : some_kernel + execution_env: + simd_size: 32 + payload_arguments: + - arg_type : arg_bypointer + offset : 0 + size : 8 + arg_index : 0 + addrmode : slm + slm_alignment: 8 +)==="; + NEO::ProgramInfo programInfo; + ZebinTestData::ValidEmptyProgram zebin; + zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "some_kernel", {}); + std::string errors, warnings; + auto elf = NEO::Elf::decodeElf(zebin.storage, errors, warnings); + ASSERT_NE(nullptr, elf.elfFileHeader) << errors << " " << warnings; + + NEO::Yaml::YamlParser parser; + bool parseSuccess = parser.parse(zeinfo, errors, warnings); + ASSERT_TRUE(parseSuccess) << errors << " " << warnings; + + NEO::ZebinSections zebinSections; + auto extractErr = NEO::extractZebinSections(elf, zebinSections, errors, warnings); + ASSERT_EQ(NEO::DecodeError::Success, extractErr) << errors << " " << warnings; + + auto &kernelNode = *parser.createChildrenRange(*parser.findNodeWithKeyDfs("kernels")).begin(); + auto res = NEO::populateKernelDescriptor(programInfo, elf, zebinSections, parser, kernelNode, errors, warnings); + EXPECT_EQ(NEO::DecodeError::Success, res); + ASSERT_EQ(1u, programInfo.kernelInfos.size()); + ASSERT_EQ(1u, programInfo.kernelInfos[0]->kernelDescriptor.payloadMappings.explicitArgs.size()); + const auto &arg = programInfo.kernelInfos[0]->kernelDescriptor.payloadMappings.explicitArgs[0].as(); + EXPECT_EQ(8, arg.requiredSlmAlignment); +} + TEST(PopulateArgDescriptorCrossthreadPalyoad, GivenArgTypeEnqueuedLocalSizeWhenArgSizeValidThenPopulatesKernelDescriptor) { uint32_t vectorSizes[] = {4, 8, 12};