zebin: add support for kernels source attributes
This commit adds parsing of "user_attributes" section of zeInfo containing kernel's language attributes. Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
parent
9c82238c1e
commit
5af2bc8a60
|
@ -11,8 +11,10 @@
|
||||||
#include "shared/source/device_binary_format/elf/elf_decoder.h"
|
#include "shared/source/device_binary_format/elf/elf_decoder.h"
|
||||||
#include "shared/source/utilities/const_stringref.h"
|
#include "shared/source/utilities/const_stringref.h"
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <array>
|
||||||
#include <stddef.h>
|
#include <cinttypes>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace NEO {
|
namespace NEO {
|
||||||
|
|
||||||
|
@ -120,6 +122,7 @@ constexpr ConstStringRef globalHostAccessTable("global_host_access_table");
|
||||||
constexpr ConstStringRef functions("functions");
|
constexpr ConstStringRef functions("functions");
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
constexpr ConstStringRef attributes("user_attributes");
|
||||||
constexpr ConstStringRef name("name");
|
constexpr ConstStringRef name("name");
|
||||||
constexpr ConstStringRef executionEnv("execution_env");
|
constexpr ConstStringRef executionEnv("execution_env");
|
||||||
constexpr ConstStringRef debugEnv("debug_env");
|
constexpr ConstStringRef debugEnv("debug_env");
|
||||||
|
@ -159,6 +162,16 @@ constexpr ConstStringRef roundRobinStall("round_robin_stall");
|
||||||
} // namespace ThreadSchedulingMode
|
} // namespace ThreadSchedulingMode
|
||||||
} // namespace ExecutionEnv
|
} // namespace ExecutionEnv
|
||||||
|
|
||||||
|
namespace Attributes {
|
||||||
|
constexpr ConstStringRef intelReqdSubgroupSize("intel_reqd_sub_group_size");
|
||||||
|
constexpr ConstStringRef intelReqdWorkgroupWalkOrder("intel_reqd_workgroup_walk_order");
|
||||||
|
constexpr ConstStringRef reqdWorkgroupSize("reqd_work_group_size");
|
||||||
|
constexpr ConstStringRef invalidKernel("invalid_kernel");
|
||||||
|
constexpr ConstStringRef vecTypeHint("vec_type_hint");
|
||||||
|
constexpr ConstStringRef workgroupSizeHint("work_group_size_hint");
|
||||||
|
constexpr ConstStringRef hintSuffix("_hint");
|
||||||
|
} // namespace Attributes
|
||||||
|
|
||||||
namespace DebugEnv {
|
namespace DebugEnv {
|
||||||
constexpr ConstStringRef debugSurfaceBTI("sip_surface_bti");
|
constexpr ConstStringRef debugSurfaceBTI("sip_surface_bti");
|
||||||
} // namespace DebugEnv
|
} // namespace DebugEnv
|
||||||
|
@ -429,6 +442,32 @@ struct ExperimentalPropertiesBaseT {
|
||||||
|
|
||||||
} // namespace ExecutionEnv
|
} // namespace ExecutionEnv
|
||||||
|
|
||||||
|
namespace Attributes {
|
||||||
|
using IntelReqdSubgroupSizeT = int32_t;
|
||||||
|
using IntelReqdWorkgroupWalkOrder = std::array<int32_t, 3>;
|
||||||
|
using ReqdWorkgroupSizeT = std::array<int32_t, 3>;
|
||||||
|
using InvalidKernelT = ConstStringRef;
|
||||||
|
using WorkgroupSizeHint = std::array<int32_t, 3>;
|
||||||
|
using VecTypeHintT = ConstStringRef;
|
||||||
|
|
||||||
|
namespace Defaults {
|
||||||
|
constexpr IntelReqdSubgroupSizeT intelReqdSubgroupSize = 0;
|
||||||
|
constexpr IntelReqdWorkgroupWalkOrder intelReqdWorkgroupWalkOrder = {0, 0, 0};
|
||||||
|
constexpr ReqdWorkgroupSizeT reqdWorkgroupSize = {0, 0, 0};
|
||||||
|
constexpr WorkgroupSizeHint workgroupSizeHint = {0, 0, 0};
|
||||||
|
} // namespace Defaults
|
||||||
|
|
||||||
|
struct AttributesBaseT {
|
||||||
|
std::optional<IntelReqdSubgroupSizeT> intelReqdSubgroupSize;
|
||||||
|
std::optional<IntelReqdWorkgroupWalkOrder> intelReqdWorkgroupWalkOrder;
|
||||||
|
std::optional<ReqdWorkgroupSizeT> reqdWorkgroupSize;
|
||||||
|
std::optional<InvalidKernelT> invalidKernel;
|
||||||
|
std::optional<WorkgroupSizeHint> workgroupSizeHint;
|
||||||
|
std::optional<VecTypeHintT> vecTypeHint;
|
||||||
|
std::vector<std::pair<ConstStringRef, ConstStringRef>> otherHints;
|
||||||
|
};
|
||||||
|
} // namespace Attributes
|
||||||
|
|
||||||
namespace DebugEnv {
|
namespace DebugEnv {
|
||||||
using DebugSurfaceBTIT = int32_t;
|
using DebugSurfaceBTIT = int32_t;
|
||||||
|
|
||||||
|
|
|
@ -251,6 +251,8 @@ void extractZeInfoKernelSections(const NEO::Yaml::YamlParser &parser, const NEO:
|
||||||
auto key = parser.readKey(kernelMetadataNd);
|
auto key = parser.readKey(kernelMetadataNd);
|
||||||
if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::name == key) {
|
if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::name == key) {
|
||||||
outZeInfoKernelSections.nameNd.push_back(&kernelMetadataNd);
|
outZeInfoKernelSections.nameNd.push_back(&kernelMetadataNd);
|
||||||
|
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::attributes == key) {
|
||||||
|
outZeInfoKernelSections.attributesNd.push_back(&kernelMetadataNd);
|
||||||
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::executionEnv == key) {
|
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::executionEnv == key) {
|
||||||
outZeInfoKernelSections.executionEnvNd.push_back(&kernelMetadataNd);
|
outZeInfoKernelSections.executionEnvNd.push_back(&kernelMetadataNd);
|
||||||
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::debugEnv == key) {
|
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::debugEnv == key) {
|
||||||
|
@ -274,6 +276,7 @@ void extractZeInfoKernelSections(const NEO::Yaml::YamlParser &parser, const NEO:
|
||||||
DecodeError validateZeInfoKernelSectionsCount(const ZeInfoKernelSections &outZeInfoKernelSections, std::string &outErrReason, std::string &outWarning) {
|
DecodeError validateZeInfoKernelSectionsCount(const ZeInfoKernelSections &outZeInfoKernelSections, std::string &outErrReason, std::string &outWarning) {
|
||||||
bool valid = validateZebinSectionsCountExactly(outZeInfoKernelSections.nameNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::name, 1U, outErrReason, outWarning);
|
bool valid = validateZebinSectionsCountExactly(outZeInfoKernelSections.nameNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::name, 1U, outErrReason, outWarning);
|
||||||
valid &= validateZebinSectionsCountExactly(outZeInfoKernelSections.executionEnvNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::executionEnv, 1U, outErrReason, outWarning);
|
valid &= validateZebinSectionsCountExactly(outZeInfoKernelSections.executionEnvNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::executionEnv, 1U, outErrReason, outWarning);
|
||||||
|
valid &= validateZebinSectionsCountAtMost(outZeInfoKernelSections.attributesNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::attributes, 1U, outErrReason, outWarning);
|
||||||
valid &= validateZebinSectionsCountAtMost(outZeInfoKernelSections.debugEnvNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::debugEnv, 1U, outErrReason, outWarning);
|
valid &= validateZebinSectionsCountAtMost(outZeInfoKernelSections.debugEnvNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::debugEnv, 1U, outErrReason, outWarning);
|
||||||
valid &= validateZebinSectionsCountAtMost(outZeInfoKernelSections.payloadArgumentsNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::payloadArguments, 1U, outErrReason, outWarning);
|
valid &= validateZebinSectionsCountAtMost(outZeInfoKernelSections.payloadArgumentsNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::payloadArguments, 1U, outErrReason, outWarning);
|
||||||
valid &= validateZebinSectionsCountAtMost(outZeInfoKernelSections.perThreadPayloadArgumentsNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::perThreadPayloadArguments, 1U, outErrReason, outWarning);
|
valid &= validateZebinSectionsCountAtMost(outZeInfoKernelSections.perThreadPayloadArgumentsNd, NEO::Elf::ZebinKernelMetadata::Tags::Kernel::perThreadPayloadArguments, 1U, outErrReason, outWarning);
|
||||||
|
@ -294,7 +297,7 @@ bool readZeInfoValueChecked(const NEO::Yaml::YamlParser &parser, const NEO::Yaml
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename DestinationT, size_t Len>
|
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) {
|
bool readZeInfoValueCollectionCheckedArr(std::array<DestinationT, Len> &vec, const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node, ConstStringRef context, std::string &outErrReason) {
|
||||||
auto collectionNodes = parser.createChildrenRange(node);
|
auto collectionNodes = parser.createChildrenRange(node);
|
||||||
size_t index = 0U;
|
size_t index = 0U;
|
||||||
bool isValid = true;
|
bool isValid = true;
|
||||||
|
@ -310,6 +313,12 @@ bool readZeInfoValueCollectionChecked(DestinationT (&vec)[Len], const NEO::Yaml:
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 &array = reinterpret_cast<std::array<DestinationT, Len> &>(vec);
|
||||||
|
return readZeInfoValueCollectionCheckedArr(array, parser, node, context, outErrReason);
|
||||||
|
}
|
||||||
|
|
||||||
DecodeError readZeInfoExecutionEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
DecodeError readZeInfoExecutionEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
||||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::ExecutionEnv::ExecutionEnvBaseT &outExecEnv,
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::ExecutionEnv::ExecutionEnvBaseT &outExecEnv,
|
||||||
ConstStringRef context,
|
ConstStringRef context,
|
||||||
|
@ -368,6 +377,37 @@ DecodeError readZeInfoExecutionEnvironment(const NEO::Yaml::YamlParser &parser,
|
||||||
return validExecEnv ? DecodeError::Success : DecodeError::InvalidBinary;
|
return validExecEnv ? DecodeError::Success : DecodeError::InvalidBinary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DecodeError readZeInfoAttributes(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node, NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes::AttributesBaseT &outAttributes, ConstStringRef context, std::string &outErrReason, std::string &outWarning) {
|
||||||
|
namespace AttributeTypes = NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes;
|
||||||
|
bool validAttributes = true;
|
||||||
|
for (const auto &attributesMetadataNd : parser.createChildrenRange(node)) {
|
||||||
|
auto key = parser.readKey(attributesMetadataNd);
|
||||||
|
if (key == NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes::intelReqdSubgroupSize) {
|
||||||
|
outAttributes.intelReqdSubgroupSize = AttributeTypes::Defaults::intelReqdSubgroupSize;
|
||||||
|
validAttributes &= readZeInfoValueChecked(parser, attributesMetadataNd, *outAttributes.intelReqdSubgroupSize, context, outErrReason);
|
||||||
|
} else if (key == NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes::intelReqdWorkgroupWalkOrder) {
|
||||||
|
outAttributes.intelReqdWorkgroupWalkOrder = AttributeTypes::Defaults::intelReqdWorkgroupWalkOrder;
|
||||||
|
validAttributes &= readZeInfoValueCollectionCheckedArr(*outAttributes.intelReqdWorkgroupWalkOrder, parser, attributesMetadataNd, context, outErrReason);
|
||||||
|
} else if (key == NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes::reqdWorkgroupSize) {
|
||||||
|
outAttributes.reqdWorkgroupSize = AttributeTypes::Defaults::reqdWorkgroupSize;
|
||||||
|
validAttributes &= readZeInfoValueCollectionCheckedArr(*outAttributes.reqdWorkgroupSize, parser, attributesMetadataNd, context, outErrReason);
|
||||||
|
} else if (key == NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes::workgroupSizeHint) {
|
||||||
|
outAttributes.workgroupSizeHint = AttributeTypes::Defaults::workgroupSizeHint;
|
||||||
|
validAttributes &= readZeInfoValueCollectionCheckedArr(*outAttributes.workgroupSizeHint, parser, attributesMetadataNd, context, outErrReason);
|
||||||
|
} else if (key == NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes::invalidKernel) {
|
||||||
|
outAttributes.invalidKernel = parser.readValue(attributesMetadataNd);
|
||||||
|
} else if (key == NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes::vecTypeHint) {
|
||||||
|
outAttributes.vecTypeHint = parser.readValue(attributesMetadataNd);
|
||||||
|
} else if (key.contains(NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes::hintSuffix.data())) {
|
||||||
|
outAttributes.otherHints.push_back({key, parser.readValue(attributesMetadataNd)});
|
||||||
|
} else {
|
||||||
|
outErrReason.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unknown attribute entry \"" + key.str() + "\" in context of " + context.str() + "\n");
|
||||||
|
validAttributes = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return validAttributes ? DecodeError::Success : DecodeError::InvalidBinary;
|
||||||
|
}
|
||||||
|
|
||||||
DecodeError readZeInfoDebugEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
DecodeError readZeInfoDebugEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
||||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::DebugEnv::DebugEnvBaseT &outDebugEnv,
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::DebugEnv::DebugEnvBaseT &outDebugEnv,
|
||||||
ConstStringRef context,
|
ConstStringRef context,
|
||||||
|
@ -1034,6 +1074,15 @@ NEO::DecodeError populateKernelDescriptor(NEO::ProgramInfo &dst, NEO::Elf::Elf<N
|
||||||
return execEnvErr;
|
return execEnvErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes::AttributesBaseT attributes;
|
||||||
|
if (false == zeInfokernelSections.attributesNd.empty()) {
|
||||||
|
auto attributeErr = readZeInfoAttributes(yamlParser, *zeInfokernelSections.attributesNd[0], attributes, kernelInfo->kernelDescriptor.kernelMetadata.kernelName, outErrReason, outWarning);
|
||||||
|
if (DecodeError::Success != attributeErr) {
|
||||||
|
return attributeErr;
|
||||||
|
}
|
||||||
|
populateKernelSourceAttributes(kernelDescriptor, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::DebugEnv::DebugEnvBaseT debugEnv;
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::DebugEnv::DebugEnvBaseT debugEnv;
|
||||||
if (false == zeInfokernelSections.debugEnvNd.empty()) {
|
if (false == zeInfokernelSections.debugEnvNd.empty()) {
|
||||||
auto debugEnvErr = readZeInfoDebugEnvironment(yamlParser, *zeInfokernelSections.debugEnvNd[0], debugEnv, kernelInfo->kernelDescriptor.kernelMetadata.kernelName, outErrReason, outWarning);
|
auto debugEnvErr = readZeInfoDebugEnvironment(yamlParser, *zeInfokernelSections.debugEnvNd[0], debugEnv, kernelInfo->kernelDescriptor.kernelMetadata.kernelName, outErrReason, outWarning);
|
||||||
|
@ -1328,6 +1377,48 @@ NEO::DecodeError populateExternalFunctionsMetadata(NEO::ProgramInfo &dst, NEO::Y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string attributeToString(const int32_t &attribute) {
|
||||||
|
return std::to_string(attribute);
|
||||||
|
}
|
||||||
|
std::string attributeToString(const std::array<int32_t, 3> &attribute) {
|
||||||
|
return std::to_string(attribute[0]) + ", " + std::to_string(attribute[1]) + ", " + std::to_string(attribute[2]);
|
||||||
|
}
|
||||||
|
std::string attributeToString(ConstStringRef attribute) {
|
||||||
|
return attribute.str();
|
||||||
|
}
|
||||||
|
void appendAttribute(std::string &dst, const std::string &attributeName, const std::string &attributeValue) {
|
||||||
|
if (dst.empty() == false) {
|
||||||
|
dst.append(" ");
|
||||||
|
}
|
||||||
|
dst.append(attributeName + "(" + attributeValue + ")");
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void appendAttributeIfSet(std::string &dst, ConstStringRef attributeName, std::optional<T> &attributeValue) {
|
||||||
|
if (attributeValue) {
|
||||||
|
appendAttribute(dst, attributeName.str(), attributeToString(*attributeValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NEO::DecodeError populateKernelSourceAttributes(NEO::KernelDescriptor &dst, NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes::AttributesBaseT &attributes) {
|
||||||
|
namespace AttributeTags = NEO::Elf::ZebinKernelMetadata::Tags::Kernel::Attributes;
|
||||||
|
namespace AttributeTypes = NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes;
|
||||||
|
auto &languageAttributes = dst.kernelMetadata.kernelLanguageAttributes;
|
||||||
|
|
||||||
|
for (auto &hint : attributes.otherHints) {
|
||||||
|
appendAttribute(languageAttributes, hint.first.str(), hint.second.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
appendAttributeIfSet(languageAttributes, AttributeTags::intelReqdSubgroupSize, attributes.intelReqdSubgroupSize);
|
||||||
|
appendAttributeIfSet(languageAttributes, AttributeTags::intelReqdWorkgroupWalkOrder, attributes.intelReqdWorkgroupWalkOrder);
|
||||||
|
appendAttributeIfSet(languageAttributes, AttributeTags::reqdWorkgroupSize, attributes.reqdWorkgroupSize);
|
||||||
|
appendAttributeIfSet(languageAttributes, AttributeTags::workgroupSizeHint, attributes.workgroupSizeHint);
|
||||||
|
appendAttributeIfSet(languageAttributes, AttributeTags::vecTypeHint, attributes.vecTypeHint);
|
||||||
|
appendAttributeIfSet(languageAttributes, AttributeTags::invalidKernel, attributes.invalidKernel);
|
||||||
|
dst.kernelAttributes.flags.isInvalid = attributes.invalidKernel.has_value();
|
||||||
|
|
||||||
|
return DecodeError::Success;
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
DecodeError decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ProgramInfo &dst, const SingleDeviceBinary &src, std::string &outErrReason, std::string &outWarning) {
|
DecodeError decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ProgramInfo &dst, const SingleDeviceBinary &src, std::string &outErrReason, std::string &outWarning) {
|
||||||
auto elf = Elf::decodeElf<Elf::EI_CLASS_64>(src.deviceBinary, outErrReason, outWarning);
|
auto elf = Elf::decodeElf<Elf::EI_CLASS_64>(src.deviceBinary, outErrReason, outWarning);
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct ZebinSections {
|
||||||
|
|
||||||
using UniqueNode = StackVec<const NEO::Yaml::Node *, 1>;
|
using UniqueNode = StackVec<const NEO::Yaml::Node *, 1>;
|
||||||
struct ZeInfoKernelSections {
|
struct ZeInfoKernelSections {
|
||||||
|
UniqueNode attributesNd;
|
||||||
UniqueNode nameNd;
|
UniqueNode nameNd;
|
||||||
UniqueNode executionEnvNd;
|
UniqueNode executionEnvNd;
|
||||||
UniqueNode debugEnvNd;
|
UniqueNode debugEnvNd;
|
||||||
|
@ -56,6 +57,9 @@ DecodeError validateZeInfoKernelSectionsCount(const ZeInfoKernelSections &outZeI
|
||||||
DecodeError readZeInfoExecutionEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
DecodeError readZeInfoExecutionEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
||||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::ExecutionEnv::ExecutionEnvBaseT &outExecEnv,
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::ExecutionEnv::ExecutionEnvBaseT &outExecEnv,
|
||||||
ConstStringRef context, std::string &outErrReason, std::string &outWarning);
|
ConstStringRef context, std::string &outErrReason, std::string &outWarning);
|
||||||
|
DecodeError readZeInfoAttributes(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
||||||
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes::AttributesBaseT &outAttributes,
|
||||||
|
ConstStringRef context, std::string &outErrReason, std::string &outWarning);
|
||||||
DecodeError readZeInfoDebugEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
DecodeError readZeInfoDebugEnvironment(const NEO::Yaml::YamlParser &parser, const NEO::Yaml::Node &node,
|
||||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::DebugEnv::DebugEnvBaseT &outDebugEnv,
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::DebugEnv::DebugEnvBaseT &outDebugEnv,
|
||||||
ConstStringRef context,
|
ConstStringRef context,
|
||||||
|
@ -115,4 +119,6 @@ NEO::DecodeError readZeInfoVersionFromZeInfo(NEO::Elf::ZebinKernelMetadata::Type
|
||||||
NEO::DecodeError populateZeInfoVersion(NEO::Elf::ZebinKernelMetadata::Types::Version &dst, ConstStringRef &versionStr, std::string &outErrReason);
|
NEO::DecodeError populateZeInfoVersion(NEO::Elf::ZebinKernelMetadata::Types::Version &dst, ConstStringRef &versionStr, std::string &outErrReason);
|
||||||
|
|
||||||
NEO::DecodeError populateExternalFunctionsMetadata(NEO::ProgramInfo &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &functionNd, std::string &outErrReason, std::string &outWarning);
|
NEO::DecodeError populateExternalFunctionsMetadata(NEO::ProgramInfo &dst, NEO::Yaml::YamlParser &yamlParser, const NEO::Yaml::Node &functionNd, std::string &outErrReason, std::string &outWarning);
|
||||||
|
|
||||||
|
NEO::DecodeError populateKernelSourceAttributes(NEO::KernelDescriptor &dst, NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes::AttributesBaseT &attributes);
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|
|
@ -1124,6 +1124,51 @@ kernels:
|
||||||
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());
|
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(ReadZeInfoAttributes, GivenValidYamlEntriesThenSetProperMembers) {
|
||||||
|
NEO::ConstStringRef yaml = R"===(---
|
||||||
|
kernels:
|
||||||
|
- name: some_kernel
|
||||||
|
user_attributes:
|
||||||
|
intel_reqd_sub_group_size: 16
|
||||||
|
intel_reqd_workgroup_walk_order: [0, 1, 2]
|
||||||
|
reqd_work_group_size: [256, 2, 1]
|
||||||
|
vec_type_hint: uint
|
||||||
|
work_group_size_hint: [256, 2, 1]
|
||||||
|
new_user_hint: new_user_hint_value
|
||||||
|
invalid_kernel: invalid_kernel_reason
|
||||||
|
...
|
||||||
|
)===";
|
||||||
|
|
||||||
|
std::string parserErrors;
|
||||||
|
std::string parserWarnings;
|
||||||
|
NEO::Yaml::YamlParser parser;
|
||||||
|
bool success = parser.parse(yaml, parserErrors, parserWarnings);
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
auto &attributeNd = *parser.findNodeWithKeyDfs(NEO::Elf::ZebinKernelMetadata::Tags::Kernel::attributes);
|
||||||
|
std::string errors;
|
||||||
|
std::string warnings;
|
||||||
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes::AttributesBaseT attributes;
|
||||||
|
auto err = NEO::readZeInfoAttributes(parser, attributeNd, attributes, "some_kernel", errors, warnings);
|
||||||
|
EXPECT_EQ(NEO::DecodeError::Success, err);
|
||||||
|
EXPECT_TRUE(warnings.empty()) << warnings;
|
||||||
|
EXPECT_TRUE(errors.empty()) << errors;
|
||||||
|
EXPECT_EQ(16, attributes.intelReqdSubgroupSize.value());
|
||||||
|
EXPECT_EQ(0, attributes.intelReqdWorkgroupWalkOrder.value()[0]);
|
||||||
|
EXPECT_EQ(1, attributes.intelReqdWorkgroupWalkOrder.value()[1]);
|
||||||
|
EXPECT_EQ(2, attributes.intelReqdWorkgroupWalkOrder.value()[2]);
|
||||||
|
EXPECT_EQ(256, attributes.reqdWorkgroupSize.value()[0]);
|
||||||
|
EXPECT_EQ(2, attributes.reqdWorkgroupSize.value()[1]);
|
||||||
|
EXPECT_EQ(1, attributes.reqdWorkgroupSize.value()[2]);
|
||||||
|
EXPECT_TRUE(equals(attributes.vecTypeHint.value(), "uint"));
|
||||||
|
EXPECT_EQ(256, attributes.workgroupSizeHint.value()[0]);
|
||||||
|
EXPECT_EQ(2, attributes.workgroupSizeHint.value()[1]);
|
||||||
|
EXPECT_EQ(1, attributes.workgroupSizeHint.value()[2]);
|
||||||
|
ASSERT_EQ(1U, attributes.otherHints.size());
|
||||||
|
EXPECT_TRUE(equals(attributes.otherHints[0].first, "new_user_hint"));
|
||||||
|
EXPECT_TRUE(equals(attributes.otherHints[0].second, "new_user_hint_value"));
|
||||||
|
EXPECT_TRUE(equals(attributes.invalidKernel.value(), "invalid_kernel_reason"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ReadZeInfoDebugEnvironment, givenValidYamlEntryThenSetProperMembers) {
|
TEST(ReadZeInfoDebugEnvironment, givenValidYamlEntryThenSetProperMembers) {
|
||||||
NEO::ConstStringRef yaml = R"===(---
|
NEO::ConstStringRef yaml = R"===(---
|
||||||
kernels:
|
kernels:
|
||||||
|
@ -1452,6 +1497,90 @@ kernels:
|
||||||
EXPECT_STREQ("Missing source offset value for element in argByValue\n", errors.c_str());
|
EXPECT_STREQ("Missing source offset value for element in argByValue\n", errors.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PopulateKernelDescriptor, GivenKernelAttributesWhenPopulatingKernelDescriptorThenKernelLanguageSourcesAreSetAccordingly) {
|
||||||
|
NEO::ConstStringRef yaml = R"===(---
|
||||||
|
kernels:
|
||||||
|
- name: some_kernel
|
||||||
|
execution_env:
|
||||||
|
simd_size: 8
|
||||||
|
user_attributes:
|
||||||
|
intel_reqd_sub_group_size: 16
|
||||||
|
intel_reqd_workgroup_walk_order: [0, 1, 2]
|
||||||
|
reqd_work_group_size: [256, 2, 1]
|
||||||
|
vec_type_hint: uint
|
||||||
|
work_group_size_hint: [256, 2, 1]
|
||||||
|
new_user_hint: new_user_hint_value
|
||||||
|
...
|
||||||
|
)===";
|
||||||
|
NEO::ProgramInfo programInfo;
|
||||||
|
ZebinTestData::ValidEmptyProgram zebin;
|
||||||
|
NEO::ZebinSections zebinSections;
|
||||||
|
std::string errors, warnings;
|
||||||
|
|
||||||
|
zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "some_kernel", {});
|
||||||
|
auto elf = NEO::Elf::decodeElf(zebin.storage, errors, warnings);
|
||||||
|
ASSERT_NE(nullptr, elf.elfFileHeader) << errors << " " << warnings;
|
||||||
|
|
||||||
|
NEO::Yaml::YamlParser parser;
|
||||||
|
bool parseSuccess = parser.parse(yaml, errors, warnings);
|
||||||
|
ASSERT_TRUE(parseSuccess) << errors << " " << warnings;
|
||||||
|
|
||||||
|
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(warnings.empty()) << warnings;
|
||||||
|
EXPECT_TRUE(errors.empty()) << errors;
|
||||||
|
|
||||||
|
EXPECT_STREQ("new_user_hint(new_user_hint_value) intel_reqd_sub_group_size(16) intel_reqd_workgroup_walk_order(0, 1, 2) reqd_work_group_size(256, 2, 1) work_group_size_hint(256, 2, 1) vec_type_hint(uint)", programInfo.kernelInfos[0]->kernelDescriptor.kernelMetadata.kernelLanguageAttributes.c_str());
|
||||||
|
EXPECT_FALSE(programInfo.kernelInfos[0]->kernelDescriptor.kernelAttributes.flags.isInvalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PopulateKernelSourceAttributes, GivenInvalidKernelAttributeWhenPopulatingKernelSourceAttributesThenKernelIsInvalidFlagIsSet) {
|
||||||
|
NEO::KernelDescriptor kd;
|
||||||
|
NEO::Elf::ZebinKernelMetadata::Types::Kernel::Attributes::AttributesBaseT attributes;
|
||||||
|
attributes.invalidKernel = "reason";
|
||||||
|
auto err = populateKernelSourceAttributes(kd, attributes);
|
||||||
|
EXPECT_EQ(NEO::DecodeError::Success, err);
|
||||||
|
EXPECT_TRUE(kd.kernelAttributes.flags.isInvalid);
|
||||||
|
EXPECT_STREQ("invalid_kernel(reason)", kd.kernelMetadata.kernelLanguageAttributes.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PopulateKernelDescriptor, GivenUnknownAttributeWhenPopulatingKernelDescriptorThenErrorIsReturned) {
|
||||||
|
NEO::ConstStringRef yaml = R"===(---
|
||||||
|
kernels:
|
||||||
|
- name: some_kernel
|
||||||
|
execution_env:
|
||||||
|
simd_size: 8
|
||||||
|
user_attributes:
|
||||||
|
unknown_attribute: unkown_attribute_value
|
||||||
|
...
|
||||||
|
)===";
|
||||||
|
NEO::ProgramInfo programInfo;
|
||||||
|
ZebinTestData::ValidEmptyProgram zebin;
|
||||||
|
NEO::ZebinSections zebinSections;
|
||||||
|
std::string errors, warnings;
|
||||||
|
|
||||||
|
zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "some_kernel", {});
|
||||||
|
auto elf = NEO::Elf::decodeElf(zebin.storage, errors, warnings);
|
||||||
|
ASSERT_NE(nullptr, elf.elfFileHeader) << errors << " " << warnings;
|
||||||
|
|
||||||
|
NEO::Yaml::YamlParser parser;
|
||||||
|
bool parseSuccess = parser.parse(yaml, errors, warnings);
|
||||||
|
ASSERT_TRUE(parseSuccess) << errors << " " << warnings;
|
||||||
|
|
||||||
|
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::InvalidBinary, err);
|
||||||
|
EXPECT_TRUE(warnings.empty()) << warnings;
|
||||||
|
EXPECT_STREQ("DeviceBinaryFormat::Zebin::.ze_info : Unknown attribute entry \"unknown_attribute\" in context of some_kernel\n", errors.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ReadZeInfoEnumChecked, GivenInvalidNodeThenFail) {
|
TEST(ReadZeInfoEnumChecked, GivenInvalidNodeThenFail) {
|
||||||
using ArgType = NEO::Zebin::ZeInfo::EnumLookup::ArgType::ArgType;
|
using ArgType = NEO::Zebin::ZeInfo::EnumLookup::ArgType::ArgType;
|
||||||
NEO::Yaml::YamlParser parser;
|
NEO::Yaml::YamlParser parser;
|
||||||
|
|
Loading…
Reference in New Issue