From 915b80b1df38ae514f28f1c6d6b306af2d5a6089 Mon Sep 17 00:00:00 2001 From: Jaroslaw Chodor Date: Mon, 24 Feb 2020 22:07:46 +0100 Subject: [PATCH] Introducing kernel descriptor Change-Id: I4ce6ebf27a81cf14b055817ebfe76d8427e349ab --- opencl/source/api/api.cpp | 2 +- opencl/source/kernel/CMakeLists.txt | 1 - opencl/source/kernel/dynamic_kernel_info.h | 16 - opencl/source/kernel/kernel.cpp | 10 +- opencl/source/kernel/kernel_info_cl.h | 16 +- opencl/source/program/kernel_arg_info.h | 167 +----- opencl/source/program/kernel_info.cpp | 8 +- opencl/source/program/kernel_info.h | 10 +- .../program/kernel_info_from_patchtokens.cpp | 2 +- opencl/source/utilities/logger.cpp | 2 +- .../cl_set_kernel_arg_svm_pointer_tests.inl | 6 +- opencl/test/unit_test/kernel/CMakeLists.txt | 6 + .../kernel/kernel_arg_info_tests.cpp | 96 ---- .../kernel/kernel_image_arg_tests.cpp | 8 +- .../unit_test/kernel/kernel_info_cl_tests.cpp | 20 +- .../kernel_reflection_surface_tests.cpp | 2 +- opencl/test/unit_test/kernel/kernel_tests.cpp | 6 +- opencl/test/unit_test/mocks/mock_kernel.h | 8 +- .../kernel_info_from_patchtokens_tests.cpp | 10 +- .../unit_test/program/kernel_info_tests.cpp | 8 +- .../unit_test/utilities/file_logger_tests.cpp | 2 +- .../patchtokens_validator.cpp | 4 +- shared/source/kernel/CMakeLists.txt | 5 + shared/source/kernel/debug_data.h | 19 + shared/source/kernel/kernel_arg_descriptor.h | 334 ++++++++++++ shared/source/kernel/kernel_arg_metadata.h | 203 +++++++ shared/source/kernel/kernel_descriptor.cpp | 11 + shared/source/kernel/kernel_descriptor.h | 173 ++++++ shared/source/utilities/stackvec.h | 159 ++++-- shared/test/unit_test/kernel/CMakeLists.txt | 16 + .../kernel/kernel_arg_descriptor_tests.cpp | 515 ++++++++++++++++++ .../kernel/kernel_arg_metadata_tests.cpp | 132 +++++ .../kernel/kernel_descriptor_tests.cpp | 112 ++++ 33 files changed, 1692 insertions(+), 397 deletions(-) delete mode 100644 opencl/source/kernel/dynamic_kernel_info.h create mode 100644 shared/source/kernel/debug_data.h create mode 100644 shared/source/kernel/kernel_arg_descriptor.h create mode 100644 shared/source/kernel/kernel_arg_metadata.h create mode 100644 shared/source/kernel/kernel_descriptor.cpp create mode 100644 shared/source/kernel/kernel_descriptor.h create mode 100644 shared/test/unit_test/kernel/CMakeLists.txt create mode 100644 shared/test/unit_test/kernel/kernel_arg_descriptor_tests.cpp create mode 100644 shared/test/unit_test/kernel/kernel_arg_metadata_tests.cpp create mode 100644 shared/test/unit_test/kernel/kernel_descriptor_tests.cpp diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index a00c05069b..42a3017cca 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -4389,7 +4389,7 @@ cl_int CL_API_CALL clSetKernelArgSVMPointer(cl_kernel kernel, return retVal; } - cl_int kernelArgAddressQualifier = asClKernelArgAddressQualifier(pKernel->getKernelInfo().kernelArgInfo[argIndex].metadata.addressQualifier); + cl_int kernelArgAddressQualifier = asClKernelArgAddressQualifier(pKernel->getKernelInfo().kernelArgInfo[argIndex].metadata.getAddressQualifier()); if ((kernelArgAddressQualifier != CL_KERNEL_ARG_ADDRESS_GLOBAL) && (kernelArgAddressQualifier != CL_KERNEL_ARG_ADDRESS_CONSTANT)) { retVal = CL_INVALID_ARG_VALUE; diff --git a/opencl/source/kernel/CMakeLists.txt b/opencl/source/kernel/CMakeLists.txt index 0862120af3..0341424d7b 100644 --- a/opencl/source/kernel/CMakeLists.txt +++ b/opencl/source/kernel/CMakeLists.txt @@ -6,7 +6,6 @@ set(RUNTIME_SRCS_KERNEL ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_kernel_info.h ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/get_additional_kernel_info.cpp ${CMAKE_CURRENT_SOURCE_DIR}/image_transformer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/image_transformer.h diff --git a/opencl/source/kernel/dynamic_kernel_info.h b/opencl/source/kernel/dynamic_kernel_info.h deleted file mode 100644 index 24b8387865..0000000000 --- a/opencl/source/kernel/dynamic_kernel_info.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2017-2020 Intel Corporation - * - * SPDX-License-Identifier: MIT - * - */ - -#pragma once - -struct DynamicKernelInfo { - char *pCrossThreadData; - size_t crossThreadDataSize; - - char *pSsh; - size_t sshSize; -}; \ No newline at end of file diff --git a/opencl/source/kernel/kernel.cpp b/opencl/source/kernel/kernel.cpp index 1f37bbe608..749a714cd7 100644 --- a/opencl/source/kernel/kernel.cpp +++ b/opencl/source/kernel/kernel.cpp @@ -348,7 +348,7 @@ cl_int Kernel::initialize() { // set the argument handler auto &argInfo = kernelInfo.kernelArgInfo[i]; - if (argInfo.metadata.addressQualifier == KernelArgMetadata::AddressSpaceQualifier::Local) { + if (argInfo.metadata.addressQualifier == KernelArgMetadata::AddrLocal) { kernelArgHandlers[i] = &Kernel::setArgLocal; } else if (argInfo.isAccelerator) { kernelArgHandlers[i] = &Kernel::setArgAccelerator; @@ -528,13 +528,13 @@ cl_int Kernel::getArgInfo(cl_uint argIndx, cl_kernel_arg_info paramName, size_t switch (paramName) { case CL_KERNEL_ARG_ADDRESS_QUALIFIER: - addressQualifier = asClKernelArgAddressQualifier(argInfo.metadata.addressQualifier); + addressQualifier = asClKernelArgAddressQualifier(argInfo.metadata.getAddressQualifier()); srcSize = sizeof(addressQualifier); pSrc = &addressQualifier; break; case CL_KERNEL_ARG_ACCESS_QUALIFIER: - accessQualifier = asClKernelArgAccessQualifier(argInfo.metadata.accessQualifier); + accessQualifier = asClKernelArgAccessQualifier(argInfo.metadata.getAccessQualifier()); srcSize = sizeof(accessQualifier); pSrc = &accessQualifier; break; @@ -2307,8 +2307,8 @@ cl_int Kernel::checkCorrectImageAccessQualifier(cl_uint argIndex, if (pMemObj) { auto accessQualifier = getKernelInfo().kernelArgInfo[argIndex].metadata.accessQualifier; cl_mem_flags flags = pMemObj->getMemoryPropertiesFlags(); - if ((accessQualifier == KernelArgMetadata::AccessQualifier::ReadOnly && ((flags | CL_MEM_WRITE_ONLY) == flags)) || - (accessQualifier == KernelArgMetadata::AccessQualifier::WriteOnly && ((flags | CL_MEM_READ_ONLY) == flags))) { + if ((accessQualifier == KernelArgMetadata::AccessReadOnly && ((flags | CL_MEM_WRITE_ONLY) == flags)) || + (accessQualifier == KernelArgMetadata::AccessWriteOnly && ((flags | CL_MEM_READ_ONLY) == flags))) { return CL_INVALID_ARG_VALUE; } } else { diff --git a/opencl/source/kernel/kernel_info_cl.h b/opencl/source/kernel/kernel_info_cl.h index 3ab4524004..2828912682 100644 --- a/opencl/source/kernel/kernel_info_cl.h +++ b/opencl/source/kernel/kernel_info_cl.h @@ -18,13 +18,13 @@ constexpr cl_kernel_arg_access_qualifier asClKernelArgAccessQualifier(KernelArgM switch (accessQualifier) { default: return 0U; - case AccessQualifier::None: + case AccessNone: return CL_KERNEL_ARG_ACCESS_NONE; - case AccessQualifier::ReadOnly: + case AccessReadOnly: return CL_KERNEL_ARG_ACCESS_READ_ONLY; - case AccessQualifier::WriteOnly: + case AccessWriteOnly: return CL_KERNEL_ARG_ACCESS_WRITE_ONLY; - case AccessQualifier::ReadWrite: + case AccessReadWrite: return CL_KERNEL_ARG_ACCESS_READ_WRITE; } } @@ -34,13 +34,13 @@ constexpr cl_kernel_arg_address_qualifier asClKernelArgAddressQualifier(KernelAr switch (addressQualifier) { default: return 0U; - case AddressSpaceQualifier::Global: + case AddrGlobal: return CL_KERNEL_ARG_ADDRESS_GLOBAL; - case AddressSpaceQualifier::Local: + case AddrLocal: return CL_KERNEL_ARG_ADDRESS_LOCAL; - case AddressSpaceQualifier::Private: + case AddrPrivate: return CL_KERNEL_ARG_ADDRESS_PRIVATE; - case AddressSpaceQualifier::Constant: + case AddrConstant: return CL_KERNEL_ARG_ADDRESS_CONSTANT; } } diff --git a/opencl/source/program/kernel_arg_info.h b/opencl/source/program/kernel_arg_info.h index 49fcbcefb8..41e2431c7c 100644 --- a/opencl/source/program/kernel_arg_info.h +++ b/opencl/source/program/kernel_arg_info.h @@ -8,6 +8,7 @@ #pragma once #include "shared/source/compiler_interface/compiler_options/compiler_options_base.h" +#include "shared/source/kernel/kernel_arg_descriptor.h" #include "shared/source/utilities/const_stringref.h" #include @@ -17,170 +18,6 @@ namespace NEO { -namespace KernelArgMetadata { - -enum class AccessQualifier : uint8_t { - Unknown, - None, - ReadOnly, - WriteOnly, - ReadWrite, -}; - -namespace AccessQualifierStrings { -constexpr ConstStringRef none = "NONE"; -constexpr ConstStringRef readOnly = "read_only"; -constexpr ConstStringRef writeOnly = "write_only"; -constexpr ConstStringRef readWrite = "read_write"; -constexpr ConstStringRef underscoreReadOnly = "__read_only"; -constexpr ConstStringRef underscoreWriteOnly = "__write_only"; -constexpr ConstStringRef underscoreReadWrite = "__read_write"; -} // namespace AccessQualifierStrings - -enum class AddressSpaceQualifier : uint8_t { - Unknown, - Global, - Local, - Private, - Constant -}; - -namespace AddressSpaceQualifierStrings { -constexpr ConstStringRef addrGlobal = "__global"; -constexpr ConstStringRef addrLocal = "__local"; -constexpr ConstStringRef addrPrivate = "__private"; -constexpr ConstStringRef addrConstant = "__constant"; -constexpr ConstStringRef addrNotSpecified = "not_specified"; -} // namespace AddressSpaceQualifierStrings - -constexpr AccessQualifier parseAccessQualifier(ConstStringRef str) { - using namespace AccessQualifierStrings; - if (str.empty() || (none == str)) { - return AccessQualifier::None; - } - - if (str.length() < 3) { - return AccessQualifier::Unknown; - } - - ConstStringRef strNoUnderscore = ('_' == str[0]) ? ConstStringRef(str.data() + 2, str.length() - 2) : str; - static_assert(writeOnly[0] != readOnly[0], ""); - static_assert(writeOnly[0] != readWrite[0], ""); - if (strNoUnderscore[0] == writeOnly[0]) { - return (writeOnly == strNoUnderscore) ? AccessQualifier::WriteOnly : AccessQualifier::Unknown; - } - - if (readOnly == strNoUnderscore) { - return AccessQualifier::ReadOnly; - } - - return (readWrite == strNoUnderscore) ? AccessQualifier::ReadWrite : AccessQualifier::Unknown; -} - -constexpr AddressSpaceQualifier parseAddressSpace(ConstStringRef str) { - using namespace AddressSpaceQualifierStrings; - if (str.empty()) { - return AddressSpaceQualifier::Global; - } - - if (str.length() < 3) { - return AddressSpaceQualifier::Unknown; - } - - switch (str[2]) { - default: - return AddressSpaceQualifier::Unknown; - case addrNotSpecified[2]: - return (str == addrNotSpecified) ? AddressSpaceQualifier::Private : AddressSpaceQualifier::Unknown; - case addrGlobal[2]: - return (str == addrGlobal) ? AddressSpaceQualifier::Global : AddressSpaceQualifier::Unknown; - case addrLocal[2]: - return (str == addrLocal) ? AddressSpaceQualifier::Local : AddressSpaceQualifier::Unknown; - case addrPrivate[2]: - return (str == addrPrivate) ? AddressSpaceQualifier::Private : AddressSpaceQualifier::Unknown; - case addrConstant[2]: - return (str == addrConstant) ? AddressSpaceQualifier::Constant : AddressSpaceQualifier::Unknown; - } -} - -union TypeQualifiers { - uint8_t packed = 0U; - struct { - bool constQual : 1; - bool volatileQual : 1; - bool restrictQual : 1; - bool pipeQual : 1; - bool unknownQual : 1; - }; - bool empty() const { - return 0U == packed; - } -}; - -namespace TypeQualifierStrings { -constexpr ConstStringRef qualConst = "const"; -constexpr ConstStringRef qualVolatile = "volatile"; -constexpr ConstStringRef qualRestrict = "restrict"; -constexpr ConstStringRef qualPipe = "pipe"; -} // namespace TypeQualifierStrings - -inline TypeQualifiers parseTypeQualifiers(ConstStringRef str) { - using namespace TypeQualifierStrings; - TypeQualifiers ret = {}; - auto tokenized = CompilerOptions::tokenize(str); - for (const auto &tok : tokenized) { - bool knownQualifier = true; - switch (tok[0]) { - default: - knownQualifier = false; - break; - case qualConst[0]: - knownQualifier = (qualConst == tok); - ret.constQual |= knownQualifier; - break; - case qualVolatile[0]: - knownQualifier = (qualVolatile == tok); - ret.volatileQual |= knownQualifier; - break; - case qualRestrict[0]: - knownQualifier = (qualRestrict == tok); - ret.restrictQual |= knownQualifier; - break; - case qualPipe[0]: - knownQualifier = (qualPipe == tok); - ret.pipeQual |= knownQualifier; - break; - } - ret.unknownQual |= !knownQualifier; - } - return ret; -} - -} // namespace KernelArgMetadata - -inline std::string parseLimitedString(const char *str, size_t maxSize) { - std::string ret{str, str + maxSize}; - size_t minSize = strlen(ret.c_str()); - ret.assign(str, minSize); - return ret; -} - -struct ArgTypeMetadata { - uint32_t argByValSize = 0U; - KernelArgMetadata::AccessQualifier accessQualifier = {}; - KernelArgMetadata::AddressSpaceQualifier addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Global; - KernelArgMetadata::TypeQualifiers typeQualifiers = {}; -}; -static_assert(sizeof(ArgTypeMetadata) <= 8, ""); - -struct ArgTypeMetadataExtended { - std::string argName; - std::string type; - std::string accessQualifier; - std::string addressQualifier; - std::string typeQualifiers; -}; - struct KernelArgPatchInfo { uint32_t crossthreadOffset = 0; uint32_t size = 0; @@ -199,7 +36,7 @@ struct KernelArgInfo { static constexpr uint32_t undefinedOffset = (uint32_t)-1; - ArgTypeMetadata metadata; + ArgTypeTraits metadata; std::unique_ptr metadataExtended; uint32_t slmAlignment = 0; diff --git a/opencl/source/program/kernel_info.cpp b/opencl/source/program/kernel_info.cpp index 7d60eb213d..e84b3a1dd3 100644 --- a/opencl/source/program/kernel_info.cpp +++ b/opencl/source/program/kernel_info.cpp @@ -206,7 +206,7 @@ void KernelInfo::storePatchToken(const SPatchExecutionEnvironment *execEnv) { } } -void KernelInfo::storeArgInfo(uint32_t argNum, ArgTypeMetadata metadata, std::unique_ptr metadataExtended) { +void KernelInfo::storeArgInfo(uint32_t argNum, ArgTypeTraits metadata, std::unique_ptr metadataExtended) { resizeKernelArgInfoAndRegisterParameter(argNum); auto &argInfo = kernelArgInfo[argNum]; argInfo.metadata = metadata; @@ -256,9 +256,9 @@ void KernelInfo::storeKernelArgument( kernelArgInfo[argNum].isTransformable = pImageMemObjKernelArg->Transformable != 0; patchInfo.imageMemObjKernelArgs.push_back(pImageMemObjKernelArg); - if (NEO::KernelArgMetadata::AccessQualifier::Unknown == kernelArgInfo[argNum].metadata.accessQualifier) { - auto accessQual = pImageMemObjKernelArg->Writeable ? NEO::KernelArgMetadata::AccessQualifier::ReadWrite - : NEO::KernelArgMetadata::AccessQualifier::ReadOnly; + if (NEO::KernelArgMetadata::AccessUnknown == kernelArgInfo[argNum].metadata.accessQualifier) { + auto accessQual = pImageMemObjKernelArg->Writeable ? NEO::KernelArgMetadata::AccessReadWrite + : NEO::KernelArgMetadata::AccessReadOnly; kernelArgInfo[argNum].metadata.accessQualifier = accessQual; } } diff --git a/opencl/source/program/kernel_info.h b/opencl/source/program/kernel_info.h index c69678c22b..cf8edf6b6d 100644 --- a/opencl/source/program/kernel_info.h +++ b/opencl/source/program/kernel_info.h @@ -7,6 +7,7 @@ #pragma once #include "shared/source/helpers/hw_info.h" +#include "shared/source/kernel/kernel_descriptor.h" #include "shared/source/utilities/arrayref.h" #include "shared/source/utilities/const_stringref.h" @@ -86,13 +87,6 @@ struct WorkSizeInfo { void checkRatio(const size_t workItems[3]); }; -struct DebugData { - uint32_t vIsaSize = 0; - uint32_t genIsaSize = 0; - const char *vIsa = nullptr; - const char *genIsa = nullptr; -}; - struct DeviceInfoKernelPayloadConstants { void *slmWindow = nullptr; uint32_t slmWindowSize = 0U; @@ -107,7 +101,7 @@ struct KernelInfo { KernelInfo &operator=(const KernelInfo &) = delete; ~KernelInfo(); - void storeArgInfo(uint32_t argNum, ArgTypeMetadata metadata, std::unique_ptr metadataExtended); + void storeArgInfo(uint32_t argNum, ArgTypeTraits metadata, std::unique_ptr metadataExtended); void storeKernelArgument(const SPatchDataParameterBuffer *pDataParameterKernelArg); void storeKernelArgument(const SPatchStatelessGlobalMemoryObjectKernelArgument *pStatelessGlobalKernelArg); void storeKernelArgument(const SPatchImageMemoryObjectKernelArgument *pImageMemObjKernelArg); diff --git a/opencl/source/program/kernel_info_from_patchtokens.cpp b/opencl/source/program/kernel_info_from_patchtokens.cpp index 05150be4e9..0164cdb5ff 100644 --- a/opencl/source/program/kernel_info_from_patchtokens.cpp +++ b/opencl/source/program/kernel_info_from_patchtokens.cpp @@ -54,7 +54,7 @@ void populateKernelInfoArgMetadata(KernelInfo &dstKernelInfoArg, const SPatchKer metadataExtended->type = std::string(argTypeFull.data(), argTypeDelim).c_str(); metadataExtended->typeQualifiers = parseLimitedString(inlineData.typeQualifiers.begin(), inlineData.typeQualifiers.size()); - ArgTypeMetadata metadata = {}; + ArgTypeTraits metadata = {}; metadata.accessQualifier = KernelArgMetadata::parseAccessQualifier(metadataExtended->accessQualifier); metadata.addressQualifier = KernelArgMetadata::parseAddressSpace(metadataExtended->addressQualifier); metadata.typeQualifiers = KernelArgMetadata::parseTypeQualifiers(metadataExtended->typeQualifiers); diff --git a/opencl/source/utilities/logger.cpp b/opencl/source/utilities/logger.cpp index 35ee435708..5b9f864fe7 100644 --- a/opencl/source/utilities/logger.cpp +++ b/opencl/source/utilities/logger.cpp @@ -179,7 +179,7 @@ void FileLogger::dumpKernelArgs(const Kernel *kernel) { auto &argInfo = kernel->getKernelInfo().kernelArgInfo[i]; - if (argInfo.metadata.addressQualifier == KernelArgMetadata::AddressSpaceQualifier::Local) { + if (argInfo.metadata.addressQualifier == KernelArgMetadata::AddrLocal) { type = "local"; } else if (argInfo.isImage) { type = "image"; diff --git a/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl b/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl index 940058f284..bbf79c0d7e 100644 --- a/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl +++ b/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl @@ -43,7 +43,7 @@ class KernelArgSvmFixture : public ApiFixture<>, public DeviceFixture { pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset = 0x30; pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].size = (uint32_t)sizeof(void *); - pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Global; + pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddrGlobal; pMockKernel = new MockKernel(pProgram, *pKernelInfo, *this->pClDevice); ASSERT_EQ(CL_SUCCESS, pMockKernel->initialize()); @@ -88,7 +88,7 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenInvalidArgIndexWhenSettingKernelArgTh } TEST_F(clSetKernelArgSVMPointerTests, GivenLocalAddressAndNullArgValueWhenSettingKernelArgThenInvalidArgValueErrorIsReturned) { - pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Local; + pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddrLocal; auto retVal = clSetKernelArgSVMPointer( pMockKernel, // cl_kernel kernel @@ -148,7 +148,7 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenSvmAndConstantAddressWhenSettingKerne void *ptrSvm = clSVMAlloc(pContext, CL_MEM_READ_WRITE, 256, 4); EXPECT_NE(nullptr, ptrSvm); - pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Constant; + pKernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddrConstant; auto retVal = clSetKernelArgSVMPointer( pMockKernel, // cl_kernel kernel diff --git a/opencl/test/unit_test/kernel/CMakeLists.txt b/opencl/test/unit_test/kernel/CMakeLists.txt index a2f8f1b9f5..4059c25fd4 100644 --- a/opencl/test/unit_test/kernel/CMakeLists.txt +++ b/opencl/test/unit_test/kernel/CMakeLists.txt @@ -30,5 +30,11 @@ set(IGDRCL_SRCS_tests_kernel ${CMAKE_CURRENT_SOURCE_DIR}/parent_kernel_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/substitute_kernel_heap_tests.cpp ) + +get_property(NEO_SHARED_KERNEL_TESTS GLOBAL PROPERTY NEO_SHARED_KERNEL_TESTS) +list(APPEND IGDRCL_SRCS_tests_kernel + ${NEO_SHARED_KERNEL_TESTS} +) + target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_kernel}) add_subdirectories() 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 6d67b1b678..77676d9b53 100644 --- a/opencl/test/unit_test/kernel/kernel_arg_info_tests.cpp +++ b/opencl/test/unit_test/kernel/kernel_arg_info_tests.cpp @@ -192,99 +192,3 @@ INSTANTIATE_TEST_CASE_P(KernelArgInfoTests, ::testing::ValuesIn(BinaryForSourceFileNames), ::testing::ValuesIn(KernelNames))); -TEST(KernelArgMetadata, WhenParseAccessQualifierIsCalledThenQualifierIsProperlyParsed) { - using namespace NEO::KernelArgMetadata; - EXPECT_EQ(AccessQualifier::None, KernelArgMetadata::parseAccessQualifier("")); - EXPECT_EQ(AccessQualifier::None, KernelArgMetadata::parseAccessQualifier("NONE")); - EXPECT_EQ(AccessQualifier::ReadOnly, KernelArgMetadata::parseAccessQualifier("read_only")); - EXPECT_EQ(AccessQualifier::WriteOnly, KernelArgMetadata::parseAccessQualifier("write_only")); - EXPECT_EQ(AccessQualifier::ReadWrite, KernelArgMetadata::parseAccessQualifier("read_write")); - EXPECT_EQ(AccessQualifier::ReadOnly, KernelArgMetadata::parseAccessQualifier("__read_only")); - EXPECT_EQ(AccessQualifier::WriteOnly, KernelArgMetadata::parseAccessQualifier("__write_only")); - EXPECT_EQ(AccessQualifier::ReadWrite, KernelArgMetadata::parseAccessQualifier("__read_write")); - - EXPECT_EQ(AccessQualifier::Unknown, KernelArgMetadata::parseAccessQualifier("re")); - EXPECT_EQ(AccessQualifier::Unknown, KernelArgMetadata::parseAccessQualifier("read")); - EXPECT_EQ(AccessQualifier::Unknown, KernelArgMetadata::parseAccessQualifier("write")); -} - -TEST(KernelArgMetadata, WhenParseAddressQualifierIsCalledThenQualifierIsProperlyParsed) { - using namespace NEO::KernelArgMetadata; - EXPECT_EQ(AddressSpaceQualifier::Global, KernelArgMetadata::parseAddressSpace("")); - EXPECT_EQ(AddressSpaceQualifier::Global, KernelArgMetadata::parseAddressSpace("__global")); - EXPECT_EQ(AddressSpaceQualifier::Local, KernelArgMetadata::parseAddressSpace("__local")); - EXPECT_EQ(AddressSpaceQualifier::Private, KernelArgMetadata::parseAddressSpace("__private")); - EXPECT_EQ(AddressSpaceQualifier::Constant, KernelArgMetadata::parseAddressSpace("__constant")); - EXPECT_EQ(AddressSpaceQualifier::Private, KernelArgMetadata::parseAddressSpace("not_specified")); - - EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("wrong")); - EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__glob")); - EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__loc")); - EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__priv")); - EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("__const")); - EXPECT_EQ(AddressSpaceQualifier::Unknown, KernelArgMetadata::parseAddressSpace("not")); -} - -TEST(KernelArgMetadata, WhenParseTypeQualifiersIsCalledThenQualifierIsProperlyParsed) { - using namespace NEO::KernelArgMetadata; - - TypeQualifiers qual = {}; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("").packed); - - qual = {}; - qual.constQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("const").packed); - - qual = {}; - qual.volatileQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("volatile").packed); - - qual = {}; - qual.restrictQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("restrict").packed); - - qual = {}; - qual.pipeQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe").packed); - - qual = {}; - qual.unknownQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("inval").packed); - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("cons").packed); - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("volat").packed); - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("restr").packed); - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pip").packed); - - qual = {}; - qual.constQual = true; - qual.volatileQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("const volatile").packed); - - qual = {}; - qual.constQual = true; - qual.volatileQual = true; - qual.restrictQual = true; - qual.pipeQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe const restrict volatile").packed); - - qual = {}; - qual.constQual = true; - qual.volatileQual = true; - qual.restrictQual = true; - qual.pipeQual = true; - qual.unknownQual = true; - EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe const restrict volatile some").packed); -} - -TEST(KernelArgMetadata, WhenParseLimitedStringIsCalledThenReturnedStringDoesntContainExcessiveTrailingZeroes) { - char str1[] = "abcd\0\0\0after\0"; - EXPECT_STREQ("abcd", NEO::parseLimitedString(str1, sizeof(str1)).c_str()); - EXPECT_EQ(4U, NEO::parseLimitedString(str1, sizeof(str1)).size()); - - EXPECT_STREQ("ab", NEO::parseLimitedString(str1, 2).c_str()); - EXPECT_EQ(2U, NEO::parseLimitedString(str1, 2).size()); - - char str2[] = {'a', 'b', 'd', 'e', 'f'}; - EXPECT_STREQ("abdef", NEO::parseLimitedString(str2, sizeof(str2)).c_str()); - EXPECT_EQ(5U, NEO::parseLimitedString(str2, sizeof(str2)).size()); -} diff --git a/opencl/test/unit_test/kernel/kernel_image_arg_tests.cpp b/opencl/test/unit_test/kernel/kernel_image_arg_tests.cpp index 4101aafe0e..6ef8e758ec 100644 --- a/opencl/test/unit_test/kernel/kernel_image_arg_tests.cpp +++ b/opencl/test/unit_test/kernel/kernel_image_arg_tests.cpp @@ -119,7 +119,7 @@ TEST_F(KernelImageArgTest, givenImageWithWriteOnlyAccessAndReadOnlyArgWhenCheckC imgDesc.image_height = 5; auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.clVersionSupport); std::unique_ptr img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal)); - pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadOnly; + pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessReadOnly; cl_mem memObj = img.get(); retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj); @@ -158,7 +158,7 @@ TEST_F(KernelImageArgTest, givenImageWithReadOnlyAccessAndWriteOnlyArgWhenCheckC imgDesc.image_height = 5; auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.clVersionSupport); std::unique_ptr img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal)); - pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::WriteOnly; + pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessWriteOnly; cl_mem memObj = img.get(); retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj); @@ -178,7 +178,7 @@ TEST_F(KernelImageArgTest, givenImageWithReadOnlyAccessAndReadOnlyArgWhenCheckCo imgDesc.image_height = 5; auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.clVersionSupport); std::unique_ptr img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal)); - pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadOnly; + pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessReadOnly; cl_mem memObj = img.get(); retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj); @@ -194,7 +194,7 @@ TEST_F(KernelImageArgTest, givenImageWithWriteOnlyAccessAndWriteOnlyArgWhenCheck imgDesc.image_height = 5; auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imgFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.clVersionSupport); std::unique_ptr img(Image::create(context.get(), MemoryPropertiesFlagsParser::createMemoryPropertiesFlags(flags, 0, 0), flags, 0, surfaceFormat, &imgDesc, nullptr, retVal)); - pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::WriteOnly; + pKernelInfo->kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessWriteOnly; cl_mem memObj = img.get(); retVal = pKernel->checkCorrectImageAccessQualifier(0, sizeof(memObj), &memObj); diff --git a/opencl/test/unit_test/kernel/kernel_info_cl_tests.cpp b/opencl/test/unit_test/kernel/kernel_info_cl_tests.cpp index ddf9953924..3993df83bc 100644 --- a/opencl/test/unit_test/kernel/kernel_info_cl_tests.cpp +++ b/opencl/test/unit_test/kernel/kernel_info_cl_tests.cpp @@ -12,20 +12,20 @@ TEST(AsClConvertersTest, whenConvertingAccessQualifiersThenProperEnumValuesAreReturned) { using namespace NEO::KernelArgMetadata; - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_NONE), NEO::asClKernelArgAccessQualifier(AccessQualifier::None)); - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_READ_ONLY), NEO::asClKernelArgAccessQualifier(AccessQualifier::ReadOnly)); - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_WRITE_ONLY), NEO::asClKernelArgAccessQualifier(AccessQualifier::WriteOnly)); - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_READ_WRITE), NEO::asClKernelArgAccessQualifier(AccessQualifier::ReadWrite)); - EXPECT_EQ(0U, NEO::asClKernelArgAccessQualifier(AccessQualifier::Unknown)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_NONE), NEO::asClKernelArgAccessQualifier(AccessNone)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_READ_ONLY), NEO::asClKernelArgAccessQualifier(AccessReadOnly)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_WRITE_ONLY), NEO::asClKernelArgAccessQualifier(AccessWriteOnly)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ACCESS_READ_WRITE), NEO::asClKernelArgAccessQualifier(AccessReadWrite)); + EXPECT_EQ(0U, NEO::asClKernelArgAccessQualifier(AccessUnknown)); } TEST(AsClConvertersTest, whenConvertingAddressQualifiersThenProperEnumValuesAreReturned) { using namespace NEO::KernelArgMetadata; - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_GLOBAL), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Global)); - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_LOCAL), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Local)); - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_PRIVATE), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Private)); - EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_CONSTANT), NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Constant)); - EXPECT_EQ(0U, NEO::asClKernelArgAddressQualifier(AddressSpaceQualifier::Unknown)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_GLOBAL), NEO::asClKernelArgAddressQualifier(AddrGlobal)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_LOCAL), NEO::asClKernelArgAddressQualifier(AddrLocal)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_PRIVATE), NEO::asClKernelArgAddressQualifier(AddrPrivate)); + EXPECT_EQ(static_cast(CL_KERNEL_ARG_ADDRESS_CONSTANT), NEO::asClKernelArgAddressQualifier(AddrConstant)); + EXPECT_EQ(0U, NEO::asClKernelArgAddressQualifier(AddrUnknown)); } TEST(AsClConvertersTest, whenConvertingTypeQualifiersThenProperBitfieldsAreSet) { diff --git a/opencl/test/unit_test/kernel/kernel_reflection_surface_tests.cpp b/opencl/test/unit_test/kernel/kernel_reflection_surface_tests.cpp index e152c3b98f..6926bc29b7 100644 --- a/opencl/test/unit_test/kernel/kernel_reflection_surface_tests.cpp +++ b/opencl/test/unit_test/kernel/kernel_reflection_surface_tests.cpp @@ -95,7 +95,7 @@ TEST_P(KernelReflectionSurfaceTest, GivenKernelInfoWithCorrectlyFilledImageArgum info.storeKernelArgument(&imageMemObjKernelArg); info.kernelArgInfo[0].metadataExtended = std::make_unique(); - info.kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadOnly; + info.kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessReadOnly; info.kernelArgInfo[0].metadataExtended->accessQualifier = "read_only"; info.kernelArgInfo[0].isImage = true; info.kernelArgInfo[0].metadataExtended->argName = "img"; diff --git a/opencl/test/unit_test/kernel/kernel_tests.cpp b/opencl/test/unit_test/kernel/kernel_tests.cpp index 3ece73ba4a..573a691085 100644 --- a/opencl/test/unit_test/kernel/kernel_tests.cpp +++ b/opencl/test/unit_test/kernel/kernel_tests.cpp @@ -3167,7 +3167,7 @@ TEST(KernelCreateTest, whenInitFailedThenReturnNull) { EXPECT_EQ(nullptr, ret); } -TEST(ArgTypeMetadata, GivenDefaultInitializedArgTypeMetadataThenAddressSpaceIsGlobal) { - ArgTypeMetadata metadata; - EXPECT_EQ(NEO::KernelArgMetadata::AddressSpaceQualifier::Global, metadata.addressQualifier); +TEST(ArgTypeTraits, GivenDefaultInitializedArgTypeMetadataThenAddressSpaceIsGlobal) { + ArgTypeTraits metadata; + EXPECT_EQ(NEO::KernelArgMetadata::AddrGlobal, metadata.addressQualifier); } diff --git a/opencl/test/unit_test/mocks/mock_kernel.h b/opencl/test/unit_test/mocks/mock_kernel.h index 0588e8144a..983b919d78 100644 --- a/opencl/test/unit_test/mocks/mock_kernel.h +++ b/opencl/test/unit_test/mocks/mock_kernel.h @@ -311,14 +311,14 @@ class MockKernelWithInternals { kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector.resize(1); kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset = 0; kernelInfo.kernelArgInfo[0].kernelArgPatchInfoVector[0].size = sizeof(uintptr_t); - kernelInfo.kernelArgInfo[0].metadata.addressQualifier = NEO::KernelArgMetadata::AddressSpaceQualifier::Global; - kernelInfo.kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadWrite; + kernelInfo.kernelArgInfo[0].metadata.addressQualifier = NEO::KernelArgMetadata::AddrGlobal; + kernelInfo.kernelArgInfo[0].metadata.accessQualifier = NEO::KernelArgMetadata::AccessReadWrite; kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector.resize(1); kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector[0].crossthreadOffset = 0; kernelInfo.kernelArgInfo[1].kernelArgPatchInfoVector[0].size = sizeof(uintptr_t); - kernelInfo.kernelArgInfo[1].metadata.addressQualifier = NEO::KernelArgMetadata::AddressSpaceQualifier::Global; - kernelInfo.kernelArgInfo[1].metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::ReadWrite; + kernelInfo.kernelArgInfo[1].metadata.addressQualifier = NEO::KernelArgMetadata::AddrGlobal; + kernelInfo.kernelArgInfo[1].metadata.accessQualifier = NEO::KernelArgMetadata::AccessReadWrite; mockKernel->setKernelArguments(defaultKernelArguments); mockKernel->kernelArgRequiresCacheFlush.resize(2); diff --git a/opencl/test/unit_test/program/kernel_info_from_patchtokens_tests.cpp b/opencl/test/unit_test/program/kernel_info_from_patchtokens_tests.cpp index 4315d209f2..7f857da0c5 100644 --- a/opencl/test/unit_test/program/kernel_info_from_patchtokens_tests.cpp +++ b/opencl/test/unit_test/program/kernel_info_from_patchtokens_tests.cpp @@ -32,8 +32,8 @@ TEST(KernelInfoFromPatchTokens, GivenValidKernelWithArgThenMetadataIsProperlyPop NEO::KernelInfo dst = {}; NEO::populateKernelInfo(dst, src.kernels[0], 4); ASSERT_EQ(1U, dst.kernelArgInfo.size()); - EXPECT_EQ(NEO::KernelArgMetadata::AccessQualifier::ReadWrite, dst.kernelArgInfo[0].metadata.accessQualifier); - EXPECT_EQ(NEO::KernelArgMetadata::AddressSpaceQualifier::Global, dst.kernelArgInfo[0].metadata.addressQualifier); + EXPECT_EQ(NEO::KernelArgMetadata::AccessReadWrite, dst.kernelArgInfo[0].metadata.accessQualifier); + EXPECT_EQ(NEO::KernelArgMetadata::AddrGlobal, dst.kernelArgInfo[0].metadata.addressQualifier); NEO::KernelArgMetadata::TypeQualifiers typeQualifiers = {}; typeQualifiers.constQual = true; EXPECT_EQ(typeQualifiers.packed, dst.kernelArgInfo[0].metadata.typeQualifiers.packed); @@ -55,7 +55,7 @@ TEST(KernelInfoFromPatchTokens, GivenValidKernelWithImageArgThenArgAccessQualifi NEO::KernelInfo dst = {}; NEO::populateKernelInfo(dst, src.kernels[0], 4); ASSERT_EQ(1U, dst.kernelArgInfo.size()); - EXPECT_EQ(NEO::KernelArgMetadata::AccessQualifier::ReadWrite, dst.kernelArgInfo[0].metadata.accessQualifier); + EXPECT_EQ(NEO::KernelArgMetadata::AccessReadWrite, dst.kernelArgInfo[0].metadata.accessQualifier); } TEST(KernelInfoFromPatchTokens, GivenValidKernelWithImageArgWhenArgInfoIsMissingThenArgAccessQualifierIsPopulatedBasedOnImageArgWriteableFlag) { @@ -69,7 +69,7 @@ TEST(KernelInfoFromPatchTokens, GivenValidKernelWithImageArgWhenArgInfoIsMissing NEO::KernelInfo dst = {}; NEO::populateKernelInfo(dst, src.kernels[0], 4); ASSERT_EQ(1U, dst.kernelArgInfo.size()); - EXPECT_EQ(NEO::KernelArgMetadata::AccessQualifier::ReadOnly, dst.kernelArgInfo[0].metadata.accessQualifier); + EXPECT_EQ(NEO::KernelArgMetadata::AccessReadOnly, dst.kernelArgInfo[0].metadata.accessQualifier); } { @@ -77,7 +77,7 @@ TEST(KernelInfoFromPatchTokens, GivenValidKernelWithImageArgWhenArgInfoIsMissing NEO::KernelInfo dst = {}; NEO::populateKernelInfo(dst, src.kernels[0], 4); ASSERT_EQ(1U, dst.kernelArgInfo.size()); - EXPECT_EQ(NEO::KernelArgMetadata::AccessQualifier::ReadWrite, dst.kernelArgInfo[0].metadata.accessQualifier); + EXPECT_EQ(NEO::KernelArgMetadata::AccessReadWrite, dst.kernelArgInfo[0].metadata.accessQualifier); } } diff --git a/opencl/test/unit_test/program/kernel_info_tests.cpp b/opencl/test/unit_test/program/kernel_info_tests.cpp index f32772c0dd..d6ce569bb1 100644 --- a/opencl/test/unit_test/program/kernel_info_tests.cpp +++ b/opencl/test/unit_test/program/kernel_info_tests.cpp @@ -100,7 +100,7 @@ TEST(KernelInfo, decodeImageKernelArgument) { EXPECT_EQ(sizeof(cl_mem), static_cast(argInfo.metadata.argByValSize)); EXPECT_EQ(arg.Offset, argInfo.offsetHeap); EXPECT_TRUE(argInfo.isImage); - EXPECT_EQ(KernelArgMetadata::AccessQualifier::ReadWrite, argInfo.metadata.accessQualifier); + EXPECT_EQ(KernelArgMetadata::AccessReadWrite, argInfo.metadata.accessQualifier); EXPECT_TRUE(argInfo.metadata.typeQualifiers.empty()); } @@ -188,9 +188,9 @@ TEST(KernelInfo, decodeSamplerKernelArgument) { TEST(KernelInfo, whenStoringArgInfoThenMetadataIsProperlyPopulated) { KernelInfo kernelInfo; - NEO::ArgTypeMetadata metadata; - metadata.accessQualifier = NEO::KernelArgMetadata::AccessQualifier::WriteOnly; - metadata.addressQualifier = NEO::KernelArgMetadata::AddressSpaceQualifier::Global; + NEO::ArgTypeTraits metadata; + metadata.accessQualifier = NEO::KernelArgMetadata::AccessWriteOnly; + metadata.addressQualifier = NEO::KernelArgMetadata::AddrGlobal; metadata.argByValSize = sizeof(void *); metadata.typeQualifiers.pipeQual = true; auto metadataExtended = std::make_unique(); diff --git a/opencl/test/unit_test/utilities/file_logger_tests.cpp b/opencl/test/unit_test/utilities/file_logger_tests.cpp index 9dbcd64b92..0c82828fe7 100644 --- a/opencl/test/unit_test/utilities/file_logger_tests.cpp +++ b/opencl/test/unit_test/utilities/file_logger_tests.cpp @@ -526,7 +526,7 @@ TEST(FileLogger, WithDebugFunctionalityDumpKernelArgsLocalBuffer) { kernelInfo->kernelArgInfo.resize(1); kernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo); - kernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddressSpaceQualifier::Local; + kernelInfo->kernelArgInfo[0].metadata.addressQualifier = KernelArgMetadata::AddrLocal; std::string testFile = "testfile"; DebugVariables flags; diff --git a/shared/source/device_binary_format/patchtokens_validator.cpp b/shared/source/device_binary_format/patchtokens_validator.cpp index 2479b57b50..3336104852 100644 --- a/shared/source/device_binary_format/patchtokens_validator.cpp +++ b/shared/source/device_binary_format/patchtokens_validator.cpp @@ -122,12 +122,12 @@ DecodeError validate(const ProgramFromPatchtokens &decodedProgram, } auto argInfoInlineData = getInlineData(kernelArg.argInfo); auto accessQualifier = KernelArgMetadata::parseAccessQualifier(parseLimitedString(argInfoInlineData.accessQualifier.begin(), argInfoInlineData.accessQualifier.size())); - if (KernelArgMetadata::AccessQualifier::Unknown == accessQualifier) { + if (KernelArgMetadata::AccessUnknown == accessQualifier) { outErrReason = "Unhandled access qualifier"; return DecodeError::UnhandledBinary; } auto addressQualifier = KernelArgMetadata::parseAddressSpace(parseLimitedString(argInfoInlineData.addressQualifier.begin(), argInfoInlineData.addressQualifier.size())); - if (KernelArgMetadata::AddressSpaceQualifier::Unknown == addressQualifier) { + if (KernelArgMetadata::AddrUnknown == addressQualifier) { outErrReason = "Unhandled address qualifier"; return DecodeError::UnhandledBinary; } diff --git a/shared/source/kernel/CMakeLists.txt b/shared/source/kernel/CMakeLists.txt index 3e83e89b74..b2e0a39693 100644 --- a/shared/source/kernel/CMakeLists.txt +++ b/shared/source/kernel/CMakeLists.txt @@ -6,8 +6,13 @@ set(NEO_CORE_KERNEL ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/debug_data.h ${CMAKE_CURRENT_SOURCE_DIR}/dispatch_kernel_encoder_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/grf_config.h + ${CMAKE_CURRENT_SOURCE_DIR}/kernel_arg_descriptor.h + ${CMAKE_CURRENT_SOURCE_DIR}/kernel_arg_metadata.h + ${CMAKE_CURRENT_SOURCE_DIR}/kernel_descriptor.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/kernel_descriptor.h ) set_property(GLOBAL PROPERTY NEO_CORE_KERNEL ${NEO_CORE_KERNEL}) diff --git a/shared/source/kernel/debug_data.h b/shared/source/kernel/debug_data.h new file mode 100644 index 0000000000..7ed9fe09f7 --- /dev/null +++ b/shared/source/kernel/debug_data.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include + +namespace NEO { +struct DebugData { + uint32_t vIsaSize = 0; + uint32_t genIsaSize = 0; + const char *vIsa = nullptr; + const char *genIsa = nullptr; +}; +} // namespace NEO diff --git a/shared/source/kernel/kernel_arg_descriptor.h b/shared/source/kernel/kernel_arg_descriptor.h new file mode 100644 index 0000000000..23a0d783f7 --- /dev/null +++ b/shared/source/kernel/kernel_arg_descriptor.h @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/helpers/debug_helpers.h" +#include "shared/source/kernel/kernel_arg_metadata.h" +#include "shared/source/utilities/arrayref.h" +#include "shared/source/utilities/stackvec.h" + +#include +#include +#include + +namespace NEO { + +using CrossThreadDataOffset = uint16_t; +using DynamicStateHeapOffset = uint16_t; +using SurfaceStateHeapOffset = uint16_t; + +template +static constexpr T undefined = std::numeric_limits::max(); + +template +bool isUndefinedOffset(T offset) { + return undefined == offset; +} + +template +bool isValidOffset(T offset) { + return false == isUndefinedOffset(offset); +} + +struct ArgDescPointer final { + SurfaceStateHeapOffset bindful = undefined; + CrossThreadDataOffset stateless = undefined; + CrossThreadDataOffset bindless = undefined; + CrossThreadDataOffset bufferOffset = undefined; + CrossThreadDataOffset slmOffset = undefined; + uint8_t requiredSlmAlignment = 0; + uint8_t pointerSize = 0; + bool accessedUsingStatelessAddressingMode = true; + + bool isPureStateful() const { + return false == accessedUsingStatelessAddressingMode; + } +}; + +struct ArgDescImage final { + SurfaceStateHeapOffset bindful = undefined; // stateful with BTI + CrossThreadDataOffset bindless = undefined; + struct { + CrossThreadDataOffset imgWidth = undefined; + CrossThreadDataOffset imgHeight = undefined; + CrossThreadDataOffset imgDepth = undefined; + CrossThreadDataOffset channelDataType = undefined; + CrossThreadDataOffset channelOrder = undefined; + + CrossThreadDataOffset arraySize = undefined; + CrossThreadDataOffset numSamples = undefined; + CrossThreadDataOffset numMipLevels = undefined; + + CrossThreadDataOffset flatBaseOffset = undefined; + CrossThreadDataOffset flatWidth = undefined; + CrossThreadDataOffset flatHeight = undefined; + CrossThreadDataOffset flatPitch = undefined; + } metadataPayload; +}; + +struct ArgDescSampler final { + uint32_t samplerType = 0; + DynamicStateHeapOffset bindful = undefined; + CrossThreadDataOffset bindless = undefined; + struct { + CrossThreadDataOffset samplerSnapWa = undefined; + CrossThreadDataOffset samplerAddressingMode = undefined; + CrossThreadDataOffset samplerNormalizedCoords = undefined; + } metadataPayload; +}; + +struct ArgDescValue final { + struct Element { + CrossThreadDataOffset offset = undefined; + uint16_t size = 0U; + uint16_t sourceOffset = 0U; + }; + StackVec elements; +}; + +struct ArgDescriptor final { + enum ArgType : uint8_t { + ArgTUnknown, + ArgTPointer, + ArgTImage, + ArgTSampler, + ArgTValue + }; + + struct ExtendedTypeInfo { + ExtendedTypeInfo() { + packed = 0U; + } + union { + struct { + bool isAccelerator : 1; + bool isDeviceQueue : 1; + bool isMediaImage : 1; + bool isMediaBlockImage : 1; + bool isTransformable : 1; + bool needsPatch : 1; + bool hasVmeExtendedDescriptor : 1; + bool hasDeviceSideEnqueueExtendedDescriptor : 1; + }; + uint32_t packed; + }; + }; + + ArgDescriptor(ArgType type); + + ArgDescriptor() + : ArgDescriptor(ArgTUnknown) { + } + + ArgDescriptor &operator=(const ArgDescriptor &rhs); + + template + const T &as() const; + + template + T &as(bool initIfUnknown = false); + + template + bool is() const { + return Type == this->type; + } + + ArgTypeTraits &getTraits() { + return traits; + } + + const ArgTypeTraits &getTraits() const { + return traits; + } + + ExtendedTypeInfo &getExtendedTypeInfo() { + return extendedTypeInfo; + } + + const ExtendedTypeInfo &getExtendedTypeInfo() const { + return extendedTypeInfo; + } + + bool isReadOnly() const { + switch (type) { + default: + return true; + case ArgTImage: + return (KernelArgMetadata::AccessReadOnly == traits.accessQualifier); + case ArgTPointer: + return (KernelArgMetadata::AddrConstant == traits.addressQualifier) || (traits.typeQualifiers.constQual); + } + } + + protected: + ArgDescValue asByValue; + ArgTypeTraits traits; + union { + ArgDescPointer asPointer; + ArgDescImage asImage; + ArgDescSampler asSampler; + }; + + ExtendedTypeInfo extendedTypeInfo; + + public: + ArgType type; +}; + +namespace { +constexpr auto ArgSize = sizeof(ArgDescriptor); +static_assert(ArgSize <= 64, "Keep it small"); +} // namespace + +template <> +inline const ArgDescPointer &ArgDescriptor::as() const { + UNRECOVERABLE_IF(type != ArgTPointer); + return this->asPointer; +} + +template <> +inline const ArgDescImage &ArgDescriptor::as() const { + UNRECOVERABLE_IF(type != ArgTImage); + return this->asImage; +} + +template <> +inline const ArgDescSampler &ArgDescriptor::as() const { + UNRECOVERABLE_IF(type != ArgTSampler); + return this->asSampler; +} + +template <> +inline const ArgDescValue &ArgDescriptor::as() const { + UNRECOVERABLE_IF(type != ArgTValue); + return this->asByValue; +} + +template <> +inline ArgDescPointer &ArgDescriptor::as(bool initIfUnknown) { + if ((ArgTUnknown == type) & initIfUnknown) { + this->type = ArgTPointer; + this->asPointer = {}; + } + UNRECOVERABLE_IF(type != ArgTPointer); + return this->asPointer; +} + +template <> +inline ArgDescImage &ArgDescriptor::as(bool initIfUnknown) { + if ((ArgTUnknown == type) & initIfUnknown) { + this->type = ArgTImage; + this->asImage = {}; + } + UNRECOVERABLE_IF(type != ArgTImage); + return this->asImage; +} + +template <> +inline ArgDescSampler &ArgDescriptor::as(bool initIfUnknown) { + if ((ArgTUnknown == type) & initIfUnknown) { + this->type = ArgTSampler; + this->asSampler = {}; + } + UNRECOVERABLE_IF(type != ArgTSampler); + return this->asSampler; +} + +template <> +inline ArgDescValue &ArgDescriptor::as(bool initIfUnknown) { + if ((ArgTUnknown == type) & initIfUnknown) { + this->type = ArgTValue; + this->asByValue = {}; + } + UNRECOVERABLE_IF(type != ArgTValue); + return this->asByValue; +} + +template +inline void setOffsetsVec(CrossThreadDataOffset (&dst)[VecSize], const T (&src)[VecSize]) { + for (uint32_t i = 0; i < VecSize; ++i) { + dst[i] = src[i]; + } +} + +template +inline bool patchNonPointer(ArrayRef buffer, CrossThreadDataOffset location, const T &value) { + if (undefined == location) { + return false; + } + UNRECOVERABLE_IF(location + sizeof(T) > buffer.size()); + *reinterpret_cast(buffer.begin() + location) = value; + return true; +} + +template +inline uint32_t patchVecNonPointer(ArrayRef buffer, const CrossThreadDataOffset (&location)[VecSize], const T (&value)[VecSize]) { + uint32_t numPatched = 0; + for (uint32_t i = 0; i < VecSize; ++i) { + numPatched += patchNonPointer(buffer, location[i], value[i]) ? 1 : 0; + } + return numPatched; +} + +inline bool patchPointer(ArrayRef buffer, const ArgDescPointer &arg, uintptr_t value) { + if (arg.pointerSize == 8) { + return patchNonPointer(buffer, arg.stateless, static_cast(value)); + } else { + UNRECOVERABLE_IF(arg.pointerSize != 4); + return patchNonPointer(buffer, arg.stateless, static_cast(value)); + } +} + +inline ArgDescriptor &ArgDescriptor::operator=(const ArgDescriptor &rhs) { + this->type = ArgTUnknown; + switch (rhs.type) { + default: + break; + case ArgTPointer: + this->as(true) = rhs.as(); + break; + case ArgTImage: + this->as(true) = rhs.as(); + break; + case ArgTSampler: + this->as(true) = rhs.as(); + break; + case ArgTValue: + this->as(true) = rhs.as(); + break; + } + this->type = rhs.type; + this->traits = rhs.traits; + this->extendedTypeInfo = rhs.extendedTypeInfo; + return *this; +} + +inline ArgDescriptor::ArgDescriptor(ArgType type) : type(type) { + switch (type) { + default: + break; + case ArgTPointer: + this->as(true); + break; + case ArgTImage: + this->as(true); + break; + case ArgTSampler: + this->as(true); + break; + case ArgTValue: + this->as(true); + break; + } +} + +struct ArgDescriptorExtended { + virtual ~ArgDescriptorExtended() = default; +}; + +} // namespace NEO diff --git a/shared/source/kernel/kernel_arg_metadata.h b/shared/source/kernel/kernel_arg_metadata.h new file mode 100644 index 0000000000..8c623e211c --- /dev/null +++ b/shared/source/kernel/kernel_arg_metadata.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2017-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/compiler_interface/compiler_options/compiler_options_base.h" +#include "shared/source/utilities/const_stringref.h" + +#include +#include +#include +#include +#include + +namespace NEO { + +namespace KernelArgMetadata { + +enum AccessQualifier : uint8_t { + AccessUnknown, + AccessNone, + AccessReadOnly, + AccessWriteOnly, + AccessReadWrite, +}; + +namespace AccessQualifierStrings { +constexpr ConstStringRef none = "NONE"; +constexpr ConstStringRef readOnly = "read_only"; +constexpr ConstStringRef writeOnly = "write_only"; +constexpr ConstStringRef readWrite = "read_write"; +constexpr ConstStringRef underscoreReadOnly = "__read_only"; +constexpr ConstStringRef underscoreWriteOnly = "__write_only"; +constexpr ConstStringRef underscoreReadWrite = "__read_write"; +} // namespace AccessQualifierStrings + +enum AddressSpaceQualifier : uint8_t { + AddrUnknown, + AddrGlobal, + AddrLocal, + AddrPrivate, + AddrConstant +}; + +namespace AddressSpaceQualifierStrings { +constexpr ConstStringRef addrGlobal = "__global"; +constexpr ConstStringRef addrLocal = "__local"; +constexpr ConstStringRef addrPrivate = "__private"; +constexpr ConstStringRef addrConstant = "__constant"; +constexpr ConstStringRef addrNotSpecified = "not_specified"; +} // namespace AddressSpaceQualifierStrings + +constexpr AccessQualifier parseAccessQualifier(ConstStringRef str) { + using namespace AccessQualifierStrings; + if (str.empty() || (none == str)) { + return AccessNone; + } + + if (str.length() < 3) { + return AccessUnknown; + } + + ConstStringRef strNoUnderscore = ('_' == str[0]) ? ConstStringRef(str.data() + 2, str.length() - 2) : str; + static_assert(writeOnly[0] != readOnly[0], ""); + static_assert(writeOnly[0] != readWrite[0], ""); + if (strNoUnderscore[0] == writeOnly[0]) { + return (writeOnly == strNoUnderscore) ? AccessWriteOnly : AccessUnknown; + } + + if (readOnly == strNoUnderscore) { + return AccessReadOnly; + } + + return (readWrite == strNoUnderscore) ? AccessReadWrite : AccessUnknown; +} + +constexpr AddressSpaceQualifier parseAddressSpace(ConstStringRef str) { + using namespace AddressSpaceQualifierStrings; + if (str.empty()) { + return AddrGlobal; + } + + if (str.length() < 3) { + return AddrUnknown; + } + + switch (str[2]) { + default: + return AddrUnknown; + case addrNotSpecified[2]: + return (str == addrNotSpecified) ? AddrPrivate : AddrUnknown; + case addrGlobal[2]: + return (str == addrGlobal) ? AddrGlobal : AddrUnknown; + case addrLocal[2]: + return (str == addrLocal) ? AddrLocal : AddrUnknown; + case addrPrivate[2]: + return (str == addrPrivate) ? AddrPrivate : AddrUnknown; + case addrConstant[2]: + return (str == addrConstant) ? AddrConstant : AddrUnknown; + } +} + +union TypeQualifiers { + uint8_t packed = 0U; + struct { + bool constQual : 1; + bool volatileQual : 1; + bool restrictQual : 1; + bool pipeQual : 1; + bool unknownQual : 1; + }; + bool empty() const { + return 0U == packed; + } +}; + +namespace TypeQualifierStrings { +constexpr ConstStringRef qualConst = "const"; +constexpr ConstStringRef qualVolatile = "volatile"; +constexpr ConstStringRef qualRestrict = "restrict"; +constexpr ConstStringRef qualPipe = "pipe"; +} // namespace TypeQualifierStrings + +inline TypeQualifiers parseTypeQualifiers(ConstStringRef str) { + using namespace TypeQualifierStrings; + TypeQualifiers ret = {}; + auto tokenized = CompilerOptions::tokenize(str); + for (const auto &tok : tokenized) { + bool knownQualifier = true; + switch (tok[0]) { + default: + knownQualifier = false; + break; + case qualConst[0]: + knownQualifier = (qualConst == tok); + ret.constQual |= knownQualifier; + break; + case qualVolatile[0]: + knownQualifier = (qualVolatile == tok); + ret.volatileQual |= knownQualifier; + break; + case qualRestrict[0]: + knownQualifier = (qualRestrict == tok); + ret.restrictQual |= knownQualifier; + break; + case qualPipe[0]: + knownQualifier = (qualPipe == tok); + ret.pipeQual |= knownQualifier; + break; + } + ret.unknownQual |= !knownQualifier; + } + return ret; +} + +} // namespace KernelArgMetadata + +inline std::string parseLimitedString(const char *str, size_t maxSize) { + std::string ret{str, str + maxSize}; + size_t minSize = strlen(ret.c_str()); + ret.assign(str, minSize); + return ret; +} + +struct ArgTypeTraits { + ArgTypeTraits() { + accessQualifier = KernelArgMetadata::AccessUnknown; + addressQualifier = KernelArgMetadata::AddrGlobal; + } + uint16_t argByValSize = 0U; + struct { + std::underlying_type_t accessQualifier : 4; + std::underlying_type_t addressQualifier : 4; + }; + KernelArgMetadata::TypeQualifiers typeQualifiers; + + KernelArgMetadata::AccessQualifier getAccessQualifier() const { + return static_cast(accessQualifier); + } + + KernelArgMetadata::AddressSpaceQualifier getAddressQualifier() const { + return static_cast(addressQualifier); + } +}; + +namespace { +static constexpr auto ArgTypeMetadataSize = sizeof(ArgTypeTraits); +static_assert(ArgTypeMetadataSize <= 4, "Keep it small"); +} // namespace + +struct ArgTypeMetadataExtended { + std::string argName; + std::string type; + std::string accessQualifier; + std::string addressQualifier; + std::string typeQualifiers; +}; + +} // namespace NEO diff --git a/shared/source/kernel/kernel_descriptor.cpp b/shared/source/kernel/kernel_descriptor.cpp new file mode 100644 index 0000000000..d1ae5671d3 --- /dev/null +++ b/shared/source/kernel/kernel_descriptor.cpp @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/kernel/kernel_descriptor.h" + +namespace NEO { +} diff --git a/shared/source/kernel/kernel_descriptor.h b/shared/source/kernel/kernel_descriptor.h new file mode 100644 index 0000000000..b32ae2f593 --- /dev/null +++ b/shared/source/kernel/kernel_descriptor.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/helpers/debug_helpers.h" +#include "shared/source/kernel/debug_data.h" +#include "shared/source/kernel/kernel_arg_descriptor.h" +#include "shared/source/kernel/kernel_arg_metadata.h" +#include "shared/source/utilities/arrayref.h" +#include "shared/source/utilities/stackvec.h" + +#include +#include +#include +#include +#include +#include + +namespace NEO { + +using StringMap = std::unordered_map; +using InstructionsSegmentOffset = uint16_t; + +struct KernelDescriptor final { + enum AddressingMode : uint8_t { + AddrNone, + Stateless, + Bindful, + Bindless, + BindfulAndStateless, + BindlessAndStateless + }; + + KernelDescriptor() = default; + ~KernelDescriptor() = default; + + struct KernelAttributes { + KernelAttributes() { flags.packed = 0U; } + + uint32_t slmInlineSize = 0U; + uint32_t perThreadScratchSize[2] = {0U, 0U}; + uint32_t perThreadPrivateMemorySize = 0U; + uint32_t perThreadSystemThreadSurfaceSize = 0U; + uint16_t requiredWorkgroupSize[3] = {0U, 0U, 0U}; + uint16_t crossThreadDataSize = 0U; + uint16_t perThreadDataSize = 0U; + uint16_t numArgsToPatch = 0U; + uint16_t numGrfRequired = 0U; + AddressingMode bufferAddressingMode = BindfulAndStateless; + AddressingMode imageAddressingMode = Bindful; + AddressingMode samplerAddressingMode = Bindful; + + uint8_t workgroupWalkOrder[3] = {0, 1, 2}; + uint8_t workgroupDimensionsOrder[3] = {0, 1, 2}; + + uint8_t gpuPointerSize = 0; + uint8_t simdSize = 8; + uint8_t grfSize = 32; + uint8_t numLocalIdChannels = 3; + + bool supportsBuffersBiggerThan4Gb() const { + return Stateless == bufferAddressingMode; + } + + union { + struct { + bool usesPrintf : 1; + bool usesBarriers : 1; + bool usesFencesForReadWriteImages : 1; + bool usesFlattenedLocalIds; + bool usesPrivateMemory : 1; + bool usesVme : 1; + bool usesImages : 1; + bool usesSamplers : 1; + bool usesDeviceSideEnqueue : 1; + bool usesSyncBuffer : 1; + bool useGlobalAtomics : 1; + bool usesStatelessWrites : 1; + bool passInlineData : 1; + bool perThreadDataHeaderIsPresent : 1; + bool perThreadDataUnusedGrfIsPresent : 1; + bool requiresDisabledMidThreadPreemption : 1; + bool requiresSubgroupIndependentForwardProgress : 1; + bool requiresWorkgroupWalkOrder : 1; + }; + uint32_t packed; + } flags; + static_assert(sizeof(KernelAttributes::flags) == sizeof(KernelAttributes::flags.packed), ""); + } kernelAttributes; + + struct { + InstructionsSegmentOffset skipPerThreadDataLoad = 0U; + InstructionsSegmentOffset skipSetFFIDGP = 0U; + InstructionsSegmentOffset systemKernel = 0U; + } entryPoints; + + struct PayloadMappings { + struct { + CrossThreadDataOffset globalWorkOffset[3] = {undefined, undefined, undefined}; + CrossThreadDataOffset globalWorkSize[3] = {undefined, undefined, undefined}; + CrossThreadDataOffset localWorkSize[3] = {undefined, undefined, undefined}; + CrossThreadDataOffset localWorkSize2[3] = {undefined, undefined, undefined}; + + CrossThreadDataOffset enqueuedLocalWorkSize[3] = {undefined, undefined, undefined}; + CrossThreadDataOffset numWorkGroups[3] = {undefined, undefined, undefined}; + CrossThreadDataOffset workDim = undefined; + } dispatchTraits; + + struct { + SurfaceStateHeapOffset tableOffset = undefined; + uint8_t numEntries = 0; + } bindingTable; + + struct { + DynamicStateHeapOffset tableOffset = undefined; + DynamicStateHeapOffset borderColor = undefined; + uint8_t numSamplers = 0; + } samplerTable; + + StackVec explicitArgs; + + struct { + ArgDescPointer printfSurfaceAddress; + ArgDescPointer globalVariablesSurfaceAddress; + ArgDescPointer globalConstantsSurfaceAddress; + ArgDescPointer privateMemoryAddress; + ArgDescPointer deviceSideEnqueueEventPoolSurfaceAddress; + ArgDescPointer deviceSideEnqueueDefaultQueueSurfaceAddress; + ArgDescPointer systemThreadSurfaceAddress; + ArgDescPointer syncBufferAddress; + CrossThreadDataOffset privateMemorySize = undefined; + CrossThreadDataOffset maxWorkGroupSize = undefined; + CrossThreadDataOffset simdSize = undefined; + CrossThreadDataOffset deviceSideEnqueueParentEvent = undefined; + CrossThreadDataOffset preferredWkgMultiple = undefined; + CrossThreadDataOffset localMemoryStatelessWindowSize = undefined; + CrossThreadDataOffset localMemoryStatelessWindowStartAddres = undefined; + } implicitArgs; + + std::vector> explicitArgsExtendedDescriptors; + } payloadMappings; + + std::vector explicitArgsExtendedMetadata; + + struct { + std::string kernelName; + std::string kernelLanguageAttributes; + StringMap printfStringsMap; + std::vector> deviceSideEnqueueChildrenKernelsIdOffset; + uint32_t deviceSideEnqueueBlockInterfaceDescriptorOffset = 0U; + + struct ByValueArgument { + ArgDescValue::Element byValueElement; + uint16_t argNum; + }; + StackVec allByValueKernelArguments; + + uint16_t compiledSubGroupsNumber = 0U; + uint8_t requiredSubGroupSize = 0U; + } kernelMetadata; + + struct { + std::unique_ptr debugData; + const void *igcInfoForGtpin = nullptr; + } external; +}; + +} // namespace NEO diff --git a/shared/source/utilities/stackvec.h b/shared/source/utilities/stackvec.h index 2f611bbcf1..34510d364f 100644 --- a/shared/source/utilities/stackvec.h +++ b/shared/source/utilities/stackvec.h @@ -12,26 +12,45 @@ #include #include #include +#include +#include +#include #include -template +template +struct StackVecSize { + static constexpr size_t max32 = std::numeric_limits::max(); + static constexpr size_t max16 = std::numeric_limits::max(); + static constexpr size_t max8 = std::numeric_limits::max(); + + using SizeT = std::conditional_t<(OnStackCapacity < max8), uint8_t, + std::conditional_t<(OnStackCapacity < max16), uint16_t, + std::conditional_t<(OnStackCapacity < max32), uint32_t, size_t>>>; +}; + +template ::SizeT> class StackVec { public: + using SizeT = StackSizeT; using iterator = DataType *; using const_iterator = const DataType *; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static const size_t onStackCaps = OnStackCapacity; + static constexpr SizeT onStackCaps = OnStackCapacity; - StackVec() = default; + StackVec() { + onStackMem = reinterpret_cast(onStackMemRawBytes); + } template - StackVec(ItType beginIt, ItType endIt) - : dynamicMem(nullptr) { + StackVec(ItType beginIt, ItType endIt) { + onStackMem = reinterpret_cast(onStackMemRawBytes); size_t count = (endIt - beginIt); if (count > OnStackCapacity) { dynamicMem = new std::vector(beginIt, endIt); + setUsesDynamicMem(); return; } @@ -39,13 +58,14 @@ class StackVec { push_back(*beginIt); ++beginIt; } - onStackSize = count; + onStackSize = static_cast(count); } - StackVec(const StackVec &rhs) - : dynamicMem(nullptr) { + StackVec(const StackVec &rhs) { + onStackMem = reinterpret_cast(onStackMemRawBytes); if (onStackCaps < rhs.size()) { dynamicMem = new std::vector(rhs.begin(), rhs.end()); + setUsesDynamicMem(); return; } @@ -56,10 +76,12 @@ class StackVec { explicit StackVec(size_t initialSize) : StackVec() { + onStackMem = reinterpret_cast(onStackMemRawBytes); resize(initialSize); } StackVec(std::initializer_list init) { + onStackMem = reinterpret_cast(onStackMemRawBytes); reserve(init.size()); for (const auto &obj : init) { push_back(obj); @@ -69,13 +91,14 @@ class StackVec { StackVec &operator=(const StackVec &rhs) { clear(); - if (this->dynamicMem != nullptr) { - this->dynamicMem->insert(dynamicMem->end(), rhs.begin(), rhs.end()); + if (usesDynamicMem()) { + this->dynamicMem->assign(rhs.begin(), rhs.end()); return *this; } if (onStackCaps < rhs.size()) { this->dynamicMem = new std::vector(rhs.begin(), rhs.end()); + setUsesDynamicMem(); return *this; } @@ -86,48 +109,57 @@ class StackVec { return *this; } - StackVec(StackVec &&rhs) - : dynamicMem(nullptr) { - if (rhs.dynamicMem != nullptr) { - std::swap(this->dynamicMem, rhs.dynamicMem); + StackVec(StackVec &&rhs) { + onStackMem = reinterpret_cast(onStackMemRawBytes); + if (rhs.usesDynamicMem()) { + this->dynamicMem = rhs.dynamicMem; + setUsesDynamicMem(); + rhs.onStackSize = 0U; return; } for (const auto &v : rhs) { push_back(v); } + rhs.clear(); } StackVec &operator=(StackVec &&rhs) { clear(); - if (rhs.dynamicMem != nullptr) { - std::swap(this->dynamicMem, rhs.dynamicMem); + if (rhs.usesDynamicMem()) { + if (usesDynamicMem()) { + delete this->dynamicMem; + } + this->dynamicMem = rhs.dynamicMem; + this->setUsesDynamicMem(); + rhs.onStackSize = 0U; return *this; } - if (this->dynamicMem != nullptr) { - this->dynamicMem->insert(this->dynamicMem->end(), rhs.begin(), rhs.end()); + if (usesDynamicMem()) { + this->dynamicMem->assign(rhs.begin(), rhs.end()); return *this; } for (const auto &v : rhs) { push_back(v); } + rhs.clear(); return *this; } ~StackVec() { - if (dynamicMem != nullptr) { + if (usesDynamicMem()) { delete dynamicMem; return; } - clear(); + clearStackObjects(); } size_t size() const { - if (dynamicMem) { + if (usesDynamicMem()) { return dynamicMem->size(); } return onStackSize; @@ -138,7 +170,7 @@ class StackVec { } size_t capacity() const { - if (dynamicMem) { + if (usesDynamicMem()) { return dynamicMem->capacity(); } return OnStackCapacity; @@ -152,7 +184,7 @@ class StackVec { } void clear() { - if (dynamicMem) { + if (usesDynamicMem()) { dynamicMem->clear(); return; } @@ -164,35 +196,35 @@ class StackVec { ensureDynamicMem(); } - if (dynamicMem) { + if (usesDynamicMem()) { dynamicMem->push_back(v); return; } - new (onStackMem + onStackSize) DataType(v); + new (reinterpret_cast(onStackMemRawBytes) + onStackSize) DataType(v); ++onStackSize; } DataType &operator[](std::size_t idx) { - if (dynamicMem) { + if (usesDynamicMem()) { return (*dynamicMem)[idx]; } - return *(onStackMem + idx); + return *(reinterpret_cast(onStackMemRawBytes) + idx); } const DataType &operator[](std::size_t idx) const { - if (dynamicMem) { + if (usesDynamicMem()) { return (*dynamicMem)[idx]; } - return *(onStackMem + idx); + return *(reinterpret_cast(onStackMemRawBytes) + idx); } iterator begin() { - if (dynamicMem) { + if (usesDynamicMem()) { return dynamicMem->data(); } - return onStackMem; + return reinterpret_cast(onStackMemRawBytes); } reverse_iterator rbegin() { @@ -204,19 +236,19 @@ class StackVec { } const_iterator begin() const { - if (dynamicMem) { + if (usesDynamicMem()) { return dynamicMem->data(); } - return onStackMem; + return reinterpret_cast(onStackMemRawBytes); } iterator end() { - if (dynamicMem) { + if (usesDynamicMem()) { return dynamicMem->data() + dynamicMem->size(); } - return onStackMem + onStackSize; + return reinterpret_cast(onStackMemRawBytes) + onStackSize; } reverse_iterator rend() { @@ -228,11 +260,11 @@ class StackVec { } const_iterator end() const { - if (dynamicMem) { + if (usesDynamicMem()) { return dynamicMem->data() + dynamicMem->size(); } - return onStackMem + onStackSize; + return reinterpret_cast(onStackMemRawBytes) + onStackSize; } void resize(size_t newSize) { @@ -243,7 +275,15 @@ class StackVec { resizeImpl(newSize, &value); } + bool usesDynamicMem() const { + return std::numeric_limits::max() == this->onStackSize; + } + private: + void setUsesDynamicMem() { + this->onStackSize = std::numeric_limits::max(); + } + void resizeImpl(size_t newSize, const DataType *value) { // new size does not fit into internal mem if (newSize > onStackCaps) { @@ -251,7 +291,7 @@ class StackVec { } // memory already backed by stl vector - if (dynamicMem != nullptr) { + if (usesDynamicMem()) { if (value != nullptr) { dynamicMem->resize(newSize, *value); } else { @@ -263,7 +303,7 @@ class StackVec { if (newSize <= onStackSize) { // trim elements clearStackObjects(newSize, onStackSize - newSize); - onStackSize = newSize; + onStackSize = static_cast(newSize); return; } @@ -271,29 +311,31 @@ class StackVec { if (value != nullptr) { // copy-construct elements while (onStackSize < newSize) { - new (onStackMem + onStackSize) DataType(*value); + new (reinterpret_cast(onStackMemRawBytes) + onStackSize) DataType(*value); ++onStackSize; } } else { // default-construct elements while (onStackSize < newSize) { - new (onStackMem + onStackSize) DataType(); + new (reinterpret_cast(onStackMemRawBytes) + onStackSize) DataType(); ++onStackSize; } } } void ensureDynamicMem() { - if (dynamicMem == nullptr) { - dynamicMem = new std::vector(); - if (onStackSize > 0) { - dynamicMem->reserve(onStackSize); - for (auto it = onStackMem, end = onStackMem + onStackSize; it != end; ++it) { - dynamicMem->push_back(std::move(*it)); - } - clearStackObjects(); - } + if (usesDynamicMem()) { + return; } + dynamicMem = new std::vector(); + if (onStackSize > 0) { + dynamicMem->reserve(onStackSize); + for (auto it = reinterpret_cast(onStackMemRawBytes), end = reinterpret_cast(onStackMemRawBytes) + onStackSize; it != end; ++it) { + dynamicMem->push_back(std::move(*it)); + } + clearStackObjects(); + } + setUsesDynamicMem(); } void clearStackObjects() { @@ -303,17 +345,26 @@ class StackVec { void clearStackObjects(size_t offset, size_t count) { UNRECOVERABLE_IF(offset + count > onStackSize); - for (auto it = onStackMem + offset, end = onStackMem + offset + count; it != end; ++it) { + for (auto it = reinterpret_cast(onStackMemRawBytes) + offset, end = reinterpret_cast(onStackMemRawBytes) + offset + count; it != end; ++it) { it->~DataType(); } } + union { + std::vector *dynamicMem; + DataType *onStackMem; + }; + alignas(alignof(DataType)) char onStackMemRawBytes[sizeof(DataType[onStackCaps])]; - std::vector *dynamicMem = nullptr; - DataType *const onStackMem = reinterpret_cast(onStackMemRawBytes); - size_t onStackSize = 0; + SizeT onStackSize = 0U; }; +namespace { +static_assert(sizeof(StackVec::SizeT) == 1u, ""); +static_assert(sizeof(StackVec) <= 16u, ""); +static_assert(sizeof(StackVec) <= 24u, ""); +} // namespace + template bool operator==(const StackVec &lhs, const StackVec &rhs) { diff --git a/shared/test/unit_test/kernel/CMakeLists.txt b/shared/test/unit_test/kernel/CMakeLists.txt new file mode 100644 index 0000000000..82c6159d11 --- /dev/null +++ b/shared/test/unit_test/kernel/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(NEO_SHARED_KERNEL_TESTS + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/kernel_arg_descriptor_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/kernel_arg_metadata_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/kernel_descriptor_tests.cpp +) + +set_property(GLOBAL PROPERTY NEO_SHARED_KERNEL_TESTS ${NEO_SHARED_KERNEL_TESTS}) + +add_subdirectories() \ No newline at end of file diff --git a/shared/test/unit_test/kernel/kernel_arg_descriptor_tests.cpp b/shared/test/unit_test/kernel/kernel_arg_descriptor_tests.cpp new file mode 100644 index 0000000000..926a2ab2d6 --- /dev/null +++ b/shared/test/unit_test/kernel/kernel_arg_descriptor_tests.cpp @@ -0,0 +1,515 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/kernel/kernel_arg_descriptor.h" + +#include "test.h" + +#include + +#include + +TEST(Undefined, GivenAnyTypeThenReturnsMaxValue) { + EXPECT_EQ(std::numeric_limits::max(), NEO::undefined); + EXPECT_EQ(std::numeric_limits::max(), NEO::undefined); + EXPECT_EQ(std::numeric_limits::max(), NEO::undefined); + EXPECT_EQ(std::numeric_limits::max(), NEO::undefined); +} + +TEST(IsUndefinedOffset, GivenAnyTypeThenComparesAgainstUndefined) { + EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined)); + EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined)); + EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined)); + EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined)); + + EXPECT_FALSE(NEO::isUndefinedOffset(NEO::undefined)); + EXPECT_FALSE(NEO::isUndefinedOffset(NEO::undefined)); + EXPECT_FALSE(NEO::isUndefinedOffset(NEO::undefined)); + + EXPECT_FALSE(NEO::isUndefinedOffset(0)); + EXPECT_FALSE(NEO::isUndefinedOffset(0)); + EXPECT_FALSE(NEO::isUndefinedOffset(0)); + EXPECT_FALSE(NEO::isUndefinedOffset(0)); +} + +TEST(IsValidOffset, GivenAnyTypeThenComparesAgainstUndefined) { + EXPECT_FALSE(NEO::isValidOffset(NEO::undefined)); + EXPECT_FALSE(NEO::isValidOffset(NEO::undefined)); + EXPECT_FALSE(NEO::isValidOffset(NEO::undefined)); + EXPECT_FALSE(NEO::isValidOffset(NEO::undefined)); + + EXPECT_TRUE(NEO::isValidOffset(NEO::undefined)); + EXPECT_TRUE(NEO::isValidOffset(NEO::undefined)); + EXPECT_TRUE(NEO::isValidOffset(NEO::undefined)); + + EXPECT_TRUE(NEO::isValidOffset(0)); + EXPECT_TRUE(NEO::isValidOffset(0)); + EXPECT_TRUE(NEO::isValidOffset(0)); + EXPECT_TRUE(NEO::isValidOffset(0)); +} + +TEST(ArgDescPointer, WhenDefaultInitializedThenOffsetsAreUndefined) { + NEO::ArgDescPointer argPtr; + EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.bindful)); + EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.stateless)); + EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.bindless)); + EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.bufferOffset)); + EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.slmOffset)); + + EXPECT_EQ(0U, argPtr.requiredSlmAlignment); + EXPECT_EQ(0U, argPtr.pointerSize); + EXPECT_TRUE(argPtr.accessedUsingStatelessAddressingMode); +} + +TEST(ArgDescPointerIsPureStateful, WhenQueriedThenReturnsTrueIfPointerIsNotAccessedInStatelessManner) { + NEO::ArgDescPointer argPtr; + argPtr.accessedUsingStatelessAddressingMode = true; + EXPECT_FALSE(argPtr.isPureStateful()); + + argPtr.accessedUsingStatelessAddressingMode = false; + EXPECT_TRUE(argPtr.isPureStateful()); +} + +TEST(ArgDescImage, WhenDefaultInitializedThenOffsetsAreUndefined) { + NEO::ArgDescImage argImage; + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.bindful)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.bindless)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.imgWidth)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.imgHeight)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.imgDepth)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.channelDataType)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.channelOrder)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.arraySize)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.numSamples)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.numMipLevels)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatBaseOffset)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatWidth)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatHeight)); + EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatPitch)); +} + +TEST(ArgDescSampler, WhenDefaultInitializedThenOffsetsAreUndefined) { + NEO::ArgDescSampler argSampler; + EXPECT_EQ(0U, argSampler.samplerType); + EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.bindful)); + EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.bindless)); + EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.metadataPayload.samplerSnapWa)); + EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.metadataPayload.samplerAddressingMode)); + EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.metadataPayload.samplerNormalizedCoords)); +} + +TEST(ArgDescValue, WhenDefaultInitializedThenOffsetsAreUndefined) { + NEO::ArgDescValue argValue; + EXPECT_TRUE(argValue.elements.empty()); + + NEO::ArgDescValue::Element argValueElement; + EXPECT_TRUE(NEO::isUndefinedOffset(argValueElement.offset)); + EXPECT_EQ(0U, argValueElement.size); + EXPECT_EQ(0U, argValueElement.sourceOffset); +} + +TEST(ArgDescriptor, WhenDefaultInitializedThenTypeIsUnknown) { + NEO::ArgDescriptor arg; + EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, arg.type); +} + +TEST(ArgDescriptorExtendedTypeInfo, WhenDefaultInitializedThenFlagsAreCleared) { + NEO::ArgDescriptor::ExtendedTypeInfo argExtendedTypeInfo; + EXPECT_EQ(0U, argExtendedTypeInfo.packed); + + NEO::ArgDescriptor arg; + EXPECT_EQ(0U, arg.getExtendedTypeInfo().packed); + EXPECT_EQ(&arg.getExtendedTypeInfo(), &const_cast(arg).getExtendedTypeInfo()); +} + +TEST(ArgDescriptorGetTraits, WhenDefaultInitializedThenTraitsAreCleared) { + NEO::ArgTypeTraits expected; + NEO::ArgDescriptor arg; + NEO::ArgTypeTraits &got = arg.getTraits(); + EXPECT_EQ(expected.accessQualifier, got.accessQualifier); + EXPECT_EQ(expected.addressQualifier, got.addressQualifier); + EXPECT_EQ(expected.argByValSize, got.argByValSize); + EXPECT_EQ(expected.typeQualifiers.packed, got.typeQualifiers.packed); + EXPECT_EQ(&arg.getTraits(), &const_cast(arg).getTraits()); +} + +TEST(ArgDescriptorIsReadOnly, GivenImageArgWhenAccessQualifierIsReadOnlyThenReturnsTrue) { + NEO::ArgDescriptor arg; + arg.as(true); + arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessReadOnly; + EXPECT_TRUE(arg.isReadOnly()); + + arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessNone; + EXPECT_FALSE(arg.isReadOnly()); + arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessReadWrite; + EXPECT_FALSE(arg.isReadOnly()); + arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessWriteOnly; + EXPECT_FALSE(arg.isReadOnly()); + arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessUnknown; + EXPECT_FALSE(arg.isReadOnly()); +} + +TEST(ArgDescriptorIsReadOnly, GivenPointerArgWhenConstQualifiedThenReturnsTrue) { + NEO::ArgDescriptor arg; + arg.as(true); + arg.getTraits().typeQualifiers.constQual = true; + EXPECT_TRUE(arg.isReadOnly()); + + arg.getTraits().typeQualifiers.constQual = false; + EXPECT_FALSE(arg.isReadOnly()); +} + +TEST(ArgDescriptorIsReadOnly, GivenPointerArgWhenConstantAddressSpaceThenReturnsTrue) { + NEO::ArgDescriptor arg; + arg.as(true); + arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrConstant; + EXPECT_TRUE(arg.isReadOnly()); + + arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrGlobal; + EXPECT_FALSE(arg.isReadOnly()); + + arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrLocal; + EXPECT_FALSE(arg.isReadOnly()); + + arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrPrivate; + EXPECT_FALSE(arg.isReadOnly()); + + arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrUnknown; + EXPECT_FALSE(arg.isReadOnly()); +} + +TEST(ArgDescriptorIsReadOnly, GivenSamplerArgThenReturnsTrue) { + NEO::ArgDescriptor arg; + arg.as(true); + EXPECT_TRUE(arg.isReadOnly()); +} + +TEST(ArgDescriptorIsReadOnly, GivenValueArgThenReturnsTrue) { + NEO::ArgDescriptor arg; + arg.as(true); + EXPECT_TRUE(arg.isReadOnly()); +} + +TEST(ArgDescriptorIs, WhenQueriedThenComparesAgainstStoredArgType) { + NEO::ArgDescriptor args[] = {{NEO::ArgDescriptor::ArgTPointer}, + {NEO::ArgDescriptor::ArgTImage}, + {NEO::ArgDescriptor::ArgTSampler}, + {NEO::ArgDescriptor::ArgTValue}}; + for (const auto &arg : args) { + EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTPointer, arg.is()); + EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTImage, arg.is()); + EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTSampler, arg.is()); + EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTValue, arg.is()); + } +} + +TEST(ArgDescriptorAs, GivenUninitializedArgWhenInitializationRequestedThenInitializesTheArg) { + NEO::ArgDescriptor argPointer; + NEO::ArgDescriptor argImage; + NEO::ArgDescriptor argSampler; + NEO::ArgDescriptor argValue; + + argPointer.as(true); + argImage.as(true); + argSampler.as(true); + argValue.as(true); + EXPECT_EQ(NEO::ArgDescriptor::ArgTPointer, argPointer.type); + EXPECT_EQ(NEO::ArgDescriptor::ArgTImage, argImage.type); + EXPECT_EQ(NEO::ArgDescriptor::ArgTSampler, argSampler.type); + EXPECT_EQ(NEO::ArgDescriptor::ArgTValue, argValue.type); +} + +TEST(ArgDescriptorAs, GivenUninitializedArgWhenInitializationNotRequestedThenAborts) { + NEO::ArgDescriptor argPointer; + NEO::ArgDescriptor argImage; + NEO::ArgDescriptor argSampler; + NEO::ArgDescriptor argValue; + + EXPECT_THROW(argPointer.as(false), std::exception); + EXPECT_THROW(argImage.as(false), std::exception); + EXPECT_THROW(argSampler.as(false), std::exception); + EXPECT_THROW(argValue.as(false), std::exception); + EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argPointer.type); + EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argImage.type); + EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argSampler.type); + EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argValue.type); +} + +TEST(ArgDescriptorAs, GivenMismatchedArgTypeThenAborts) { + NEO::ArgDescriptor argPointer; + NEO::ArgDescriptor argImage; + NEO::ArgDescriptor argSampler; + NEO::ArgDescriptor argValue; + + argPointer.as(true); + argImage.as(true); + argSampler.as(true); + argValue.as(true); + + EXPECT_NO_THROW(argPointer.as()); + EXPECT_NO_THROW(argImage.as()); + EXPECT_NO_THROW(argSampler.as()); + EXPECT_NO_THROW(argValue.as()); + + EXPECT_THROW(argPointer.as(), std::exception); + EXPECT_THROW(argPointer.as(), std::exception); + EXPECT_THROW(argPointer.as(), std::exception); + + EXPECT_THROW(argImage.as(), std::exception); + EXPECT_THROW(argImage.as(), std::exception); + EXPECT_THROW(argImage.as(), std::exception); + + EXPECT_THROW(argSampler.as(), std::exception); + EXPECT_THROW(argSampler.as(), std::exception); + EXPECT_THROW(argSampler.as(), std::exception); + + EXPECT_THROW(argValue.as(), std::exception); + EXPECT_THROW(argValue.as(), std::exception); + EXPECT_THROW(argValue.as(), std::exception); + + EXPECT_NO_THROW(const_cast(argPointer).as()); + EXPECT_NO_THROW(const_cast(argImage).as()); + EXPECT_NO_THROW(const_cast(argSampler).as()); + EXPECT_NO_THROW(const_cast(argValue).as()); + + EXPECT_THROW(const_cast(argPointer).as(), std::exception); + EXPECT_THROW(const_cast(argPointer).as(), std::exception); + EXPECT_THROW(const_cast(argPointer).as(), std::exception); + + EXPECT_THROW(const_cast(argImage).as(), std::exception); + EXPECT_THROW(const_cast(argImage).as(), std::exception); + EXPECT_THROW(const_cast(argImage).as(), std::exception); + + EXPECT_THROW(const_cast(argSampler).as(), std::exception); + EXPECT_THROW(const_cast(argSampler).as(), std::exception); + EXPECT_THROW(const_cast(argSampler).as(), std::exception); + + EXPECT_THROW(const_cast(argValue).as(), std::exception); + EXPECT_THROW(const_cast(argValue).as(), std::exception); + EXPECT_THROW(const_cast(argValue).as(), std::exception); +} + +TEST(ArgDescriptorCopyAssign, WhenCopyAssignedThenCopiesExtendedTypeInfo) { + NEO::ArgDescriptor arg0; + arg0.getExtendedTypeInfo().isAccelerator = true; + arg0.getExtendedTypeInfo().hasDeviceSideEnqueueExtendedDescriptor = true; + + NEO::ArgDescriptor arg2; + arg2 = arg0; + EXPECT_EQ(arg0.getExtendedTypeInfo().packed, arg2.getExtendedTypeInfo().packed); +} + +TEST(ArgDescriptorCopyAssign, WhenCopyAssignedThenCopiesTraits) { + NEO::ArgDescriptor arg0; + arg0.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessWriteOnly; + arg0.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrLocal; + arg0.getTraits().argByValSize = 3; + arg0.getTraits().typeQualifiers.restrictQual = true; + + NEO::ArgDescriptor arg2; + arg2 = arg0; + EXPECT_EQ(arg0.getTraits().accessQualifier, arg2.getTraits().accessQualifier); + EXPECT_EQ(arg0.getTraits().addressQualifier, arg2.getTraits().addressQualifier); + EXPECT_EQ(arg0.getTraits().argByValSize, arg2.getTraits().argByValSize); + EXPECT_EQ(arg0.getTraits().typeQualifiers.packed, arg2.getTraits().typeQualifiers.packed); +} + +TEST(ArgDescriptorCopyAssign, GivenPointerArgWhenCopyAssignedThenCopiesDataBasedOnArgType) { + NEO::ArgDescriptor arg0; + auto &argPointer = arg0.as(true); + argPointer.bindful = 2; + argPointer.stateless = 3; + argPointer.bindless = 5; + argPointer.bufferOffset = 7; + argPointer.slmOffset = 11; + argPointer.requiredSlmAlignment = 13; + argPointer.pointerSize = 17; + argPointer.accessedUsingStatelessAddressingMode = false; + + NEO::ArgDescriptor arg2; + arg2 = arg0; + EXPECT_EQ(argPointer.bindful, arg2.as().bindful); + EXPECT_EQ(argPointer.stateless, arg2.as().stateless); + EXPECT_EQ(argPointer.bindless, arg2.as().bindless); + EXPECT_EQ(argPointer.bufferOffset, arg2.as().bufferOffset); + EXPECT_EQ(argPointer.slmOffset, arg2.as().slmOffset); + EXPECT_EQ(argPointer.requiredSlmAlignment, arg2.as().requiredSlmAlignment); + EXPECT_EQ(argPointer.pointerSize, arg2.as().pointerSize); + EXPECT_EQ(argPointer.accessedUsingStatelessAddressingMode, arg2.as().accessedUsingStatelessAddressingMode); +} + +TEST(ArgDescriptorCopyAssign, GivenImageArgWhenCopyAssignedThenCopiesDataBasedOnArgType) { + NEO::ArgDescriptor arg0; + auto &argImage = arg0.as(true); + argImage.bindful = 2; + argImage.bindless = 3; + + argImage.metadataPayload.imgWidth = 5; + argImage.metadataPayload.imgHeight = 7; + argImage.metadataPayload.imgDepth = 11; + argImage.metadataPayload.channelDataType = 13; + argImage.metadataPayload.channelOrder = 17; + + argImage.metadataPayload.arraySize = 19; + argImage.metadataPayload.numSamples = 23; + argImage.metadataPayload.numMipLevels = 29; + + argImage.metadataPayload.flatBaseOffset = 31; + argImage.metadataPayload.flatWidth = 37; + argImage.metadataPayload.flatHeight = 41; + argImage.metadataPayload.flatPitch = 43; + + NEO::ArgDescriptor arg2; + arg2 = arg0; + EXPECT_EQ(argImage.metadataPayload.imgWidth, arg2.as().metadataPayload.imgWidth); + EXPECT_EQ(argImage.metadataPayload.imgHeight, arg2.as().metadataPayload.imgHeight); + EXPECT_EQ(argImage.metadataPayload.imgDepth, arg2.as().metadataPayload.imgDepth); + EXPECT_EQ(argImage.metadataPayload.channelDataType, arg2.as().metadataPayload.channelDataType); + EXPECT_EQ(argImage.metadataPayload.channelOrder, arg2.as().metadataPayload.channelOrder); + EXPECT_EQ(argImage.metadataPayload.arraySize, arg2.as().metadataPayload.arraySize); + EXPECT_EQ(argImage.metadataPayload.numSamples, arg2.as().metadataPayload.numSamples); + EXPECT_EQ(argImage.metadataPayload.numMipLevels, arg2.as().metadataPayload.numMipLevels); + EXPECT_EQ(argImage.metadataPayload.flatBaseOffset, arg2.as().metadataPayload.flatBaseOffset); + EXPECT_EQ(argImage.metadataPayload.flatWidth, arg2.as().metadataPayload.flatWidth); + EXPECT_EQ(argImage.metadataPayload.flatHeight, arg2.as().metadataPayload.flatHeight); + EXPECT_EQ(argImage.metadataPayload.flatPitch, arg2.as().metadataPayload.flatPitch); +} + +TEST(ArgDescriptorCopyAssign, GivenSamplerArgWhenCopyAssignedThenCopiesDataBasedOnArgType) { + NEO::ArgDescriptor arg0; + auto &argSampler = arg0.as(true); + argSampler.samplerType = 2; + argSampler.bindful = 3; + argSampler.bindless = 5; + argSampler.metadataPayload.samplerSnapWa = 7; + argSampler.metadataPayload.samplerAddressingMode = 11; + argSampler.metadataPayload.samplerNormalizedCoords = 13; + + NEO::ArgDescriptor arg2; + arg2 = arg0; + EXPECT_EQ(argSampler.samplerType, arg2.as().samplerType); + EXPECT_EQ(argSampler.bindful, arg2.as().bindful); + EXPECT_EQ(argSampler.bindless, arg2.as().bindless); + EXPECT_EQ(argSampler.metadataPayload.samplerSnapWa, arg2.as().metadataPayload.samplerSnapWa); + EXPECT_EQ(argSampler.metadataPayload.samplerAddressingMode, arg2.as().metadataPayload.samplerAddressingMode); + EXPECT_EQ(argSampler.metadataPayload.samplerNormalizedCoords, arg2.as().metadataPayload.samplerNormalizedCoords); +} + +TEST(ArgDescriptorCopyAssign, GivenValueArgWhenCopyAssignedThenCopiesDataBasedOnArgType) { + NEO::ArgDescValue::Element element0; + element0.offset = 2; + element0.size = 3; + element0.sourceOffset = 5; + + NEO::ArgDescValue::Element element1; + element1.offset = 7; + element1.size = 11; + element1.sourceOffset = 13; + + NEO::ArgDescriptor arg0; + auto &argValue = arg0.as(true); + argValue.elements.push_back(element0); + argValue.elements.push_back(element1); + + NEO::ArgDescriptor arg2; + arg2 = arg0; + ASSERT_EQ(argValue.elements.size(), arg2.as().elements.size()); + for (size_t i = 0; i < argValue.elements.size(); ++i) { + EXPECT_EQ(argValue.elements[i].offset, arg2.as().elements[i].offset) << i; + EXPECT_EQ(argValue.elements[i].offset, arg2.as().elements[i].offset) << i; + EXPECT_EQ(argValue.elements[i].offset, arg2.as().elements[i].offset) << i; + } +} + +TEST(SetOffsetsVec, GivenArrayOfCrossThreadDataThenCopiesProperAmountOfElements) { + NEO::CrossThreadDataOffset src[3] = {2, 3, 5}; + NEO::CrossThreadDataOffset dst[3] = {7, 11, 13}; + NEO::setOffsetsVec(dst, src); + EXPECT_EQ(dst[0], src[0]); + EXPECT_EQ(dst[1], src[1]); + EXPECT_EQ(dst[2], src[2]); +} + +TEST(PatchNonPointer, GivenUndefinedOffsetThenReturnsFalse) { + uint8_t buffer[64]; + uint32_t value = 7; + EXPECT_FALSE(NEO::patchNonPointer(buffer, NEO::undefined, value)); +} + +TEST(PatchNonPointer, GivenOutOfBoundsOffsetThenAbort) { + uint8_t buffer[64]; + uint32_t value = 7; + EXPECT_THROW(NEO::patchNonPointer(buffer, sizeof(buffer), value), std::exception); + EXPECT_THROW(NEO::patchNonPointer(buffer, sizeof(buffer) - sizeof(value) + 1, value), std::exception); +} + +TEST(PatchNonPointer, GivenValidOffsetThenPatchProperly) { + alignas(8) uint8_t buffer[64]; + memset(buffer, 3, sizeof(buffer)); + uint32_t value32 = 7; + uint64_t value64 = 13; + EXPECT_TRUE(NEO::patchNonPointer(buffer, 0, value32)); + EXPECT_TRUE(NEO::patchNonPointer(buffer, 8, value64)); + EXPECT_TRUE(NEO::patchNonPointer(buffer, sizeof(buffer) - sizeof(value64), value64)); + + alignas(8) uint8_t expected[64]; + memset(expected, 3, sizeof(expected)); + *reinterpret_cast(expected) = value32; + *reinterpret_cast(expected + 8) = value64; + *reinterpret_cast(expected + sizeof(expected) - sizeof(value64)) = value64; + EXPECT_EQ(0, memcmp(expected, buffer, sizeof(buffer))); +} + +TEST(PatchVecNonPointer, GivenArrayOfOffsetsThenReturnsNumberOfValuesProperlyPatched) { + alignas(8) uint8_t buffer[64]; + memset(buffer, 3, sizeof(buffer)); + NEO::CrossThreadDataOffset offsets[] = {0, 4, sizeof(buffer) - sizeof(uint32_t), NEO::undefined}; + uint32_t values[] = {7, 11, 13, 17}; + auto numPatched = NEO::patchVecNonPointer(buffer, offsets, values); + EXPECT_EQ(3U, numPatched); + alignas(8) uint8_t expected[64]; + memset(expected, 3, sizeof(expected)); + *reinterpret_cast(expected) = 7; + *reinterpret_cast(expected + 4) = 11; + *reinterpret_cast(expected + sizeof(expected) - sizeof(uint32_t)) = 13; + EXPECT_EQ(0, memcmp(expected, buffer, sizeof(buffer))); +} + +TEST(PatchPointer, GivenUnhandledPointerSizeThenAborts) { + alignas(8) uint8_t buffer[64]; + memset(buffer, 3, sizeof(buffer)); + NEO::ArgDescPointer ptrArg; + uintptr_t ptrValue = reinterpret_cast(&ptrArg); + ptrArg.pointerSize = 5; + EXPECT_THROW(patchPointer(buffer, ptrArg, ptrValue), std::exception); +} + +TEST(PatchPointer, Given32bitPointerSizeThenPatchesOnly32bits) { + alignas(8) uint8_t buffer[64]; + memset(buffer, 3, sizeof(buffer)); + NEO::ArgDescPointer ptrArg; + uintptr_t ptrValue = reinterpret_cast(&ptrArg); + ptrArg.stateless = 0U; + ptrArg.pointerSize = 4; + EXPECT_TRUE(patchPointer(buffer, ptrArg, ptrValue)); + alignas(8) uint8_t expected[64]; + memset(expected, 3, sizeof(expected)); + *reinterpret_cast(expected) = static_cast(ptrValue); +} + +TEST(PatchPointer, Given64bitPointerSizeThenPatchesAll64bits) { + alignas(8) uint8_t buffer[64]; + memset(buffer, 3, sizeof(buffer)); + NEO::ArgDescPointer ptrArg; + uintptr_t ptrValue = reinterpret_cast(&ptrArg); + ptrArg.stateless = 0U; + ptrArg.pointerSize = 8; + EXPECT_TRUE(patchPointer(buffer, ptrArg, ptrValue)); + alignas(8) uint8_t expected[64]; + memset(expected, 3, sizeof(expected)); + *reinterpret_cast(expected) = static_cast(ptrValue); +} diff --git a/shared/test/unit_test/kernel/kernel_arg_metadata_tests.cpp b/shared/test/unit_test/kernel/kernel_arg_metadata_tests.cpp new file mode 100644 index 0000000000..aac18982ef --- /dev/null +++ b/shared/test/unit_test/kernel/kernel_arg_metadata_tests.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/kernel/kernel_arg_metadata.h" + +#include "test.h" + +TEST(KernelArgMetadata, WhenParseAccessQualifierIsCalledThenQualifierIsProperlyParsed) { + using namespace NEO; + using namespace NEO::KernelArgMetadata; + EXPECT_EQ(AccessNone, KernelArgMetadata::parseAccessQualifier("")); + EXPECT_EQ(AccessNone, KernelArgMetadata::parseAccessQualifier("NONE")); + EXPECT_EQ(AccessReadOnly, KernelArgMetadata::parseAccessQualifier("read_only")); + EXPECT_EQ(AccessWriteOnly, KernelArgMetadata::parseAccessQualifier("write_only")); + EXPECT_EQ(AccessReadWrite, KernelArgMetadata::parseAccessQualifier("read_write")); + EXPECT_EQ(AccessReadOnly, KernelArgMetadata::parseAccessQualifier("__read_only")); + EXPECT_EQ(AccessWriteOnly, KernelArgMetadata::parseAccessQualifier("__write_only")); + EXPECT_EQ(AccessReadWrite, KernelArgMetadata::parseAccessQualifier("__read_write")); + + EXPECT_EQ(AccessUnknown, KernelArgMetadata::parseAccessQualifier("re")); + EXPECT_EQ(AccessUnknown, KernelArgMetadata::parseAccessQualifier("read")); + EXPECT_EQ(AccessUnknown, KernelArgMetadata::parseAccessQualifier("write")); +} + +TEST(KernelArgMetadata, WhenParseAddressQualifierIsCalledThenQualifierIsProperlyParsed) { + using namespace NEO; + using namespace NEO::KernelArgMetadata; + EXPECT_EQ(AddrGlobal, KernelArgMetadata::parseAddressSpace("")); + EXPECT_EQ(AddrGlobal, KernelArgMetadata::parseAddressSpace("__global")); + EXPECT_EQ(AddrLocal, KernelArgMetadata::parseAddressSpace("__local")); + EXPECT_EQ(AddrPrivate, KernelArgMetadata::parseAddressSpace("__private")); + EXPECT_EQ(AddrConstant, KernelArgMetadata::parseAddressSpace("__constant")); + EXPECT_EQ(AddrPrivate, KernelArgMetadata::parseAddressSpace("not_specified")); + + EXPECT_EQ(AddrUnknown, KernelArgMetadata::parseAddressSpace("wrong")); + EXPECT_EQ(AddrUnknown, KernelArgMetadata::parseAddressSpace("__glob")); + EXPECT_EQ(AddrUnknown, KernelArgMetadata::parseAddressSpace("__loc")); + EXPECT_EQ(AddrUnknown, KernelArgMetadata::parseAddressSpace("__priv")); + EXPECT_EQ(AddrUnknown, KernelArgMetadata::parseAddressSpace("__const")); + EXPECT_EQ(AddrUnknown, KernelArgMetadata::parseAddressSpace("not")); +} + +TEST(KernelArgMetadata, WhenParseTypeQualifiersIsCalledThenQualifierIsProperlyParsed) { + using namespace NEO; + using namespace NEO::KernelArgMetadata; + + TypeQualifiers qual = {}; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("").packed); + + qual = {}; + qual.constQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("const").packed); + + qual = {}; + qual.volatileQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("volatile").packed); + + qual = {}; + qual.restrictQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("restrict").packed); + + qual = {}; + qual.pipeQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe").packed); + + qual = {}; + qual.unknownQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("inval").packed); + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("cons").packed); + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("volat").packed); + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("restr").packed); + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pip").packed); + + qual = {}; + qual.constQual = true; + qual.volatileQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("const volatile").packed); + + qual = {}; + qual.constQual = true; + qual.volatileQual = true; + qual.restrictQual = true; + qual.pipeQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe const restrict volatile").packed); + + qual = {}; + qual.constQual = true; + qual.volatileQual = true; + qual.restrictQual = true; + qual.pipeQual = true; + qual.unknownQual = true; + EXPECT_EQ(qual.packed, KernelArgMetadata::parseTypeQualifiers("pipe const restrict volatile some").packed); +} + +TEST(KernelArgMetadata, WhenParseLimitedStringIsCalledThenReturnedStringDoesntContainExcessiveTrailingZeroes) { + char str1[] = "abcd\0\0\0after\0"; + EXPECT_STREQ("abcd", NEO::parseLimitedString(str1, sizeof(str1)).c_str()); + EXPECT_EQ(4U, NEO::parseLimitedString(str1, sizeof(str1)).size()); + + EXPECT_STREQ("ab", NEO::parseLimitedString(str1, 2).c_str()); + EXPECT_EQ(2U, NEO::parseLimitedString(str1, 2).size()); + + char str2[] = {'a', 'b', 'd', 'e', 'f'}; + EXPECT_STREQ("abdef", NEO::parseLimitedString(str2, sizeof(str2)).c_str()); + EXPECT_EQ(5U, NEO::parseLimitedString(str2, sizeof(str2)).size()); +} + +TEST(TypeQualifiers, WhenDefaultInitialiedThenFlagsAreCleared) { + NEO::KernelArgMetadata::TypeQualifiers qual; + EXPECT_EQ(0U, qual.packed); +} + +TEST(TypeQualifiersEmpty, WhenQueriedThenReturnsTrueIfCleared) { + NEO::KernelArgMetadata::TypeQualifiers qual; + qual.packed = 0U; + EXPECT_TRUE(qual.empty()); + + qual.constQual = true; + EXPECT_FALSE(qual.empty()); +} + +TEST(ArgTypeTraits, WhenDefaultInitialiedThenValuesAreClearedAndAddressSpaceIsGlobal) { + NEO::ArgTypeTraits argTraits; + EXPECT_EQ(0U, argTraits.argByValSize); + EXPECT_EQ(NEO::KernelArgMetadata::AccessUnknown, argTraits.getAccessQualifier()); + EXPECT_EQ(NEO::KernelArgMetadata::AddrGlobal, argTraits.getAddressQualifier()); + EXPECT_TRUE(argTraits.typeQualifiers.empty()); +} diff --git a/shared/test/unit_test/kernel/kernel_descriptor_tests.cpp b/shared/test/unit_test/kernel/kernel_descriptor_tests.cpp new file mode 100644 index 0000000000..bc484368b1 --- /dev/null +++ b/shared/test/unit_test/kernel/kernel_descriptor_tests.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/kernel/kernel_arg_descriptor.h" +#include "shared/source/kernel/kernel_descriptor.h" + +#include "test.h" + +TEST(KernelDescriptor, WhenDefaultInitializedThenValuesAreCleared) { + NEO::KernelDescriptor desc; + EXPECT_EQ(0U, desc.kernelAttributes.flags.packed); + EXPECT_EQ(0U, desc.kernelAttributes.slmInlineSize); + EXPECT_EQ(0U, desc.kernelAttributes.perThreadScratchSize[0]); + EXPECT_EQ(0U, desc.kernelAttributes.perThreadScratchSize[1]); + EXPECT_EQ(0U, desc.kernelAttributes.perThreadPrivateMemorySize); + EXPECT_EQ(0U, desc.kernelAttributes.perThreadSystemThreadSurfaceSize); + EXPECT_EQ(0U, desc.kernelAttributes.requiredWorkgroupSize[0]); + EXPECT_EQ(0U, desc.kernelAttributes.requiredWorkgroupSize[1]); + EXPECT_EQ(0U, desc.kernelAttributes.requiredWorkgroupSize[2]); + EXPECT_EQ(0U, desc.kernelAttributes.crossThreadDataSize); + EXPECT_EQ(0U, desc.kernelAttributes.perThreadDataSize); + EXPECT_EQ(0U, desc.kernelAttributes.numArgsToPatch); + EXPECT_EQ(0U, desc.kernelAttributes.numGrfRequired); + EXPECT_EQ(NEO::KernelDescriptor::BindfulAndStateless, desc.kernelAttributes.bufferAddressingMode); + EXPECT_EQ(NEO::KernelDescriptor::Bindful, desc.kernelAttributes.imageAddressingMode); + EXPECT_EQ(NEO::KernelDescriptor::Bindful, desc.kernelAttributes.samplerAddressingMode); + EXPECT_EQ(0U, desc.kernelAttributes.workgroupWalkOrder[0]); + EXPECT_EQ(1U, desc.kernelAttributes.workgroupWalkOrder[1]); + EXPECT_EQ(2U, desc.kernelAttributes.workgroupWalkOrder[2]); + EXPECT_EQ(0U, desc.kernelAttributes.workgroupDimensionsOrder[0]); + EXPECT_EQ(1U, desc.kernelAttributes.workgroupDimensionsOrder[1]); + EXPECT_EQ(2U, desc.kernelAttributes.workgroupDimensionsOrder[2]); + EXPECT_EQ(0U, desc.kernelAttributes.gpuPointerSize); + EXPECT_EQ(8U, desc.kernelAttributes.simdSize); + EXPECT_EQ(32U, desc.kernelAttributes.grfSize); + EXPECT_EQ(3U, desc.kernelAttributes.numLocalIdChannels); + + EXPECT_EQ(0U, desc.entryPoints.skipPerThreadDataLoad); + EXPECT_EQ(0U, desc.entryPoints.skipSetFFIDGP); + EXPECT_EQ(0U, desc.entryPoints.systemKernel); + + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.globalWorkOffset[0]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.globalWorkOffset[1]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.globalWorkOffset[2]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.globalWorkSize[0]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.globalWorkSize[1]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.globalWorkSize[2]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.localWorkSize[0]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.localWorkSize[1]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.localWorkSize[2]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.localWorkSize2[0]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.localWorkSize2[1]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.localWorkSize2[2]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.enqueuedLocalWorkSize[0]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.enqueuedLocalWorkSize[1]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.enqueuedLocalWorkSize[2]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.numWorkGroups[0]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.numWorkGroups[1]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.numWorkGroups[2]); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.dispatchTraits.workDim); + + EXPECT_EQ(NEO::undefined, desc.payloadMappings.bindingTable.tableOffset); + EXPECT_EQ(0U, desc.payloadMappings.bindingTable.numEntries); + + EXPECT_EQ(NEO::undefined, desc.payloadMappings.samplerTable.tableOffset); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.samplerTable.borderColor); + EXPECT_EQ(0U, desc.payloadMappings.samplerTable.numSamplers); + + EXPECT_EQ(0U, desc.payloadMappings.explicitArgs.size()); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.implicitArgs.privateMemorySize); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.implicitArgs.maxWorkGroupSize); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.implicitArgs.simdSize); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.implicitArgs.deviceSideEnqueueParentEvent); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.implicitArgs.preferredWkgMultiple); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.implicitArgs.localMemoryStatelessWindowSize); + EXPECT_EQ(NEO::undefined, desc.payloadMappings.implicitArgs.localMemoryStatelessWindowStartAddres); + + EXPECT_EQ(0U, desc.payloadMappings.explicitArgsExtendedDescriptors.size()); + + EXPECT_TRUE(desc.kernelMetadata.kernelName.empty()); + EXPECT_TRUE(desc.kernelMetadata.kernelLanguageAttributes.empty()); + EXPECT_TRUE(desc.kernelMetadata.printfStringsMap.empty()); + EXPECT_TRUE(desc.kernelMetadata.deviceSideEnqueueChildrenKernelsIdOffset.empty()); + EXPECT_EQ(0U, desc.kernelMetadata.deviceSideEnqueueBlockInterfaceDescriptorOffset); + EXPECT_TRUE(desc.kernelMetadata.allByValueKernelArguments.empty()); + EXPECT_EQ(0U, desc.kernelMetadata.compiledSubGroupsNumber); + EXPECT_EQ(0U, desc.kernelMetadata.requiredSubGroupSize); + EXPECT_EQ(nullptr, desc.external.debugData.get()); + EXPECT_EQ(nullptr, desc.external.igcInfoForGtpin); +} + +TEST(KernelDescriptorAttributesSupportsBuffersBiggerThan4Gb, GivenPureStatelessBufferAddressingThenReturnTrue) { + NEO::KernelDescriptor desc; + desc.kernelAttributes.bufferAddressingMode = NEO::KernelDescriptor::Stateless; + EXPECT_TRUE(desc.kernelAttributes.supportsBuffersBiggerThan4Gb()); +} + +TEST(KernelDescriptorAttributesSupportsBuffersBiggerThan4Gb, GiveStatefulBufferAddressingThenReturnFalse) { + NEO::KernelDescriptor desc; + desc.kernelAttributes.bufferAddressingMode = NEO::KernelDescriptor::Bindful; + EXPECT_FALSE(desc.kernelAttributes.supportsBuffersBiggerThan4Gb()); + desc.kernelAttributes.bufferAddressingMode = NEO::KernelDescriptor::BindfulAndStateless; + EXPECT_FALSE(desc.kernelAttributes.supportsBuffersBiggerThan4Gb()); + desc.kernelAttributes.bufferAddressingMode = NEO::KernelDescriptor::Bindless; + EXPECT_FALSE(desc.kernelAttributes.supportsBuffersBiggerThan4Gb()); + desc.kernelAttributes.bufferAddressingMode = NEO::KernelDescriptor::BindlessAndStateless; + EXPECT_FALSE(desc.kernelAttributes.supportsBuffersBiggerThan4Gb()); +}