Zebin: Add support for new buffer_address arg type

This change adds support for new "buffer_address" arg type, which adds
buffer address information for stateful-only argument. This will prevent
from generating stateless version of a kernel argument if all its
accesses are to be promoted to the stateful ones.
- Change default value of accessedUsingStatelessAddressingMode flag.

Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
Related-To: NEO-7048
This commit is contained in:
Kacper Nowak
2022-06-03 16:01:33 +00:00
committed by Compute-Runtime-Automation
parent 9bcab12496
commit de75e51228
4 changed files with 67 additions and 8 deletions

View File

@@ -178,6 +178,7 @@ static constexpr ConstStringRef enqueuedLocalSize("enqueued_local_size");
static constexpr ConstStringRef privateBaseStateless("private_base_stateless");
static constexpr ConstStringRef argByvalue("arg_byvalue");
static constexpr ConstStringRef argBypointer("arg_bypointer");
static constexpr ConstStringRef bufferAddress("buffer_address");
static constexpr ConstStringRef bufferOffset("buffer_offset");
static constexpr ConstStringRef printfBuffer("printf_buffer");
static constexpr ConstStringRef workDimensions("work_dimensions");
@@ -377,6 +378,7 @@ enum ArgType : uint8_t {
ArgTypePrivateBaseStateless,
ArgTypeArgByvalue,
ArgTypeArgBypointer,
ArgTypeBufferAddress,
ArgTypeBufferOffset,
ArgTypePrintfBuffer,
ArgTypeWorkDimensions,

View File

@@ -376,6 +376,8 @@ bool readEnumChecked(const Yaml::Token *token, NEO::Elf::ZebinKernelMetadata::Ty
out = ArgTypeT::ArgTypeArgByvalue;
} else if (tokenValue == PayloadArgument::ArgType::argBypointer) {
out = ArgTypeT::ArgTypeArgBypointer;
} else if (tokenValue == PayloadArgument::ArgType::bufferAddress) {
out = ArgTypeT::ArgTypeBufferAddress;
} else if (tokenValue == PayloadArgument::ArgType::bufferOffset) {
out = ArgTypeT::ArgTypeBufferOffset;
} else if (tokenValue == PayloadArgument::ArgType::printfBuffer) {
@@ -824,14 +826,14 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type
}
argTraits.argByValSize = sizeof(void *);
if (dst.payloadMappings.explicitArgs[src.argIndex].is<NEO::ArgDescriptor::ArgTPointer>()) {
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescPointer>().accessedUsingStatelessAddressingMode = false;
}
switch (src.addrmode) {
default:
outErrReason.append("Invalid or missing memory addressing mode for arg idx : " + std::to_string(src.argIndex) + " in context of : " + dst.kernelMetadata.kernelName + ".\n");
return DecodeError::InvalidBinary;
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::MemoryAddressingModeStateful:
if (dst.payloadMappings.explicitArgs[src.argIndex].is<NEO::ArgDescriptor::ArgTPointer>()) {
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescPointer>(true).accessedUsingStatelessAddressingMode = false;
}
break;
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::MemoryAddressingModeStateless:
if (false == dst.payloadMappings.explicitArgs[src.argIndex].is<NEO::ArgDescriptor::ArgTPointer>()) {
@@ -840,6 +842,7 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type
}
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescPointer>(false).stateless = src.offset;
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescPointer>(false).pointerSize = src.size;
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescPointer>(false).accessedUsingStatelessAddressingMode = true;
break;
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::MemoryAddressingModeBindless:
if (dst.payloadMappings.explicitArgs[src.argIndex].is<NEO::ArgDescriptor::ArgTPointer>()) {
@@ -917,6 +920,11 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type
break;
}
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeBufferAddress: {
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescPointer>(true).stateless = src.offset;
break;
}
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeBufferOffset: {
if (4 != src.size) {
outErrReason.append("DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::ArgType::bufferOffset.str() + " in context of : " + dst.kernelMetadata.kernelName + ". Expected 4. Got : " + std::to_string(src.size) + "\n");

View File

@@ -5007,6 +5007,55 @@ TEST(PopulateArgDescriptorCrossthreadPayload, GivenArgTypeBufferOffsetWhenOffset
EXPECT_EQ(8, arg.bufferOffset);
}
TEST(PopulateArgDescriptorCrossthreadPayload, givenPureStatefulArgWithBufferAddressWhenThereIsNoStatelessAccessThenPopulatesKernelDescriptorAndArgIsPureStateful) {
NEO::ConstStringRef zeinfo = R"===(
kernels:
- name : some_kernel
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
- arg_type: buffer_address
offset: 32
arg_index: 0
binding_table_indices:
- bti_value: 0
arg_index: 0
)===";
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 err = NEO::populateKernelDescriptor(programInfo, elf, zebinSections, parser, kernelNode, errors, warnings);
EXPECT_EQ(NEO::DecodeError::Success, err);
EXPECT_TRUE(errors.empty()) << errors;
EXPECT_TRUE(warnings.empty()) << warnings;
ASSERT_EQ(1U, programInfo.kernelInfos[0]->kernelDescriptor.payloadMappings.explicitArgs.size());
const auto &arg = programInfo.kernelInfos[0]->kernelDescriptor.payloadMappings.explicitArgs[0].as<ArgDescPointer>();
EXPECT_EQ(32, arg.stateless);
EXPECT_FALSE(arg.accessedUsingStatelessAddressingMode);
EXPECT_TRUE(arg.isPureStateful());
}
TEST(PopulateArgDescriptorCrossthreadPayload, GivenNoArgsThenPopulatesKernelDescriptor) {
NEO::ConstStringRef zeinfo = R"===(
kernels:

View File

@@ -861,7 +861,7 @@ TEST(KernelDescriptorFromPatchtokens, GivenKernelWithPointerArgumentAndMetadataT
NEO::populateKernelDescriptor(dst, kernelTokens, sizeof(void *));
EXPECT_TRUE(dst.payloadMappings.explicitArgs[0].is<NEO::ArgDescriptor::ArgTPointer>());
EXPECT_TRUE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().bufferOffset));
EXPECT_FALSE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful()));
EXPECT_FALSE(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful());
EXPECT_FALSE(dst.kernelAttributes.flags.usesImages);
EXPECT_FALSE(dst.kernelAttributes.flags.usesSamplers);
}
@@ -874,7 +874,7 @@ TEST(KernelDescriptorFromPatchtokens, GivenKernelWithPointerArgumentAndMetadataT
NEO::populateKernelDescriptor(dst, kernelTokens, sizeof(void *));
EXPECT_TRUE(dst.payloadMappings.explicitArgs[0].is<NEO::ArgDescriptor::ArgTPointer>());
EXPECT_EQ(bufferOffset.Offset, dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().bufferOffset);
EXPECT_FALSE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful()));
EXPECT_FALSE(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful());
kernelTokens.tokens.kernelArgs[0].metadata.buffer.bufferOffset = nullptr;
EXPECT_FALSE(dst.kernelAttributes.flags.usesImages);
EXPECT_FALSE(dst.kernelAttributes.flags.usesSamplers);
@@ -886,7 +886,7 @@ TEST(KernelDescriptorFromPatchtokens, GivenKernelWithPointerArgumentAndMetadataT
NEO::populateKernelDescriptor(dst, kernelTokens, sizeof(void *));
EXPECT_TRUE(dst.payloadMappings.explicitArgs[0].is<NEO::ArgDescriptor::ArgTPointer>());
EXPECT_TRUE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().bufferOffset));
EXPECT_TRUE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful()));
EXPECT_TRUE(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful());
kernelTokens.tokens.kernelArgs[0].metadata.buffer.pureStateful = nullptr;
EXPECT_FALSE(dst.kernelAttributes.flags.usesImages);
EXPECT_FALSE(dst.kernelAttributes.flags.usesSamplers);
@@ -1029,7 +1029,7 @@ TEST(KernelDescriptorFromPatchtokens, GivenKernelWithSlmArgumentAndMetadataThenK
NEO::populateKernelDescriptor(dst, kernelTokens, sizeof(void *));
EXPECT_TRUE(dst.payloadMappings.explicitArgs[0].is<NEO::ArgDescriptor::ArgTPointer>());
EXPECT_TRUE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().bufferOffset));
EXPECT_FALSE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful()));
EXPECT_FALSE(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful());
EXPECT_FALSE(dst.kernelAttributes.flags.usesImages);
EXPECT_FALSE(dst.kernelAttributes.flags.usesSamplers);
EXPECT_TRUE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().bindful));
@@ -1052,7 +1052,7 @@ TEST(KernelDescriptorFromPatchtokens, GivenKernelWithSlmArgumentAndMetadataThenK
NEO::populateKernelDescriptor(dst, kernelTokens, sizeof(void *));
EXPECT_TRUE(dst.payloadMappings.explicitArgs[0].is<NEO::ArgDescriptor::ArgTPointer>());
EXPECT_TRUE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().bufferOffset));
EXPECT_FALSE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful()));
EXPECT_FALSE(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().isPureStateful());
EXPECT_FALSE(dst.kernelAttributes.flags.usesImages);
EXPECT_FALSE(dst.kernelAttributes.flags.usesSamplers);
EXPECT_TRUE(NEO::isUndefinedOffset(dst.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>().bindful));