/* * Copyright (C) 2019-2023 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "shared/source/device_binary_format/patchtokens_decoder.h" #include "shared/source/helpers/api_specific_config.h" #include "shared/source/helpers/compiler_product_helper.h" #include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/string.h" #include "shared/test/common/helpers/default_hw_info.h" #include "igfxfmid.h" #include #include extern GFXCORE_FAMILY renderCoreFamily; namespace PatchTokensTestData { template inline TokenT initToken(iOpenCL::PATCH_TOKEN tok) { TokenT ret = {}; ret.Size = sizeof(TokenT); ret.Token = tok; return ret; } inline iOpenCL::SPatchDataParameterBuffer initDataParameterBufferToken(iOpenCL::DATA_PARAMETER_TOKEN type, uint32_t sourceIndex = 0, uint32_t argNum = 0) { iOpenCL::SPatchDataParameterBuffer tok = {}; tok.Size = static_cast(sizeof(iOpenCL::SPatchDataParameterBuffer)); tok.Token = iOpenCL::PATCH_TOKEN_DATA_PARAMETER_BUFFER; tok.Type = type; tok.SourceOffset = sourceIndex * sizeof(uint32_t); tok.ArgumentNumber = argNum; return tok; } inline uint32_t pushBackString(const std::string &str, std::vector &storage) { auto offset = storage.size(); storage.insert(storage.end(), reinterpret_cast(str.c_str()), reinterpret_cast(str.c_str()) + str.size()); return static_cast(offset); } inline uint32_t pushBackStringToken(const std::string &str, uint32_t stringIndex, std::vector &outStream) { auto off = outStream.size(); outStream.reserve(outStream.size() + sizeof(iOpenCL::SPatchString) + str.length()); outStream.resize(outStream.size() + sizeof(iOpenCL::SPatchString)); iOpenCL::SPatchString *tok = reinterpret_cast(outStream.data() + off); *tok = initToken(iOpenCL::PATCH_TOKEN::PATCH_TOKEN_STRING); tok->StringSize = static_cast(str.length()); tok->Size += tok->StringSize; tok->Index = stringIndex; pushBackString(str, outStream); return static_cast(off); }; inline uint32_t pushBackArgInfoToken(std::vector &outStream, uint32_t argNum = 0, const std::string &addressQualifier = "__global", const std::string &accessQualifier = "read_write", const std::string &argName = "custom_arg", const std::string &typeName = "int*;", std::string typeQualifier = "const") { auto off = outStream.size(); iOpenCL::SPatchKernelArgumentInfo tok = {}; tok.Token = iOpenCL::PATCH_TOKEN_KERNEL_ARGUMENT_INFO; tok.AddressQualifierSize = static_cast(addressQualifier.size()); tok.AccessQualifierSize = static_cast(accessQualifier.size()); tok.ArgumentNameSize = static_cast(argName.size()); tok.TypeNameSize = static_cast(typeName.size()); tok.TypeQualifierSize = static_cast(typeQualifier.size()); tok.Size = sizeof(iOpenCL::SPatchKernelArgumentInfo) + tok.AddressQualifierSize + tok.AccessQualifierSize + tok.ArgumentNameSize + tok.TypeNameSize + tok.TypeQualifierSize; outStream.insert(outStream.end(), reinterpret_cast(&tok), reinterpret_cast(&tok) + sizeof(tok)); pushBackString(addressQualifier, outStream); pushBackString(accessQualifier, outStream); pushBackString(argName, outStream); pushBackString(typeName, outStream); pushBackString(typeQualifier, outStream); return static_cast(off); } struct ValidEmptyProgram : NEO::PatchTokenBinary::ProgramFromPatchtokens { ValidEmptyProgram() { auto hwInfo = *NEO::defaultHwInfo; auto compilerProductHelper = NEO::CompilerProductHelper::create(hwInfo.platform.eProductFamily); compilerProductHelper->adjustHwInfoForIgc(hwInfo); iOpenCL::SProgramBinaryHeader headerTok = {}; headerTok.Magic = iOpenCL::MAGIC_CL; headerTok.Version = iOpenCL::CURRENT_ICBE_VERSION; headerTok.Device = hwInfo.platform.eRenderCoreFamily; headerTok.GPUPointerSizeInBytes = sizeof(uintptr_t); this->decodeStatus = NEO::DecodeError::success; storage.insert(storage.end(), reinterpret_cast(&headerTok), reinterpret_cast((&headerTok) + 1)); recalcTokPtr(); } void recalcTokPtr() { this->blobs.programInfo = storage; this->headerMutable = reinterpret_cast(storage.data()); this->header = this->headerMutable; } std::vector storage; iOpenCL::SProgramBinaryHeader *headerMutable = nullptr; }; struct ValidProgramWithConstantSurface : ValidEmptyProgram { ValidProgramWithConstantSurface() { iOpenCL::SPatchAllocateConstantMemorySurfaceProgramBinaryInfo constSurfTok = {}; constSurfTok.Token = iOpenCL::PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO; constSurfTok.Size = sizeof(constSurfTok); constSurfTok.InlineDataSize = 128; this->programScopeTokens.allocateConstantMemorySurface.push_back(nullptr); storage.insert(storage.end(), reinterpret_cast(&constSurfTok), reinterpret_cast((&constSurfTok) + 1)); storage.resize(storage.size() + constSurfTok.InlineDataSize); recalcTokPtr(); } void recalcTokPtr() { ValidEmptyProgram::recalcTokPtr(); this->constSurfMutable = reinterpret_cast(storage.data() + sizeof(*this->headerMutable)); this->programScopeTokens.allocateConstantMemorySurface[0] = this->constSurfMutable; this->blobs.patchList = ArrayRef(storage.data() + sizeof(*this->headerMutable), storage.size() - sizeof(*this->headerMutable)); this->headerMutable->PatchListSize = static_cast(this->blobs.patchList.size()); } iOpenCL::SPatchAllocateConstantMemorySurfaceProgramBinaryInfo *constSurfMutable = nullptr; }; struct ValidProgramWithGlobalSurface : ValidEmptyProgram { ValidProgramWithGlobalSurface() { iOpenCL::SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo globalSurfTok = {}; globalSurfTok.Token = iOpenCL::PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_PROGRAM_BINARY_INFO; globalSurfTok.Size = sizeof(globalSurfTok); globalSurfTok.InlineDataSize = 256; this->programScopeTokens.allocateGlobalMemorySurface.push_back(nullptr); storage.insert(storage.end(), reinterpret_cast(&globalSurfTok), reinterpret_cast((&globalSurfTok) + 1)); storage.resize(storage.size() + globalSurfTok.InlineDataSize); recalcTokPtr(); } void recalcTokPtr() { ValidEmptyProgram::recalcTokPtr(); this->globalSurfMutable = reinterpret_cast(storage.data() + sizeof(*this->headerMutable)); this->programScopeTokens.allocateGlobalMemorySurface[0] = this->globalSurfMutable; this->blobs.patchList = ArrayRef(storage.data() + sizeof(*this->headerMutable), storage.size() - sizeof(*this->headerMutable)); this->headerMutable->PatchListSize = static_cast(this->blobs.patchList.size()); } iOpenCL::SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *globalSurfMutable = nullptr; }; struct ValidProgramWithConstantSurfaceAndPointer : ValidProgramWithConstantSurface { ValidProgramWithConstantSurfaceAndPointer() { iOpenCL::SPatchConstantPointerProgramBinaryInfo constantPointerTok = {}; constantPointerTok.Token = iOpenCL::PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO; constantPointerTok.Size = sizeof(constantPointerTok); constantPointerTok.ConstantBufferIndex = 0; constantPointerTok.BufferIndex = 0; constantPointerTok.BufferType = iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER; constantPointerTok.ConstantPointerOffset = 96; this->programScopeTokens.constantPointer.push_back(nullptr); storage.insert(storage.end(), reinterpret_cast(&constantPointerTok), reinterpret_cast((&constantPointerTok) + 1)); recalcTokPtr(); } void recalcTokPtr() { ValidProgramWithConstantSurface::recalcTokPtr(); this->constantPointerMutable = reinterpret_cast(storage.data() + sizeof(*this->headerMutable) + sizeof(*this->constSurfMutable) + this->constSurfMutable->InlineDataSize); this->programScopeTokens.constantPointer[0] = this->constantPointerMutable; } iOpenCL::SPatchConstantPointerProgramBinaryInfo *constantPointerMutable = nullptr; }; struct ValidProgramWithGlobalSurfaceAndPointer : ValidProgramWithGlobalSurface { ValidProgramWithGlobalSurfaceAndPointer() { iOpenCL::SPatchGlobalPointerProgramBinaryInfo globalPointerTok = {}; globalPointerTok.Token = iOpenCL::PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO; globalPointerTok.Size = sizeof(globalPointerTok); globalPointerTok.GlobalBufferIndex = 0; globalPointerTok.BufferIndex = 0; globalPointerTok.BufferType = iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER; globalPointerTok.GlobalPointerOffset = 48; this->programScopeTokens.globalPointer.push_back(nullptr); storage.insert(storage.end(), reinterpret_cast(&globalPointerTok), reinterpret_cast((&globalPointerTok) + 1)); recalcTokPtr(); } void recalcTokPtr() { ValidProgramWithGlobalSurface::recalcTokPtr(); this->globalPointerMutable = reinterpret_cast(storage.data() + sizeof(*this->headerMutable) + sizeof(*this->globalSurfMutable) + this->globalSurfMutable->InlineDataSize); this->programScopeTokens.globalPointer[0] = this->globalPointerMutable; } iOpenCL::SPatchGlobalPointerProgramBinaryInfo *globalPointerMutable = nullptr; }; struct ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers : ValidProgramWithConstantSurfaceAndPointer { ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers() { globalVariableTokensOffset = this->storage.size(); this->constantPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER; ValidProgramWithGlobalSurfaceAndPointer globalVarSurfProg; this->programScopeTokens.globalPointer.push_back(nullptr); this->programScopeTokens.allocateGlobalMemorySurface.push_back(nullptr); this->storage.insert(this->storage.end(), globalVarSurfProg.storage.data() + sizeof(*globalVarSurfProg.headerMutable), globalVarSurfProg.storage.data() + globalVarSurfProg.storage.size()); recalcTokPtr(); this->globalPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER; } void recalcTokPtr() { this->ValidProgramWithConstantSurfaceAndPointer::recalcTokPtr(); this->globalSurfMutable = reinterpret_cast(storage.data() + globalVariableTokensOffset); this->programScopeTokens.allocateGlobalMemorySurface[0] = this->globalSurfMutable; this->blobs.patchList = ArrayRef(storage.data() + sizeof(*this->headerMutable), storage.size() - sizeof(*this->headerMutable)); this->headerMutable->PatchListSize = static_cast(this->blobs.patchList.size()); this->globalPointerMutable = reinterpret_cast(storage.data() + globalVariableTokensOffset + sizeof(*this->globalSurfMutable) + this->globalSurfMutable->InlineDataSize); this->programScopeTokens.globalPointer[0] = this->globalPointerMutable; } size_t globalVariableTokensOffset = 0U; iOpenCL::SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *globalSurfMutable = nullptr; iOpenCL::SPatchGlobalPointerProgramBinaryInfo *globalPointerMutable = nullptr; }; struct ValidEmptyKernel { static NEO::PatchTokenBinary::KernelFromPatchtokens create(std::vector &storage) { NEO::PatchTokenBinary::KernelFromPatchtokens ret; iOpenCL::SKernelBinaryHeaderCommon headerTokInl = {}; auto execEnvTokInl = initToken(iOpenCL::PATCH_TOKEN_EXECUTION_ENVIRONMENT); execEnvTokInl.LargestCompiledSIMDSize = 32U; execEnvTokInl.CompiledSIMD32 = 1U; execEnvTokInl.UseBindlessMode = NEO::ApiSpecificConfig::getBindlessMode(nullptr); headerTokInl.PatchListSize = sizeof(execEnvTokInl); ret.decodeStatus = NEO::DecodeError::success; ret.name = "test_kernel"; headerTokInl.KernelNameSize = static_cast(ret.name.size()); auto kernOffset = storage.size(); storage.reserve(storage.size() + 512); storage.insert(storage.end(), reinterpret_cast(&headerTokInl), reinterpret_cast((&headerTokInl) + 1)); auto headerTok = reinterpret_cast(&*(storage.begin() + kernOffset)); ret.NEO::PatchTokenBinary::KernelFromPatchtokens::header = headerTok; storage.insert(storage.end(), reinterpret_cast(ret.name.begin()), reinterpret_cast(ret.name.end())); auto execEnvOffset = storage.size(); storage.insert(storage.end(), reinterpret_cast(&execEnvTokInl), reinterpret_cast((&execEnvTokInl) + 1)); ret.blobs.kernelInfo = ArrayRef(storage.data() + kernOffset, storage.data() + kernOffset + storage.size()); headerTok->CheckSum = NEO::PatchTokenBinary::calcKernelChecksum(ret.blobs.kernelInfo); ret.blobs.patchList = ArrayRef(storage.data() + execEnvOffset, storage.data() + storage.size()); ret.tokens.executionEnvironment = reinterpret_cast(storage.data() + execEnvOffset); return ret; } }; struct ValidProgramWithKernel : ValidEmptyProgram { ValidProgramWithKernel() { this->headerMutable->NumberOfKernels = 1; kernOffset = storage.size(); this->kernels.push_back(ValidEmptyKernel::create(storage)); this->kernels[0].decodeStatus = NEO::DecodeError::success; kernExecEnvOffset = ptrDiff(this->kernels[0].blobs.patchList.begin(), storage.data()); recalcTokPtr(); } void recalcTokPtr() { ValidEmptyProgram::recalcTokPtr(); this->kernels[0].blobs.kernelInfo = ArrayRef(storage.data() + kernOffset, storage.data() + storage.size()); kernelHeaderMutable = reinterpret_cast(&*(storage.begin() + kernOffset)); this->kernels[0].header = kernelHeaderMutable; char *name = reinterpret_cast(storage.data() + kernOffset + sizeof(iOpenCL::SKernelBinaryHeaderCommon)); this->kernels[0].name = ArrayRef(name, name + kernelHeaderMutable->KernelNameSize); kernelExecEnvMutable = reinterpret_cast(&*(storage.begin() + kernExecEnvOffset)); this->kernels[0].tokens.executionEnvironment = kernelExecEnvMutable; this->kernels[0].blobs.patchList = ArrayRef(storage.data() + kernExecEnvOffset, storage.data() + storage.size()); this->kernelHeaderMutable->PatchListSize = static_cast(this->kernels[0].blobs.patchList.size()); kernelHeaderMutable->CheckSum = NEO::PatchTokenBinary::calcKernelChecksum(this->kernels[0].blobs.kernelInfo); } size_t kernOffset = 0U; size_t kernExecEnvOffset = 0U; iOpenCL::SKernelBinaryHeaderCommon *kernelHeaderMutable = nullptr; iOpenCL::SPatchExecutionEnvironment *kernelExecEnvMutable = nullptr; }; struct ValidProgramWithKernelUsingSlm : ValidProgramWithKernel { ValidProgramWithKernelUsingSlm() { slmMutableOffset = storage.size(); iOpenCL::SPatchAllocateLocalSurface slmTok = {}; slmTok.Token = iOpenCL::PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE; slmTok.Size = sizeof(slmTok); slmTok.TotalInlineLocalMemorySize = 16; storage.insert(storage.end(), reinterpret_cast(&slmTok), reinterpret_cast((&slmTok) + 1)); recalcTokPtr(); } void recalcTokPtr() { ValidProgramWithKernel::recalcTokPtr(); slmMutable = reinterpret_cast(storage.data() + slmMutableOffset); this->kernels[0].tokens.allocateLocalSurface = slmMutable; } iOpenCL::SPatchAllocateLocalSurface *slmMutable = nullptr; size_t slmMutableOffset = 0U; }; struct ValidProgramWithKernelAndArg : ValidProgramWithKernel { ValidProgramWithKernelAndArg() { kernelArgOffset = storage.size(); pushBackArgInfoToken(storage); this->kernels[0].tokens.kernelArgs.resize(1); recalcTokPtr(); } void recalcTokPtr() { ValidProgramWithKernel::recalcTokPtr(); arg0InfoMutable = reinterpret_cast(storage.data() + kernelArgOffset); this->kernels[0].tokens.kernelArgs[0].argInfo = arg0InfoMutable; arg0InfoAddressQualifierMutable = reinterpret_cast(arg0InfoMutable + 1); arg0InfoAccessQualifierMutable = arg0InfoAddressQualifierMutable + arg0InfoMutable->AddressQualifierSize; arg0NameMutable = arg0InfoAccessQualifierMutable + arg0InfoMutable->AccessQualifierSize; arg0TypeMutable = arg0NameMutable + arg0InfoMutable->ArgumentNameSize; arg0TypeQualifierMutable = arg0TypeMutable + arg0InfoMutable->TypeNameSize; } iOpenCL::SPatchKernelArgumentInfo *arg0InfoMutable = nullptr; char *arg0InfoAddressQualifierMutable = nullptr; char *arg0InfoAccessQualifierMutable = nullptr; char *arg0NameMutable = nullptr; char *arg0TypeMutable = nullptr; char *arg0TypeQualifierMutable = nullptr; size_t kernelArgOffset = 0U; }; struct ValidProgramWithKernelUsingHostAccessTable : ValidProgramWithKernel { ValidProgramWithKernelUsingHostAccessTable() { hostAccessMutableOffset = storage.size(); iOpenCL::SPatchFunctionTableInfo hostAccessTok = {}; hostAccessTok.Token = iOpenCL::PATCH_TOKEN_GLOBAL_HOST_ACCESS_TABLE; hostAccessTok.NumEntries = 2; struct HostAccessTableEntry { char deviceName[vISA::MAX_SYMBOL_NAME_LENGTH]; char hostName[vISA::MAX_SYMBOL_NAME_LENGTH]; }; hostAccessTok.Size = sizeof(hostAccessTok) + 2 * sizeof(HostAccessTableEntry); const size_t hostAccessTokStorageSize = sizeof(hostAccessTok) + 2 * sizeof(HostAccessTableEntry); uint8_t hostAccessTokStorage[hostAccessTokStorageSize] = {}; uint8_t *storagePtr = hostAccessTokStorage; memcpy_s(storagePtr, hostAccessTokStorageSize, &hostAccessTok, sizeof(iOpenCL::SPatchFunctionTableInfo)); storagePtr = ptrOffset(storagePtr, sizeof(iOpenCL::SPatchFunctionTableInfo)); HostAccessTableEntry *entries = reinterpret_cast(storagePtr); strcpy_s(entries[0].deviceName, vISA::MAX_SYMBOL_NAME_LENGTH, "deviceNameOne"); strcpy_s(entries[0].hostName, vISA::MAX_SYMBOL_NAME_LENGTH, "hostNameOne"); strcpy_s(entries[1].deviceName, vISA::MAX_SYMBOL_NAME_LENGTH, "deviceNameTwo"); strcpy_s(entries[1].hostName, vISA::MAX_SYMBOL_NAME_LENGTH, "hostNameTwo"); storage.insert(storage.end(), hostAccessTokStorage, hostAccessTokStorage + hostAccessTokStorageSize); ValidProgramWithKernel::recalcTokPtr(); } void recalcTokPtr() { ValidProgramWithKernel::recalcTokPtr(); hostAccessMutable = reinterpret_cast(storage.data() + hostAccessMutableOffset); this->kernels[0].tokens.hostAccessTable = hostAccessMutable; } iOpenCL::SPatchFunctionTableInfo *hostAccessMutable = nullptr; size_t hostAccessMutableOffset = 0u; }; } // namespace PatchTokensTestData