Moving patchtokens decoder to core

Change-Id: I61d9f3ec7a1bca55df5b3b8c1884014acff1a4c0
This commit is contained in:
Jaroslaw Chodor
2020-01-25 13:11:54 +01:00
parent fc5b98970c
commit b74d502052
26 changed files with 70 additions and 45 deletions

View File

@@ -0,0 +1,16 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_DEVICE_BINARY_FORMAT
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_decoder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_decoder.h
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_dumper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_dumper.h
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_validator.inl
)
set_property(GLOBAL PROPERTY NEO_DEVICE_BINARY_FORMAT ${NEO_DEVICE_BINARY_FORMAT})

View File

@@ -0,0 +1,636 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "patchtokens_decoder.h"
#include "core/debug_settings/debug_settings_manager.h"
#include "core/helpers/debug_helpers.h"
#include "core/helpers/hash.h"
#include "core/helpers/ptr_math.h"
#include <algorithm>
namespace NEO {
namespace PatchTokenBinary {
struct PatchTokensStreamReader {
const ArrayRef<const uint8_t> data;
PatchTokensStreamReader(ArrayRef<const uint8_t> data) : data(data) {}
template <typename DecodePosT>
bool notEnoughDataLeft(DecodePosT *decodePos, size_t requestedSize) {
return getDataSizeLeft(decodePos) < requestedSize;
}
template <typename T, typename DecodePosT>
constexpr bool notEnoughDataLeft(DecodePosT *decodePos) {
return notEnoughDataLeft(decodePos, sizeof(T));
}
template <typename... ArgsT>
bool enoughDataLeft(ArgsT &&... args) {
return false == notEnoughDataLeft(std::forward<ArgsT>(args)...);
}
template <typename T, typename... ArgsT>
bool enoughDataLeft(ArgsT &&... args) {
return false == notEnoughDataLeft<T>(std::forward<ArgsT>(args)...);
}
template <typename DecodePosT>
size_t getDataSizeLeft(DecodePosT *decodePos) {
auto dataConsumed = ptrDiff(decodePos, data.begin());
UNRECOVERABLE_IF(dataConsumed > data.size());
return data.size() - dataConsumed;
}
};
template <typename T>
inline void assignToken(const T *&dst, const SPatchItemHeader *src) {
dst = reinterpret_cast<const T *>(src);
}
inline KernelArgFromPatchtokens &getKernelArg(KernelFromPatchtokens &kernel, size_t argNum, ArgObjectType type = ArgObjectType::None, ArgObjectTypeSpecialized typeSpecialized = ArgObjectTypeSpecialized::None) {
if (kernel.tokens.kernelArgs.size() < argNum + 1) {
kernel.tokens.kernelArgs.resize(argNum + 1);
}
auto &arg = kernel.tokens.kernelArgs[argNum];
if (arg.objectType == ArgObjectType::None) {
arg.objectType = type;
} else if ((arg.objectType != type) && (type != ArgObjectType::None)) {
kernel.decodeStatus = DecoderError::InvalidBinary;
DBG_LOG(LogPatchTokens, "\n Mismatched metadata for kernel arg :", argNum);
DEBUG_BREAK_IF(true);
}
if (arg.objectTypeSpecialized == ArgObjectTypeSpecialized::None) {
arg.objectTypeSpecialized = typeSpecialized;
} else if (typeSpecialized != ArgObjectTypeSpecialized::None) {
UNRECOVERABLE_IF(arg.objectTypeSpecialized != typeSpecialized);
}
return arg;
}
inline void assignArgInfo(KernelFromPatchtokens &kernel, const SPatchItemHeader *src) {
auto argInfoToken = reinterpret_cast<const SPatchKernelArgumentInfo *>(src);
getKernelArg(kernel, argInfoToken->ArgumentNumber, ArgObjectType::None).argInfo = argInfoToken;
}
template <typename T>
inline uint32_t getArgNum(const SPatchItemHeader *argToken) {
return reinterpret_cast<const T *>(argToken)->ArgumentNumber;
}
inline void assignArg(KernelFromPatchtokens &kernel, const SPatchItemHeader *src) {
uint32_t argNum = 0;
ArgObjectType type = ArgObjectType::Buffer;
switch (src->Token) {
default:
UNRECOVERABLE_IF(src->Token != PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT);
argNum = getArgNum<SPatchSamplerKernelArgument>(src);
type = ArgObjectType::Sampler;
break;
case PATCH_TOKEN_IMAGE_MEMORY_OBJECT_KERNEL_ARGUMENT:
argNum = getArgNum<SPatchImageMemoryObjectKernelArgument>(src);
type = ArgObjectType::Image;
break;
case PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT:
argNum = getArgNum<SPatchGlobalMemoryObjectKernelArgument>(src);
break;
case PATCH_TOKEN_STATELESS_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT:
argNum = getArgNum<SPatchStatelessGlobalMemoryObjectKernelArgument>(src);
break;
case PATCH_TOKEN_STATELESS_CONSTANT_MEMORY_OBJECT_KERNEL_ARGUMENT:
argNum = getArgNum<SPatchStatelessConstantMemoryObjectKernelArgument>(src);
break;
case PATCH_TOKEN_STATELESS_DEVICE_QUEUE_KERNEL_ARGUMENT:
argNum = getArgNum<SPatchStatelessDeviceQueueKernelArgument>(src);
break;
}
getKernelArg(kernel, argNum, type).objectArg = src;
}
inline void assignToken(StackVecStrings &stringVec, const SPatchItemHeader *src) {
auto stringToken = reinterpret_cast<const SPatchString *>(src);
if (stringVec.size() < stringToken->Index + 1) {
stringVec.resize(stringToken->Index + 1);
}
stringVec[stringToken->Index] = stringToken;
}
template <size_t S>
inline void assignTokenInArray(const SPatchDataParameterBuffer *(&tokensArray)[S], const SPatchDataParameterBuffer *src, StackVecUnhandledTokens &unhandledTokens) {
auto sourceIndex = src->SourceOffset >> 2;
if (sourceIndex >= S) {
DBG_LOG(LogPatchTokens, "\n .Type", "Unhandled sourceIndex ", sourceIndex);
DEBUG_BREAK_IF(true);
unhandledTokens.push_back(src);
return;
}
assignToken(tokensArray[sourceIndex], src);
}
template <typename PatchT, size_t NumInlineEl>
inline void addTok(StackVec<const PatchT *, NumInlineEl> &tokensVec, const SPatchItemHeader *src) {
tokensVec.push_back(reinterpret_cast<const PatchT *>(src));
}
inline void decodeKernelDataParameterToken(const SPatchDataParameterBuffer *token, KernelFromPatchtokens &out) {
auto &crossthread = out.tokens.crossThreadPayloadArgs;
auto sourceIndex = token->SourceOffset >> 2;
auto argNum = token->ArgumentNumber;
switch (token->Type) {
default:
DBG_LOG(LogPatchTokens, "\n .Type", "Unhandled SPatchDataParameterBuffer ", token->Type);
DEBUG_BREAK_IF(true);
out.unhandledTokens.push_back(token);
break;
case DATA_PARAMETER_KERNEL_ARGUMENT:
getKernelArg(out, argNum, ArgObjectType::None).byValMap.push_back(token);
break;
case DATA_PARAMETER_LOCAL_WORK_SIZE: {
if (sourceIndex >= 3) {
DBG_LOG(LogPatchTokens, "\n .Type", "Unhandled sourceIndex ", sourceIndex);
DEBUG_BREAK_IF(true);
out.unhandledTokens.push_back(token);
return;
}
auto localWorkSizeArray = (crossthread.localWorkSize[sourceIndex] == nullptr)
? crossthread.localWorkSize
: crossthread.localWorkSize2;
localWorkSizeArray[sourceIndex] = token;
break;
}
case DATA_PARAMETER_GLOBAL_WORK_OFFSET:
assignTokenInArray(crossthread.globalWorkOffset, token, out.unhandledTokens);
break;
case DATA_PARAMETER_ENQUEUED_LOCAL_WORK_SIZE:
assignTokenInArray(crossthread.enqueuedLocalWorkSize, token, out.unhandledTokens);
break;
case DATA_PARAMETER_GLOBAL_WORK_SIZE:
assignTokenInArray(crossthread.globalWorkSize, token, out.unhandledTokens);
break;
case DATA_PARAMETER_NUM_WORK_GROUPS:
assignTokenInArray(crossthread.numWorkGroups, token, out.unhandledTokens);
break;
case DATA_PARAMETER_MAX_WORKGROUP_SIZE:
crossthread.maxWorkGroupSize = token;
break;
case DATA_PARAMETER_WORK_DIMENSIONS:
crossthread.workDimensions = token;
break;
case DATA_PARAMETER_SIMD_SIZE:
crossthread.simdSize = token;
break;
case DATA_PARAMETER_PRIVATE_MEMORY_STATELESS_SIZE:
crossthread.privateMemoryStatelessSize = token;
break;
case DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_SIZE:
crossthread.localMemoryStatelessWindowSize = token;
break;
case DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_START_ADDRESS:
crossthread.localMemoryStatelessWindowStartAddress = token;
break;
case DATA_PARAMETER_OBJECT_ID:
getKernelArg(out, argNum, ArgObjectType::None).objectId = token;
break;
case DATA_PARAMETER_SUM_OF_LOCAL_MEMORY_OBJECT_ARGUMENT_SIZES: {
auto &kernelArg = getKernelArg(out, argNum, ArgObjectType::Slm);
kernelArg.byValMap.push_back(token);
kernelArg.metadata.slm.token = token;
} break;
case DATA_PARAMETER_BUFFER_OFFSET:
getKernelArg(out, argNum, ArgObjectType::Buffer).metadata.buffer.bufferOffset = token;
break;
case DATA_PARAMETER_BUFFER_STATEFUL:
getKernelArg(out, argNum, ArgObjectType::Buffer).metadata.buffer.pureStateful = token;
break;
case DATA_PARAMETER_IMAGE_WIDTH:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.width = token;
break;
case DATA_PARAMETER_IMAGE_HEIGHT:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.height = token;
break;
case DATA_PARAMETER_IMAGE_DEPTH:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.depth = token;
break;
case DATA_PARAMETER_IMAGE_CHANNEL_DATA_TYPE:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.channelDataType = token;
break;
case DATA_PARAMETER_IMAGE_CHANNEL_ORDER:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.channelOrder = token;
break;
case DATA_PARAMETER_IMAGE_ARRAY_SIZE:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.arraySize = token;
break;
case DATA_PARAMETER_IMAGE_NUM_SAMPLES:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.numSamples = token;
break;
case DATA_PARAMETER_IMAGE_NUM_MIP_LEVELS:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.numMipLevels = token;
break;
case DATA_PARAMETER_FLAT_IMAGE_BASEOFFSET:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.flatBaseOffset = token;
break;
case DATA_PARAMETER_FLAT_IMAGE_WIDTH:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.flatWidth = token;
break;
case DATA_PARAMETER_FLAT_IMAGE_HEIGHT:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.flatHeight = token;
break;
case DATA_PARAMETER_FLAT_IMAGE_PITCH:
getKernelArg(out, argNum, ArgObjectType::Image).metadata.image.flatPitch = token;
break;
case DATA_PARAMETER_SAMPLER_COORDINATE_SNAP_WA_REQUIRED:
getKernelArg(out, argNum, ArgObjectType::Sampler).metadata.sampler.coordinateSnapWaRequired = token;
break;
case DATA_PARAMETER_SAMPLER_ADDRESS_MODE:
getKernelArg(out, argNum, ArgObjectType::Sampler).metadata.sampler.addressMode = token;
break;
case DATA_PARAMETER_SAMPLER_NORMALIZED_COORDS:
getKernelArg(out, argNum, ArgObjectType::Sampler).metadata.sampler.normalizedCoords = token;
break;
case DATA_PARAMETER_VME_MB_BLOCK_TYPE:
getKernelArg(out, argNum, ArgObjectType::None, ArgObjectTypeSpecialized::Vme).metadataSpecialized.vme.mbBlockType = token;
break;
case DATA_PARAMETER_VME_SUBPIXEL_MODE:
getKernelArg(out, argNum, ArgObjectType::None, ArgObjectTypeSpecialized::Vme).metadataSpecialized.vme.subpixelMode = token;
break;
case DATA_PARAMETER_VME_SAD_ADJUST_MODE:
getKernelArg(out, argNum, ArgObjectType::None, ArgObjectTypeSpecialized::Vme).metadataSpecialized.vme.sadAdjustMode = token;
break;
case DATA_PARAMETER_VME_SEARCH_PATH_TYPE:
getKernelArg(out, argNum, ArgObjectType::None, ArgObjectTypeSpecialized::Vme).metadataSpecialized.vme.searchPathType = token;
break;
case DATA_PARAMETER_PARENT_EVENT:
crossthread.parentEvent = token;
break;
case DATA_PARAMETER_CHILD_BLOCK_SIMD_SIZE:
crossthread.childBlockSimdSize.push_back(token);
break;
case DATA_PARAMETER_PREFERRED_WORKGROUP_MULTIPLE:
crossthread.preferredWorkgroupMultiple = token;
break;
case DATA_PARAMETER_NUM_HARDWARE_THREADS:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_PRINTF_SURFACE_SIZE:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_IMAGE_SRGB_CHANNEL_ORDER:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_STAGE_IN_GRID_ORIGIN:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_STAGE_IN_GRID_SIZE:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_LOCAL_ID:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_EXECUTION_MASK:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_VME_IMAGE_TYPE:
CPP_ATTRIBUTE_FALLTHROUGH;
case DATA_PARAMETER_VME_MB_SKIP_BLOCK_TYPE:
// ignored intentionally
break;
}
}
inline bool decodeToken(const SPatchItemHeader *token, KernelFromPatchtokens &out) {
switch (token->Token) {
default: {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "Unknown kernel-scope Patch Token: %d\n", token->Token);
DEBUG_BREAK_IF(true);
out.unhandledTokens.push_back(token);
break;
}
case PATCH_TOKEN_SAMPLER_STATE_ARRAY:
assignToken(out.tokens.samplerStateArray, token);
break;
case PATCH_TOKEN_BINDING_TABLE_STATE:
assignToken(out.tokens.bindingTableState, token);
break;
case PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE:
assignToken(out.tokens.allocateLocalSurface, token);
break;
case PATCH_TOKEN_MEDIA_VFE_STATE:
assignToken(out.tokens.mediaVfeState[0], token);
break;
case PATCH_TOKEN_MEDIA_VFE_STATE_SLOT1:
assignToken(out.tokens.mediaVfeState[1], token);
break;
case PATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD:
assignToken(out.tokens.mediaInterfaceDescriptorLoad, token);
break;
case PATCH_TOKEN_INTERFACE_DESCRIPTOR_DATA:
assignToken(out.tokens.interfaceDescriptorData, token);
break;
case PATCH_TOKEN_THREAD_PAYLOAD:
assignToken(out.tokens.threadPayload, token);
break;
case PATCH_TOKEN_EXECUTION_ENVIRONMENT:
assignToken(out.tokens.executionEnvironment, token);
break;
case PATCH_TOKEN_KERNEL_ATTRIBUTES_INFO:
assignToken(out.tokens.kernelAttributesInfo, token);
break;
case PATCH_TOKEN_ALLOCATE_STATELESS_PRIVATE_MEMORY:
assignToken(out.tokens.allocateStatelessPrivateSurface, token);
break;
case PATCH_TOKEN_ALLOCATE_STATELESS_CONSTANT_MEMORY_SURFACE_WITH_INITIALIZATION:
assignToken(out.tokens.allocateStatelessConstantMemorySurfaceWithInitialization, token);
break;
case PATCH_TOKEN_ALLOCATE_STATELESS_GLOBAL_MEMORY_SURFACE_WITH_INITIALIZATION:
assignToken(out.tokens.allocateStatelessGlobalMemorySurfaceWithInitialization, token);
break;
case PATCH_TOKEN_ALLOCATE_STATELESS_PRINTF_SURFACE:
assignToken(out.tokens.allocateStatelessPrintfSurface, token);
break;
case PATCH_TOKEN_ALLOCATE_STATELESS_EVENT_POOL_SURFACE:
assignToken(out.tokens.allocateStatelessEventPoolSurface, token);
break;
case PATCH_TOKEN_ALLOCATE_STATELESS_DEFAULT_DEVICE_QUEUE_SURFACE:
assignToken(out.tokens.allocateStatelessDefaultDeviceQueueSurface, token);
break;
case PATCH_TOKEN_STRING:
assignToken(out.tokens.strings, token);
break;
case PATCH_TOKEN_INLINE_VME_SAMPLER_INFO:
assignToken(out.tokens.inlineVmeSamplerInfo, token);
break;
case PATCH_TOKEN_GTPIN_FREE_GRF_INFO:
assignToken(out.tokens.gtpinFreeGrfInfo, token);
break;
case PATCH_TOKEN_GTPIN_INFO:
assignToken(out.tokens.gtpinInfo, token);
break;
case PATCH_TOKEN_STATE_SIP:
assignToken(out.tokens.stateSip, token);
break;
case PATCH_TOKEN_ALLOCATE_SIP_SURFACE:
assignToken(out.tokens.allocateSystemThreadSurface, token);
break;
case PATCH_TOKEN_PROGRAM_SYMBOL_TABLE:
assignToken(out.tokens.programSymbolTable, token);
break;
case PATCH_TOKEN_PROGRAM_RELOCATION_TABLE:
assignToken(out.tokens.programRelocationTable, token);
break;
case PATCH_TOKEN_KERNEL_ARGUMENT_INFO:
assignArgInfo(out, token);
break;
case PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT:
CPP_ATTRIBUTE_FALLTHROUGH;
case PATCH_TOKEN_IMAGE_MEMORY_OBJECT_KERNEL_ARGUMENT:
CPP_ATTRIBUTE_FALLTHROUGH;
case PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT:
CPP_ATTRIBUTE_FALLTHROUGH;
case PATCH_TOKEN_STATELESS_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT:
CPP_ATTRIBUTE_FALLTHROUGH;
case PATCH_TOKEN_STATELESS_CONSTANT_MEMORY_OBJECT_KERNEL_ARGUMENT:
CPP_ATTRIBUTE_FALLTHROUGH;
case PATCH_TOKEN_STATELESS_DEVICE_QUEUE_KERNEL_ARGUMENT:
assignArg(out, token);
break;
case PATCH_TOKEN_DATA_PARAMETER_STREAM:
assignToken(out.tokens.dataParameterStream, token);
break;
case PATCH_TOKEN_DATA_PARAMETER_BUFFER: {
auto tokDataP = reinterpret_cast<const SPatchDataParameterBuffer *>(token);
decodeKernelDataParameterToken(tokDataP, out);
} break;
case PATCH_TOKEN_ALLOCATE_SYNC_BUFFER: {
assignToken(out.tokens.allocateSyncBuffer, token);
} break;
}
return out.decodeStatus != DecoderError::InvalidBinary;
}
inline bool decodeToken(const SPatchItemHeader *token, ProgramFromPatchtokens &out) {
auto &progTok = out.programScopeTokens;
switch (token->Token) {
default: {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "Unknown program-scope Patch Token: %d\n", token->Token);
DEBUG_BREAK_IF(true);
out.unhandledTokens.push_back(token);
break;
}
case PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO:
addTok(progTok.allocateConstantMemorySurface, token);
break;
case PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_PROGRAM_BINARY_INFO:
addTok(progTok.allocateGlobalMemorySurface, token);
break;
case PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO:
addTok(progTok.globalPointer, token);
break;
case PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO:
addTok(progTok.constantPointer, token);
break;
case PATCH_TOKEN_PROGRAM_SYMBOL_TABLE:
assignToken(progTok.symbolTable, token);
break;
}
return true;
}
template <typename DecodeContext>
inline size_t getPatchTokenTotalSize(PatchTokensStreamReader stream, const SPatchItemHeader *token);
template <>
inline size_t getPatchTokenTotalSize<KernelFromPatchtokens>(PatchTokensStreamReader stream, const SPatchItemHeader *token) {
return token->Size;
}
template <>
inline size_t getPatchTokenTotalSize<ProgramFromPatchtokens>(PatchTokensStreamReader stream, const SPatchItemHeader *token) {
size_t tokSize = token->Size;
switch (token->Token) {
default:
return tokSize;
case PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO:
return stream.enoughDataLeft<SPatchAllocateConstantMemorySurfaceProgramBinaryInfo>(token)
? tokSize + reinterpret_cast<const SPatchAllocateConstantMemorySurfaceProgramBinaryInfo *>(token)->InlineDataSize
: std::numeric_limits<size_t>::max();
case PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_PROGRAM_BINARY_INFO:
return stream.enoughDataLeft<SPatchAllocateConstantMemorySurfaceProgramBinaryInfo>(token)
? tokSize + reinterpret_cast<const SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *>(token)->InlineDataSize
: std::numeric_limits<size_t>::max();
}
}
template <typename OutT>
inline bool decodePatchList(PatchTokensStreamReader patchListStream, OutT &out) {
auto decodePos = patchListStream.data.begin();
auto decodeEnd = patchListStream.data.end();
bool decodeSuccess = true;
while ((decodePos + sizeof(SPatchItemHeader) <= decodeEnd) && decodeSuccess) {
auto token = reinterpret_cast<const SPatchItemHeader *>(decodePos);
size_t tokenTotalSize = getPatchTokenTotalSize<OutT>(patchListStream, token);
decodeSuccess = patchListStream.enoughDataLeft(decodePos, tokenTotalSize);
decodeSuccess = decodeSuccess && (tokenTotalSize > 0U);
decodeSuccess = decodeSuccess && decodeToken(token, out);
decodePos = ptrOffset(decodePos, tokenTotalSize);
}
return decodeSuccess;
}
bool decodeKernelFromPatchtokensBlob(ArrayRef<const uint8_t> data, KernelFromPatchtokens &out) {
PatchTokensStreamReader stream{data};
auto decodePos = stream.data.begin();
out.decodeStatus = DecoderError::Undefined;
if (stream.notEnoughDataLeft<SKernelBinaryHeaderCommon>(decodePos)) {
out.decodeStatus = DecoderError::InvalidBinary;
return false;
}
out.header = reinterpret_cast<const SKernelBinaryHeaderCommon *>(decodePos);
auto kernelInfoBlobSize = sizeof(SKernelBinaryHeaderCommon) + out.header->KernelNameSize + out.header->KernelHeapSize + out.header->GeneralStateHeapSize + out.header->DynamicStateHeapSize + out.header->SurfaceStateHeapSize + out.header->PatchListSize;
if (stream.notEnoughDataLeft(decodePos, kernelInfoBlobSize)) {
out.decodeStatus = DecoderError::InvalidBinary;
return false;
}
out.blobs.kernelInfo = ArrayRef<const uint8_t>(stream.data.begin(), kernelInfoBlobSize);
decodePos = ptrOffset(decodePos, sizeof(SKernelBinaryHeaderCommon));
auto kernelName = reinterpret_cast<const char *>(decodePos);
out.name = ArrayRef<const char>(kernelName, out.header->KernelNameSize);
decodePos = ptrOffset(decodePos, out.name.size());
out.isa = ArrayRef<const uint8_t>(decodePos, out.header->KernelHeapSize);
decodePos = ptrOffset(decodePos, out.isa.size());
out.heaps.generalState = ArrayRef<const uint8_t>(decodePos, out.header->GeneralStateHeapSize);
decodePos = ptrOffset(decodePos, out.heaps.generalState.size());
out.heaps.dynamicState = ArrayRef<const uint8_t>(decodePos, out.header->DynamicStateHeapSize);
decodePos = ptrOffset(decodePos, out.heaps.dynamicState.size());
out.heaps.surfaceState = ArrayRef<const uint8_t>(decodePos, out.header->SurfaceStateHeapSize);
decodePos = ptrOffset(decodePos, out.heaps.surfaceState.size());
out.blobs.patchList = ArrayRef<const uint8_t>(decodePos, out.header->PatchListSize);
if (false == decodePatchList(out.blobs.patchList, out)) {
out.decodeStatus = DecoderError::InvalidBinary;
return false;
}
out.decodeStatus = DecoderError::Success;
return true;
}
inline bool decodeProgramHeader(ProgramFromPatchtokens &decodedProgram) {
auto decodePos = decodedProgram.blobs.programInfo.begin();
PatchTokensStreamReader stream{decodedProgram.blobs.programInfo};
if (stream.notEnoughDataLeft<SProgramBinaryHeader>(decodePos)) {
return false;
}
decodedProgram.header = reinterpret_cast<const SProgramBinaryHeader *>(decodePos);
if (decodedProgram.header->Magic != MAGIC_CL) {
return false;
}
decodePos = ptrOffset(decodePos, sizeof(SProgramBinaryHeader));
if (stream.notEnoughDataLeft(decodePos, decodedProgram.header->PatchListSize)) {
return false;
}
decodedProgram.blobs.patchList = ArrayRef<const uint8_t>(decodePos, decodedProgram.header->PatchListSize);
decodePos = ptrOffset(decodePos, decodedProgram.blobs.patchList.size());
decodedProgram.blobs.kernelsInfo = ArrayRef<const uint8_t>(decodePos, stream.getDataSizeLeft(decodePos));
return true;
}
inline bool decodeKernels(ProgramFromPatchtokens &decodedProgram) {
auto numKernels = decodedProgram.header->NumberOfKernels;
decodedProgram.kernels.reserve(decodedProgram.header->NumberOfKernels);
const uint8_t *decodePos = decodedProgram.blobs.kernelsInfo.begin();
bool decodeSuccess = true;
PatchTokensStreamReader stream{decodedProgram.blobs.kernelsInfo};
for (uint32_t i = 0; (i < numKernels) && decodeSuccess; i++) {
decodedProgram.kernels.resize(decodedProgram.kernels.size() + 1);
auto &currKernelInfo = *decodedProgram.kernels.rbegin();
auto kernelDataLeft = ArrayRef<const uint8_t>(decodePos, stream.getDataSizeLeft(decodePos));
decodeSuccess = decodeKernelFromPatchtokensBlob(kernelDataLeft, currKernelInfo);
decodePos = ptrOffset(decodePos, currKernelInfo.blobs.kernelInfo.size());
}
return decodeSuccess;
}
bool decodeProgramFromPatchtokensBlob(ArrayRef<const uint8_t> blob, ProgramFromPatchtokens &out) {
out.blobs.programInfo = blob;
bool decodeSuccess = decodeProgramHeader(out);
decodeSuccess = decodeSuccess && decodeKernels(out);
decodeSuccess = decodeSuccess && decodePatchList(out.blobs.patchList, out);
out.decodeStatus = decodeSuccess ? DecoderError::Success : DecoderError::InvalidBinary;
return decodeSuccess;
}
uint32_t calcKernelChecksum(const ArrayRef<const uint8_t> kernelBlob) {
UNRECOVERABLE_IF(kernelBlob.size() <= sizeof(SKernelBinaryHeaderCommon));
auto dataToHash = ArrayRef<const uint8_t>(ptrOffset(kernelBlob.begin(), sizeof(SKernelBinaryHeaderCommon)), kernelBlob.end());
uint64_t hashValue = Hash::hash(reinterpret_cast<const char *>(dataToHash.begin()), dataToHash.size());
uint32_t checksum = hashValue & 0xFFFFFFFF;
return checksum;
}
bool hasInvalidChecksum(const KernelFromPatchtokens &decodedKernel) {
uint32_t decodedChecksum = decodedKernel.header->CheckSum;
uint32_t calculatedChecksum = NEO::PatchTokenBinary::calcKernelChecksum(decodedKernel.blobs.kernelInfo);
return decodedChecksum != calculatedChecksum;
}
const KernelArgAttributesFromPatchtokens getInlineData(const SPatchKernelArgumentInfo *ptr) {
KernelArgAttributesFromPatchtokens ret = {};
UNRECOVERABLE_IF(ptr == nullptr);
auto decodePos = reinterpret_cast<const char *>(ptr + 1);
auto bounds = reinterpret_cast<const char *>(ptr) + ptr->Size;
ret.addressQualifier = ArrayRef<const char>(decodePos, std::min(decodePos + ptr->AddressQualifierSize, bounds));
decodePos += ret.addressQualifier.size();
ret.accessQualifier = ArrayRef<const char>(decodePos, std::min(decodePos + ptr->AccessQualifierSize, bounds));
decodePos += ret.accessQualifier.size();
ret.argName = ArrayRef<const char>(decodePos, std::min(decodePos + ptr->ArgumentNameSize, bounds));
decodePos += ret.argName.size();
ret.typeName = ArrayRef<const char>(decodePos, std::min(decodePos + ptr->TypeNameSize, bounds));
decodePos += ret.typeName.size();
ret.typeQualifiers = ArrayRef<const char>(decodePos, std::min(decodePos + ptr->TypeQualifierSize, bounds));
return ret;
}
} // namespace PatchTokenBinary
} // namespace NEO

View File

@@ -0,0 +1,219 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "core/helpers/ptr_math.h"
#include "core/utilities/arrayref.h"
#include "core/utilities/stackvec.h"
#include "patch_g7.h"
#include "patch_list.h"
#include "patch_shared.h"
#include "program_debug_data.h"
#include <cstdint>
#include <limits>
#include <memory>
namespace NEO {
namespace PatchTokenBinary {
using namespace iOpenCL;
enum class DecoderError {
Success = 0,
Undefined = 1,
InvalidBinary = 2,
};
enum class ArgObjectType : uint32_t {
None = 0,
Buffer,
Image,
Sampler,
Slm
};
enum class ArgObjectTypeSpecialized : uint32_t {
None = 0,
Vme
};
using StackVecUnhandledTokens = StackVec<const SPatchItemHeader *, 4>;
using StackVecByValMap = StackVec<const SPatchDataParameterBuffer *, 8>;
using StackVecStrings = StackVec<const SPatchString *, 4>;
struct KernelArgFromPatchtokens {
const SPatchKernelArgumentInfo *argInfo = nullptr;
const SPatchItemHeader *objectArg = nullptr;
const SPatchDataParameterBuffer *objectId = nullptr;
ArgObjectType objectType = ArgObjectType::None;
ArgObjectTypeSpecialized objectTypeSpecialized = ArgObjectTypeSpecialized::None;
StackVecByValMap byValMap;
union {
struct {
const SPatchDataParameterBuffer *width;
const SPatchDataParameterBuffer *height;
const SPatchDataParameterBuffer *depth;
const SPatchDataParameterBuffer *channelDataType;
const SPatchDataParameterBuffer *channelOrder;
const SPatchDataParameterBuffer *arraySize;
const SPatchDataParameterBuffer *numSamples;
const SPatchDataParameterBuffer *numMipLevels;
const SPatchDataParameterBuffer *flatBaseOffset;
const SPatchDataParameterBuffer *flatWidth;
const SPatchDataParameterBuffer *flatHeight;
const SPatchDataParameterBuffer *flatPitch;
} image;
struct {
const SPatchDataParameterBuffer *bufferOffset;
const SPatchDataParameterBuffer *pureStateful;
} buffer;
struct {
const SPatchDataParameterBuffer *coordinateSnapWaRequired;
const SPatchDataParameterBuffer *addressMode;
const SPatchDataParameterBuffer *normalizedCoords;
} sampler;
struct {
const SPatchDataParameterBuffer *token;
} slm;
static_assert((sizeof(image) > sizeof(buffer)) && (sizeof(image) > sizeof(sampler)) && (sizeof(image) > sizeof(slm)),
"Union initialization based on image wont' initialize whole struct");
} metadata = {};
union {
struct {
const SPatchDataParameterBuffer *mbBlockType;
const SPatchDataParameterBuffer *subpixelMode;
const SPatchDataParameterBuffer *sadAdjustMode;
const SPatchDataParameterBuffer *searchPathType;
} vme;
} metadataSpecialized = {};
};
using StackVecKernelArgs = StackVec<KernelArgFromPatchtokens, 12>;
struct KernelFromPatchtokens {
DecoderError decodeStatus = DecoderError::Undefined;
const SKernelBinaryHeaderCommon *header = nullptr;
ArrayRef<const char> name;
ArrayRef<const uint8_t> isa;
struct {
ArrayRef<const uint8_t> generalState;
ArrayRef<const uint8_t> dynamicState;
ArrayRef<const uint8_t> surfaceState;
} heaps;
struct {
ArrayRef<const uint8_t> kernelInfo;
ArrayRef<const uint8_t> patchList;
} blobs;
struct {
const SPatchSamplerStateArray *samplerStateArray = nullptr;
const SPatchBindingTableState *bindingTableState = nullptr;
const SPatchAllocateLocalSurface *allocateLocalSurface = nullptr;
const SPatchMediaVFEState *mediaVfeState[2] = {nullptr, nullptr};
const SPatchMediaInterfaceDescriptorLoad *mediaInterfaceDescriptorLoad = nullptr;
const SPatchInterfaceDescriptorData *interfaceDescriptorData = nullptr;
const SPatchThreadPayload *threadPayload = nullptr;
const SPatchExecutionEnvironment *executionEnvironment = nullptr;
const SPatchDataParameterStream *dataParameterStream = nullptr;
const SPatchKernelAttributesInfo *kernelAttributesInfo = nullptr;
const SPatchAllocateStatelessPrivateSurface *allocateStatelessPrivateSurface = nullptr;
const SPatchAllocateStatelessConstantMemorySurfaceWithInitialization *allocateStatelessConstantMemorySurfaceWithInitialization = nullptr;
const SPatchAllocateStatelessGlobalMemorySurfaceWithInitialization *allocateStatelessGlobalMemorySurfaceWithInitialization = nullptr;
const SPatchAllocateStatelessPrintfSurface *allocateStatelessPrintfSurface = nullptr;
const SPatchAllocateStatelessEventPoolSurface *allocateStatelessEventPoolSurface = nullptr;
const SPatchAllocateStatelessDefaultDeviceQueueSurface *allocateStatelessDefaultDeviceQueueSurface = nullptr;
const SPatchAllocateSyncBuffer *allocateSyncBuffer = nullptr;
const SPatchItemHeader *inlineVmeSamplerInfo = nullptr;
const SPatchGtpinFreeGRFInfo *gtpinFreeGrfInfo = nullptr;
const SPatchStateSIP *stateSip = nullptr;
const SPatchAllocateSystemThreadSurface *allocateSystemThreadSurface = nullptr;
const SPatchItemHeader *gtpinInfo = nullptr;
const SPatchFunctionTableInfo *programSymbolTable = nullptr;
const SPatchFunctionTableInfo *programRelocationTable = nullptr;
StackVecKernelArgs kernelArgs;
StackVecStrings strings;
struct {
const SPatchDataParameterBuffer *localWorkSize[3] = {};
const SPatchDataParameterBuffer *localWorkSize2[3] = {};
const SPatchDataParameterBuffer *enqueuedLocalWorkSize[3] = {};
const SPatchDataParameterBuffer *numWorkGroups[3] = {};
const SPatchDataParameterBuffer *globalWorkOffset[3] = {};
const SPatchDataParameterBuffer *globalWorkSize[3] = {};
const SPatchDataParameterBuffer *maxWorkGroupSize = nullptr;
const SPatchDataParameterBuffer *workDimensions = nullptr;
const SPatchDataParameterBuffer *simdSize = nullptr;
const SPatchDataParameterBuffer *parentEvent = nullptr;
const SPatchDataParameterBuffer *privateMemoryStatelessSize = nullptr;
const SPatchDataParameterBuffer *localMemoryStatelessWindowSize = nullptr;
const SPatchDataParameterBuffer *localMemoryStatelessWindowStartAddress = nullptr;
const SPatchDataParameterBuffer *preferredWorkgroupMultiple = nullptr;
StackVec<const SPatchDataParameterBuffer *, 4> childBlockSimdSize;
} crossThreadPayloadArgs;
} tokens;
StackVecUnhandledTokens unhandledTokens;
};
struct ProgramFromPatchtokens {
DecoderError decodeStatus = DecoderError::Undefined;
const SProgramBinaryHeader *header = nullptr;
struct {
ArrayRef<const uint8_t> programInfo;
ArrayRef<const uint8_t> patchList;
ArrayRef<const uint8_t> kernelsInfo;
} blobs;
struct {
StackVec<const SPatchAllocateConstantMemorySurfaceProgramBinaryInfo *, 2> allocateConstantMemorySurface;
StackVec<const SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *, 2> allocateGlobalMemorySurface;
StackVec<const SPatchConstantPointerProgramBinaryInfo *, 4> constantPointer;
StackVec<const SPatchGlobalPointerProgramBinaryInfo *, 4> globalPointer;
const SPatchFunctionTableInfo *symbolTable = nullptr;
} programScopeTokens;
StackVec<KernelFromPatchtokens, 2> kernels;
StackVec<const SPatchItemHeader *, 4> unhandledTokens;
};
struct KernelArgAttributesFromPatchtokens {
ArrayRef<const char> addressQualifier;
ArrayRef<const char> accessQualifier;
ArrayRef<const char> argName;
ArrayRef<const char> typeName;
ArrayRef<const char> typeQualifiers;
};
bool decodeKernelFromPatchtokensBlob(ArrayRef<const uint8_t> blob, KernelFromPatchtokens &out);
bool decodeProgramFromPatchtokensBlob(ArrayRef<const uint8_t> blob, ProgramFromPatchtokens &out);
uint32_t calcKernelChecksum(const ArrayRef<const uint8_t> kernelBlob);
bool hasInvalidChecksum(const KernelFromPatchtokens &decodedKernel);
inline const uint8_t *getInlineData(const SPatchAllocateConstantMemorySurfaceProgramBinaryInfo *ptr) {
return ptrOffset(reinterpret_cast<const uint8_t *>(ptr), sizeof(SPatchAllocateConstantMemorySurfaceProgramBinaryInfo));
}
inline const uint8_t *getInlineData(const SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *ptr) {
return ptrOffset(reinterpret_cast<const uint8_t *>(ptr), sizeof(SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo));
}
inline const uint8_t *getInlineData(const SPatchString *ptr) {
return ptrOffset(reinterpret_cast<const uint8_t *>(ptr), sizeof(SPatchString));
}
const KernelArgAttributesFromPatchtokens getInlineData(const SPatchKernelArgumentInfo *ptr);
} // namespace PatchTokenBinary
} // namespace NEO

View File

@@ -0,0 +1,897 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "patchtokens_dumper.h"
#include "patchtokens_decoder.h"
#include <sstream>
namespace NEO {
namespace PatchTokenBinary {
#define CASE_TOK_STR(TOK) \
case TOK: \
return std::to_string(TOK) + "(" + #TOK + ")"; \
break;
std::string asString(PATCH_TOKEN token) {
switch (token) {
default:
return std::to_string(token);
CASE_TOK_STR(PATCH_TOKEN_UNKNOWN);
CASE_TOK_STR(PATCH_TOKEN_MEDIA_STATE_POINTERS);
CASE_TOK_STR(PATCH_TOKEN_STATE_SIP);
CASE_TOK_STR(PATCH_TOKEN_CS_URB_STATE);
CASE_TOK_STR(PATCH_TOKEN_CONSTANT_BUFFER);
CASE_TOK_STR(PATCH_TOKEN_SAMPLER_STATE_ARRAY);
CASE_TOK_STR(PATCH_TOKEN_INTERFACE_DESCRIPTOR);
CASE_TOK_STR(PATCH_TOKEN_VFE_STATE);
CASE_TOK_STR(PATCH_TOKEN_BINDING_TABLE_STATE);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_SCRATCH_SURFACE);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_SIP_SURFACE);
CASE_TOK_STR(PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT);
CASE_TOK_STR(PATCH_TOKEN_IMAGE_MEMORY_OBJECT_KERNEL_ARGUMENT);
CASE_TOK_STR(PATCH_TOKEN_CONSTANT_MEMORY_OBJECT_KERNEL_ARGUMENT);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_SURFACE_WITH_INITIALIZATION);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE);
CASE_TOK_STR(PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT);
CASE_TOK_STR(PATCH_TOKEN_DATA_PARAMETER_BUFFER);
CASE_TOK_STR(PATCH_TOKEN_MEDIA_VFE_STATE);
CASE_TOK_STR(PATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD);
CASE_TOK_STR(PATCH_TOKEN_MEDIA_CURBE_LOAD);
CASE_TOK_STR(PATCH_TOKEN_INTERFACE_DESCRIPTOR_DATA);
CASE_TOK_STR(PATCH_TOKEN_THREAD_PAYLOAD);
CASE_TOK_STR(PATCH_TOKEN_EXECUTION_ENVIRONMENT);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_PRIVATE_MEMORY);
CASE_TOK_STR(PATCH_TOKEN_DATA_PARAMETER_STREAM);
CASE_TOK_STR(PATCH_TOKEN_KERNEL_ARGUMENT_INFO);
CASE_TOK_STR(PATCH_TOKEN_KERNEL_ATTRIBUTES_INFO);
CASE_TOK_STR(PATCH_TOKEN_STRING);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_PRINTF_SURFACE);
CASE_TOK_STR(PATCH_TOKEN_STATELESS_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT);
CASE_TOK_STR(PATCH_TOKEN_STATELESS_CONSTANT_MEMORY_OBJECT_KERNEL_ARGUMENT);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_STATELESS_SURFACE_WITH_INITIALIZATION);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_STATELESS_PRINTF_SURFACE);
CASE_TOK_STR(PATCH_TOKEN_CB_MAPPING);
CASE_TOK_STR(PATCH_TOKEN_CB2CR_GATHER_TABLE);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_STATELESS_EVENT_POOL_SURFACE);
CASE_TOK_STR(PATCH_TOKEN_NULL_SURFACE_LOCATION);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_STATELESS_PRIVATE_MEMORY);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_WITH_INITIALIZATION);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_WITH_INITIALIZATION);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_GLOBAL_MEMORY_SURFACE_PROGRAM_BINARY_INFO);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_STATELESS_GLOBAL_MEMORY_SURFACE_WITH_INITIALIZATION);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_STATELESS_CONSTANT_MEMORY_SURFACE_WITH_INITIALIZATION);
CASE_TOK_STR(PATCH_TOKEN_ALLOCATE_STATELESS_DEFAULT_DEVICE_QUEUE_SURFACE);
CASE_TOK_STR(PATCH_TOKEN_STATELESS_DEVICE_QUEUE_KERNEL_ARGUMENT);
CASE_TOK_STR(PATCH_TOKEN_GLOBAL_POINTER_PROGRAM_BINARY_INFO);
CASE_TOK_STR(PATCH_TOKEN_CONSTANT_POINTER_PROGRAM_BINARY_INFO);
CASE_TOK_STR(PATCH_TOKEN_CONSTRUCTOR_DESTRUCTOR_KERNEL_PROGRAM_BINARY_INFO);
CASE_TOK_STR(PATCH_TOKEN_INLINE_VME_SAMPLER_INFO);
CASE_TOK_STR(PATCH_TOKEN_GTPIN_FREE_GRF_INFO);
CASE_TOK_STR(PATCH_TOKEN_GTPIN_INFO);
CASE_TOK_STR(PATCH_TOKEN_PROGRAM_SYMBOL_TABLE);
CASE_TOK_STR(PATCH_TOKEN_PROGRAM_RELOCATION_TABLE);
CASE_TOK_STR(PATCH_TOKEN_MEDIA_VFE_STATE_SLOT1);
}
}
std::string asString(DATA_PARAMETER_TOKEN dataParameter) {
switch (dataParameter) {
default:
return std::to_string(dataParameter);
CASE_TOK_STR(DATA_PARAMETER_TOKEN_UNKNOWN);
CASE_TOK_STR(DATA_PARAMETER_KERNEL_ARGUMENT);
CASE_TOK_STR(DATA_PARAMETER_LOCAL_WORK_SIZE);
CASE_TOK_STR(DATA_PARAMETER_GLOBAL_WORK_SIZE);
CASE_TOK_STR(DATA_PARAMETER_NUM_WORK_GROUPS);
CASE_TOK_STR(DATA_PARAMETER_WORK_DIMENSIONS);
CASE_TOK_STR(DATA_PARAMETER_LOCAL_ID);
CASE_TOK_STR(DATA_PARAMETER_EXECUTION_MASK);
CASE_TOK_STR(DATA_PARAMETER_SUM_OF_LOCAL_MEMORY_OBJECT_ARGUMENT_SIZES);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_WIDTH);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_HEIGHT);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_DEPTH);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_CHANNEL_DATA_TYPE);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_CHANNEL_ORDER);
CASE_TOK_STR(DATA_PARAMETER_FLAT_IMAGE_BASEOFFSET);
CASE_TOK_STR(DATA_PARAMETER_FLAT_IMAGE_WIDTH);
CASE_TOK_STR(DATA_PARAMETER_FLAT_IMAGE_HEIGHT);
CASE_TOK_STR(DATA_PARAMETER_FLAT_IMAGE_PITCH);
CASE_TOK_STR(DATA_PARAMETER_SAMPLER_ADDRESS_MODE);
CASE_TOK_STR(DATA_PARAMETER_SAMPLER_NORMALIZED_COORDS);
CASE_TOK_STR(DATA_PARAMETER_GLOBAL_WORK_OFFSET);
CASE_TOK_STR(DATA_PARAMETER_NUM_HARDWARE_THREADS);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_ARRAY_SIZE);
CASE_TOK_STR(DATA_PARAMETER_PRINTF_SURFACE_SIZE);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_NUM_SAMPLES);
CASE_TOK_STR(DATA_PARAMETER_SAMPLER_COORDINATE_SNAP_WA_REQUIRED);
CASE_TOK_STR(DATA_PARAMETER_PARENT_EVENT);
CASE_TOK_STR(DATA_PARAMETER_VME_MB_BLOCK_TYPE);
CASE_TOK_STR(DATA_PARAMETER_VME_SUBPIXEL_MODE);
CASE_TOK_STR(DATA_PARAMETER_VME_SAD_ADJUST_MODE);
CASE_TOK_STR(DATA_PARAMETER_VME_SEARCH_PATH_TYPE);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_NUM_MIP_LEVELS);
CASE_TOK_STR(DATA_PARAMETER_ENQUEUED_LOCAL_WORK_SIZE);
CASE_TOK_STR(DATA_PARAMETER_MAX_WORKGROUP_SIZE);
CASE_TOK_STR(DATA_PARAMETER_PREFERRED_WORKGROUP_MULTIPLE);
CASE_TOK_STR(DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_START_ADDRESS);
CASE_TOK_STR(DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_SIZE);
CASE_TOK_STR(DATA_PARAMETER_PRIVATE_MEMORY_STATELESS_SIZE);
CASE_TOK_STR(DATA_PARAMETER_SIMD_SIZE);
CASE_TOK_STR(DATA_PARAMETER_OBJECT_ID);
CASE_TOK_STR(DATA_PARAMETER_VME_IMAGE_TYPE);
CASE_TOK_STR(DATA_PARAMETER_VME_MB_SKIP_BLOCK_TYPE);
CASE_TOK_STR(DATA_PARAMETER_CHILD_BLOCK_SIMD_SIZE);
CASE_TOK_STR(DATA_PARAMETER_IMAGE_SRGB_CHANNEL_ORDER);
CASE_TOK_STR(DATA_PARAMETER_STAGE_IN_GRID_ORIGIN);
CASE_TOK_STR(DATA_PARAMETER_STAGE_IN_GRID_SIZE);
CASE_TOK_STR(DATA_PARAMETER_BUFFER_OFFSET);
CASE_TOK_STR(DATA_PARAMETER_BUFFER_STATEFUL);
}
}
#undef CASE_TOK_STR
void dump(const SProgramBinaryHeader &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SProgramBinaryHeader {\n";
out << indent << " uint32_t Magic; // = " << value.Magic << "\n";
out << indent << " uint32_t Version; // = " << value.Version << "\n";
out << indent << "\n";
out << indent << " uint32_t Device; // = " << value.Device << "\n";
out << indent << " uint32_t GPUPointerSizeInBytes; // = " << value.GPUPointerSizeInBytes << "\n";
out << indent << "\n";
out << indent << " uint32_t NumberOfKernels; // = " << value.NumberOfKernels << "\n";
out << indent << "\n";
out << indent << " uint32_t SteppingId; // = " << value.SteppingId << "\n";
out << indent << "\n";
out << indent << " uint32_t PatchListSize; // = " << value.PatchListSize << "\n";
out << indent << "};\n";
}
void dump(const SKernelBinaryHeader &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SKernelBinaryHeader {\n";
out << indent << " uint32_t CheckSum;// = " << value.CheckSum << "\n";
out << indent << " uint64_t ShaderHashCode;// = " << value.ShaderHashCode << "\n";
out << indent << " uint32_t KernelNameSize;// = " << value.KernelNameSize << "\n";
out << indent << " uint32_t PatchListSize;// = " << value.PatchListSize << "\n";
out << indent << "};\n";
}
void dump(const SPatchDataParameterBuffer &value, std::stringstream &out, const std::string &indent);
void dump(const SPatchItemHeader &value, std::stringstream &out, const std::string &indent) {
if (value.Token == iOpenCL::PATCH_TOKEN_DATA_PARAMETER_BUFFER) {
dump(static_cast<const SPatchDataParameterBuffer &>(value), out, indent);
return;
}
out << indent << "struct SPatchItemHeader {\n";
out << indent << " uint32_t Token;// = " << asString(static_cast<PATCH_TOKEN>(value.Token)) << "\n";
out << indent << " uint32_t Size;// = " << value.Size << "\n";
out << indent << "};\n";
}
void dumpPatchItemHeaderInline(const SPatchItemHeader &value, std::stringstream &out, const std::string &indent) {
out << "Token=" << asString(static_cast<PATCH_TOKEN>(value.Token)) << ", Size=" << value.Size;
}
void dump(const SPatchGlobalMemoryObjectKernelArgument &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchGlobalMemoryObjectKernelArgument :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t LocationIndex;// = " << value.LocationIndex << "\n";
out << indent << " uint32_t LocationIndex2;// = " << value.LocationIndex2 << "\n";
out << indent << " uint32_t IsEmulationArgument;// = " << value.IsEmulationArgument << "\n";
out << indent << "}\n";
}
void dump(const SPatchImageMemoryObjectKernelArgument &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchImageMemoryObjectKernelArgument :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t Type;// = " << value.Type << "\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t LocationIndex;// = " << value.LocationIndex << "\n";
out << indent << " uint32_t LocationIndex2;// = " << value.LocationIndex2 << "\n";
out << indent << " uint32_t Writeable;// = " << value.Writeable << "\n";
out << indent << " uint32_t Transformable;// = " << value.Transformable << "\n";
out << indent << " uint32_t needBindlessHandle;// = " << value.needBindlessHandle << "\n";
out << indent << " uint32_t IsEmulationArgument;// = " << value.IsEmulationArgument << "\n";
out << indent << " uint32_t btiOffset;// = " << value.btiOffset << "\n";
out << indent << "}\n";
}
void dump(const SPatchSamplerKernelArgument &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchSamplerKernelArgument :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t Type;// = " << value.Type << "\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t LocationIndex;// = " << value.LocationIndex << "\n";
out << indent << " uint32_t LocationIndex2;// = " << value.LocationIndex2 << "\n";
out << indent << " uint32_t needBindlessHandle;// = " << value.needBindlessHandle << "\n";
out << indent << " uint32_t TextureMask;// = " << value.TextureMask << "\n";
out << indent << " uint32_t IsEmulationArgument;// = " << value.IsEmulationArgument << "\n";
out << indent << " uint32_t btiOffset;// = " << value.btiOffset << "\n";
out << indent << "}\n";
}
void dump(const SPatchDataParameterBuffer &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchDataParameterBuffer :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Type;// = " << asString(static_cast<DATA_PARAMETER_TOKEN>(value.Type)) << "\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t DataSize;// = " << value.DataSize << "\n";
out << indent << " uint32_t SourceOffset;// = " << value.SourceOffset << "\n";
out << indent << " uint32_t LocationIndex;// = " << value.LocationIndex << "\n";
out << indent << " uint32_t LocationIndex2;// = " << value.LocationIndex2 << "\n";
out << indent << " uint32_t IsEmulationArgument;// = " << value.IsEmulationArgument << "\n";
out << indent << "}\n";
}
void dump(const SPatchKernelArgumentInfo &value, std::stringstream &out, const std::string &indent) {
auto toStr = [](ArrayRef<const char> &src) { return std::string(src.begin(), src.end()); };
auto inlineData = getInlineData(&value);
out << indent << "struct SPatchKernelArgumentInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t AddressQualifierSize;// = " << value.AddressQualifierSize << " : [" << toStr(inlineData.addressQualifier) << "]\n";
out << indent << " uint32_t AccessQualifierSize;// = " << value.AccessQualifierSize << " : [" << toStr(inlineData.accessQualifier) << "]\n";
out << indent << " uint32_t ArgumentNameSize;// = " << value.ArgumentNameSize << " : [" << toStr(inlineData.argName) << "]\n";
out << indent << " uint32_t TypeNameSize;// = " << value.TypeNameSize << " : [" << toStr(inlineData.typeName) << "]\n";
out << indent << " uint32_t TypeQualifierSize;// = " << value.TypeQualifierSize << " : [" << toStr(inlineData.typeQualifiers) << "]\n";
out << indent << "}\n";
}
void dump(const SPatchKernelAttributesInfo &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchKernelAttributesInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t AttributesSize;// = " << value.AttributesSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchMediaInterfaceDescriptorLoad &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchMediaInterfaceDescriptorLoad :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t InterfaceDescriptorDataOffset;// = " << value.InterfaceDescriptorDataOffset << "\n";
out << indent << "}\n";
}
void dump(const SPatchInterfaceDescriptorData &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchInterfaceDescriptorData :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t SamplerStateOffset;// = " << value.SamplerStateOffset << "\n";
out << indent << " uint32_t KernelOffset;// = " << value.KernelOffset << "\n";
out << indent << " uint32_t BindingTableOffset;// = " << value.BindingTableOffset << "\n";
out << indent << "}\n";
}
void dump(const SPatchDataParameterStream &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchDataParameterStream :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t DataParameterStreamSize;// = " << value.DataParameterStreamSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchStateSIP &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchStateSIP :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t SystemKernelOffset;// = " << value.SystemKernelOffset << "\n";
out << indent << "}\n";
}
void dump(const SPatchSamplerStateArray &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchSamplerStateArray :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t Count;// = " << value.Count << "\n";
out << indent << " uint32_t BorderColorOffset;// = " << value.BorderColorOffset << "\n";
out << indent << "}\n";
}
void dump(const SPatchBindingTableState &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchBindingTableState :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t Count;// = " << value.Count << "\n";
out << indent << " uint32_t SurfaceStateOffset;// = " << value.SurfaceStateOffset << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateSystemThreadSurface &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateSystemThreadSurface :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t PerThreadSystemThreadSurfaceSize;// = " << value.PerThreadSystemThreadSurfaceSize << "\n";
out << indent << " uint32_t BTI;// = " << value.BTI << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateLocalSurface &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateLocalSurface :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Offset;// = " << value.Offset << "\n";
out << indent << " uint32_t TotalInlineLocalMemorySize;// = " << value.TotalInlineLocalMemorySize << "\n";
out << indent << "}\n";
}
void dump(const SPatchThreadPayload &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchThreadPayload :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t HeaderPresent;// = " << value.HeaderPresent << "\n";
out << indent << " uint32_t LocalIDXPresent;// = " << value.LocalIDXPresent << "\n";
out << indent << " uint32_t LocalIDYPresent;// = " << value.LocalIDYPresent << "\n";
out << indent << " uint32_t LocalIDZPresent;// = " << value.LocalIDZPresent << "\n";
out << indent << " uint32_t LocalIDFlattenedPresent;// = " << value.LocalIDFlattenedPresent << "\n";
out << indent << " uint32_t IndirectPayloadStorage;// = " << value.IndirectPayloadStorage << "\n";
out << indent << " uint32_t UnusedPerThreadConstantPresent;// = " << value.UnusedPerThreadConstantPresent << "\n";
out << indent << " uint32_t GetLocalIDPresent;// = " << value.GetLocalIDPresent << "\n";
out << indent << " uint32_t GetGroupIDPresent;// = " << value.GetGroupIDPresent << "\n";
out << indent << " uint32_t GetGlobalOffsetPresent;// = " << value.GetGlobalOffsetPresent << "\n";
out << indent << " uint32_t StageInGridOriginPresent;// = " << value.StageInGridOriginPresent << "\n";
out << indent << " uint32_t StageInGridSizePresent;// = " << value.StageInGridSizePresent << "\n";
out << indent << " uint32_t OffsetToSkipPerThreadDataLoad;// = " << value.OffsetToSkipPerThreadDataLoad << "\n";
out << indent << " uint32_t OffsetToSkipSetFFIDGP;// = " << value.OffsetToSkipSetFFIDGP << "\n";
out << indent << " uint32_t PassInlineData;// = " << value.PassInlineData << "\n";
out << indent << "}\n";
}
void dump(const SPatchExecutionEnvironment &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchExecutionEnvironment :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t RequiredWorkGroupSizeX;// = " << value.RequiredWorkGroupSizeX << "\n";
out << indent << " uint32_t RequiredWorkGroupSizeY;// = " << value.RequiredWorkGroupSizeY << "\n";
out << indent << " uint32_t RequiredWorkGroupSizeZ;// = " << value.RequiredWorkGroupSizeZ << "\n";
out << indent << " uint32_t LargestCompiledSIMDSize;// = " << value.LargestCompiledSIMDSize << "\n";
out << indent << " uint32_t CompiledSubGroupsNumber;// = " << value.CompiledSubGroupsNumber << "\n";
out << indent << " uint32_t HasBarriers;// = " << value.HasBarriers << "\n";
out << indent << " uint32_t DisableMidThreadPreemption;// = " << value.DisableMidThreadPreemption << "\n";
out << indent << " uint32_t CompiledSIMD8;// = " << value.CompiledSIMD8 << "\n";
out << indent << " uint32_t CompiledSIMD16;// = " << value.CompiledSIMD16 << "\n";
out << indent << " uint32_t CompiledSIMD32;// = " << value.CompiledSIMD32 << "\n";
out << indent << " uint32_t HasDeviceEnqueue;// = " << value.HasDeviceEnqueue << "\n";
out << indent << " uint32_t MayAccessUndeclaredResource;// = " << value.MayAccessUndeclaredResource << "\n";
out << indent << " uint32_t UsesFencesForReadWriteImages;// = " << value.UsesFencesForReadWriteImages << "\n";
out << indent << " uint32_t UsesStatelessSpillFill;// = " << value.UsesStatelessSpillFill << "\n";
out << indent << " uint32_t UsesMultiScratchSpaces;// = " << value.UsesMultiScratchSpaces << "\n";
out << indent << " uint32_t IsCoherent;// = " << value.IsCoherent << "\n";
out << indent << " uint32_t IsInitializer;// = " << value.IsInitializer << "\n";
out << indent << " uint32_t IsFinalizer;// = " << value.IsFinalizer << "\n";
out << indent << " uint32_t SubgroupIndependentForwardProgressRequired;// = " << value.SubgroupIndependentForwardProgressRequired << "\n";
out << indent << " uint32_t CompiledForGreaterThan4GBBuffers;// = " << value.CompiledForGreaterThan4GBBuffers << "\n";
out << indent << " uint32_t NumGRFRequired;// = " << value.NumGRFRequired << "\n";
out << indent << " uint32_t WorkgroupWalkOrderDims;// = " << value.WorkgroupWalkOrderDims << "\n";
out << indent << " uint32_t HasGlobalAtomics;// = " << value.HasGlobalAtomics << "\n";
out << indent << "}\n";
}
void dump(const SPatchString &value, std::stringstream &out, const std::string &indent) {
const char *strBeg = reinterpret_cast<const char *>((&value) + 1);
std::string strValue = std::string(strBeg, strBeg + value.StringSize);
out << indent << "struct SPatchString :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Index;// = " << value.Index << "\n";
out << indent << " uint32_t StringSize;// = " << value.StringSize << " : [" << strValue << "]"
<< "\n";
out << indent << "}\n";
}
void dump(const SPatchStatelessGlobalMemoryObjectKernelArgument &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchStatelessGlobalMemoryObjectKernelArgument :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << " uint32_t LocationIndex;// = " << value.LocationIndex << "\n";
out << indent << " uint32_t LocationIndex2;// = " << value.LocationIndex2 << "\n";
out << indent << " uint32_t IsEmulationArgument;// = " << value.IsEmulationArgument << "\n";
out << indent << "}\n";
}
void dump(const SPatchStatelessConstantMemoryObjectKernelArgument &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchStatelessConstantMemoryObjectKernelArgument :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << " uint32_t LocationIndex;// = " << value.LocationIndex << "\n";
out << indent << " uint32_t LocationIndex2;// = " << value.LocationIndex2 << "\n";
out << indent << " uint32_t IsEmulationArgument;// = " << value.IsEmulationArgument << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateStatelessGlobalMemorySurfaceWithInitialization &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateStatelessGlobalMemorySurfaceWithInitialization :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t GlobalBufferIndex;// = " << value.GlobalBufferIndex << "\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateStatelessConstantMemorySurfaceWithInitialization &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateStatelessConstantMemorySurfaceWithInitialization :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ConstantBufferIndex;// = " << value.ConstantBufferIndex << "\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t Type;// = " << value.Type << "\n";
out << indent << " uint32_t GlobalBufferIndex;// = " << value.GlobalBufferIndex << "\n";
out << indent << " uint32_t InlineDataSize;// = " << value.InlineDataSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateConstantMemorySurfaceProgramBinaryInfo &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateConstantMemorySurfaceProgramBinaryInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ConstantBufferIndex;// = " << value.ConstantBufferIndex << "\n";
out << indent << " uint32_t InlineDataSize;// = " << value.InlineDataSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchGlobalPointerProgramBinaryInfo &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchGlobalPointerProgramBinaryInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t GlobalBufferIndex;// = " << value.GlobalBufferIndex << "\n";
out << indent << " uint64_t GlobalPointerOffset;// = " << value.GlobalPointerOffset << "\n";
out << indent << " uint32_t BufferType;// = " << value.BufferType << "\n";
out << indent << " uint32_t BufferIndex;// = " << value.BufferIndex << "\n";
out << indent << "}\n";
}
void dump(const SPatchConstantPointerProgramBinaryInfo &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchConstantPointerProgramBinaryInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ConstantBufferIndex;// = " << value.ConstantBufferIndex << "\n";
out << indent << " uint64_t ConstantPointerOffset;// = " << value.ConstantPointerOffset << "\n";
out << indent << " uint32_t BufferType;// = " << value.BufferType << "\n";
out << indent << " uint32_t BufferIndex;// = " << value.BufferIndex << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateStatelessPrintfSurface &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateStatelessPrintfSurface :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t PrintfSurfaceIndex;// = " << value.PrintfSurfaceIndex << "\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateStatelessPrivateSurface &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateStatelessPrivateSurface :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << " uint32_t PerThreadPrivateMemorySize;// = " << value.PerThreadPrivateMemorySize << "\n";
out << indent << "}\n";
}
void dump(const SPatchMediaVFEState &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchMediaVFEState :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ScratchSpaceOffset;// = " << value.ScratchSpaceOffset << "\n";
out << indent << " uint32_t PerThreadScratchSpace;// = " << value.PerThreadScratchSpace << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateStatelessEventPoolSurface &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateStatelessEventPoolSurface :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t EventPoolSurfaceIndex;// = " << value.EventPoolSurfaceIndex << "\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchAllocateStatelessDefaultDeviceQueueSurface &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchAllocateStatelessDefaultDeviceQueueSurface :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchStatelessDeviceQueueKernelArgument &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchStatelessDeviceQueueKernelArgument :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t ArgumentNumber;// = " << value.ArgumentNumber << "\n";
out << indent << " uint32_t SurfaceStateHeapOffset;// = " << value.SurfaceStateHeapOffset << "\n";
out << indent << " uint32_t DataParamOffset;// = " << value.DataParamOffset << "\n";
out << indent << " uint32_t DataParamSize;// = " << value.DataParamSize << "\n";
out << indent << " uint32_t LocationIndex;// = " << value.LocationIndex << "\n";
out << indent << " uint32_t LocationIndex2;// = " << value.LocationIndex2 << "\n";
out << indent << " uint32_t IsEmulationArgument;// = " << value.IsEmulationArgument << "\n";
out << indent << "}\n";
}
void dump(const SPatchGtpinFreeGRFInfo &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchGtpinFreeGRFInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t BufferSize;// = " << value.BufferSize << "\n";
out << indent << "}\n";
}
void dump(const SPatchFunctionTableInfo &value, std::stringstream &out, const std::string &indent) {
out << indent << "struct SPatchFunctionTableInfo :\n";
out << indent << " SPatchItemHeader (";
dumpPatchItemHeaderInline(value, out, "");
out << ")\n"
<< indent << "{\n";
out << indent << " uint32_t NumEntries;// = " << value.NumEntries << "\n";
out << indent << "}\n";
}
template <typename T>
void dumpOrNull(const T *value, const std::string &messageIfNull, std::stringstream &out, const std::string &indent) {
if (value == nullptr) {
if (messageIfNull.empty() == false) {
out << indent << messageIfNull;
}
return;
}
dump(*value, out, indent);
}
template <typename T>
void dumpOrNullObjArg(const T *value, std::stringstream &out, const std::string &indent) {
if (value == nullptr) {
return;
}
switch (value->Token) {
default:
UNRECOVERABLE_IF(value->Token != PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT);
dumpOrNull(reinterpret_cast<const SPatchSamplerKernelArgument *>(value), "", out, indent);
break;
case PATCH_TOKEN_IMAGE_MEMORY_OBJECT_KERNEL_ARGUMENT:
dumpOrNull(reinterpret_cast<const SPatchImageMemoryObjectKernelArgument *>(value), "", out, indent);
break;
case PATCH_TOKEN_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT:
dumpOrNull(reinterpret_cast<const SPatchGlobalMemoryObjectKernelArgument *>(value), "", out, indent);
break;
case PATCH_TOKEN_STATELESS_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT:
dumpOrNull(reinterpret_cast<const SPatchStatelessGlobalMemoryObjectKernelArgument *>(value), "", out, indent);
break;
case PATCH_TOKEN_STATELESS_CONSTANT_MEMORY_OBJECT_KERNEL_ARGUMENT:
dumpOrNull(reinterpret_cast<const SPatchStatelessConstantMemoryObjectKernelArgument *>(value), "", out, indent);
break;
case PATCH_TOKEN_STATELESS_DEVICE_QUEUE_KERNEL_ARGUMENT:
dumpOrNull(reinterpret_cast<const SPatchStatelessDeviceQueueKernelArgument *>(value), "", out, indent);
break;
}
}
template <typename T, size_t Size>
void dumpOrNullArrayIfNotEmpty(T (&value)[Size], const std::string &arrayName, std::stringstream &out, const std::string &indent) {
bool allEmpty = true;
for (size_t i = 0; i < Size; ++i) {
allEmpty = allEmpty && (value[i] == nullptr);
}
if (allEmpty) {
return;
}
out << indent << arrayName << " [" << Size << "] :\n";
for (size_t i = 0; i < Size; ++i) {
if (value[i] == nullptr) {
continue;
}
out << indent << " + [" << i << "]:\n";
dump(*value[i], out, indent + " | ");
}
}
template <typename T>
void dumpVecIfNotEmpty(const T &vector, const std::string &vectorName, std::stringstream &out, const std::string &indent) {
if (vector.size() == 0) {
return;
}
out << indent << vectorName << " [" << vector.size() << "] :\n";
for (size_t i = 0; i < vector.size(); ++i) {
out << indent << " + [" << i << "]:\n";
dumpOrNull(vector[i], "DECODER INTERNAL ERROR\n", out, indent + " | ");
}
}
const char *asString(DecoderError err) {
switch (err) {
default:
DEBUG_BREAK_IF(err != DecoderError::InvalidBinary);
return "with invalid binary";
break;
case DecoderError::Success:
return "decoded successfully";
break;
case DecoderError::Undefined:
return "in undefined status";
break;
}
}
std::string asString(const ProgramFromPatchtokens &prog) {
std::stringstream stream;
stream << "Program of size : " << prog.blobs.programInfo.size()
<< " " << asString(prog.decodeStatus) << "\n";
dumpOrNull(prog.header, "WARNING : Program header is missing\n", stream, "");
stream << "Program-scope tokens section size : " << prog.blobs.patchList.size() << "\n";
dumpVecIfNotEmpty(prog.unhandledTokens, "WARNING : Unhandled program-scope tokens detected", stream, " ");
dumpVecIfNotEmpty(prog.programScopeTokens.allocateConstantMemorySurface, "Inline Costant Surface(s)", stream, " ");
dumpVecIfNotEmpty(prog.programScopeTokens.constantPointer, "Inline Costant Surface - self relocations", stream, " ");
dumpVecIfNotEmpty(prog.programScopeTokens.allocateGlobalMemorySurface, "Inline Global Variable Surface(s)", stream, " ");
dumpVecIfNotEmpty(prog.programScopeTokens.globalPointer, "Inline Global Variable Surface - self relocations", stream, " ");
dumpOrNull(prog.programScopeTokens.symbolTable, "", stream, " ");
stream << "Kernels section size : " << prog.blobs.kernelsInfo.size() << "\n";
for (size_t i = 0; i < prog.kernels.size(); ++i) {
stream << "kernel[" << i << "] " << (prog.kernels[i].name.size() > 0 ? std::string(prog.kernels[i].name.begin(), prog.kernels[i].name.end()).c_str() : "<UNNAMED>") << ":\n";
stream << asString(prog.kernels[i]);
}
return stream.str();
}
std::string asString(const KernelFromPatchtokens &kern) {
std::stringstream stream;
std::string indentLevel1 = " ";
stream << "Kernel of size : " << kern.blobs.kernelInfo.size() << " "
<< " " << asString(kern.decodeStatus) << "\n";
dumpOrNull(kern.header, "WARNING : Kernel header is missing\n", stream, "");
stream << "Kernel-scope tokens section size : " << kern.blobs.patchList.size() << "\n";
dumpVecIfNotEmpty(kern.unhandledTokens, "WARNING : Unhandled kernel-scope tokens detected", stream, indentLevel1);
dumpOrNull(kern.tokens.executionEnvironment, "", stream, indentLevel1);
dumpOrNull(kern.tokens.threadPayload, "", stream, indentLevel1);
dumpOrNull(kern.tokens.samplerStateArray, "", stream, indentLevel1);
dumpOrNull(kern.tokens.bindingTableState, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateLocalSurface, "", stream, indentLevel1);
dumpOrNullArrayIfNotEmpty(kern.tokens.mediaVfeState, "mediaVfeState", stream, indentLevel1);
dumpOrNull(kern.tokens.mediaInterfaceDescriptorLoad, "", stream, indentLevel1);
dumpOrNull(kern.tokens.interfaceDescriptorData, "", stream, indentLevel1);
dumpOrNull(kern.tokens.kernelAttributesInfo, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateStatelessPrivateSurface, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateStatelessConstantMemorySurfaceWithInitialization, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateStatelessGlobalMemorySurfaceWithInitialization, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateStatelessPrintfSurface, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateStatelessEventPoolSurface, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateStatelessDefaultDeviceQueueSurface, "", stream, indentLevel1);
dumpOrNull(kern.tokens.inlineVmeSamplerInfo, "", stream, indentLevel1);
dumpOrNull(kern.tokens.gtpinFreeGrfInfo, "", stream, indentLevel1);
dumpOrNull(kern.tokens.stateSip, "", stream, indentLevel1);
dumpOrNull(kern.tokens.allocateSystemThreadSurface, "", stream, indentLevel1);
dumpOrNull(kern.tokens.gtpinInfo, "", stream, indentLevel1);
dumpOrNull(kern.tokens.programSymbolTable, "", stream, indentLevel1);
dumpOrNull(kern.tokens.programRelocationTable, "", stream, indentLevel1);
dumpOrNull(kern.tokens.dataParameterStream, "", stream, indentLevel1);
dumpVecIfNotEmpty(kern.tokens.strings, "String literals", stream, indentLevel1);
dumpOrNullArrayIfNotEmpty(kern.tokens.crossThreadPayloadArgs.localWorkSize, "localWorkSize", stream, indentLevel1);
dumpOrNullArrayIfNotEmpty(kern.tokens.crossThreadPayloadArgs.localWorkSize2, "localWorkSize2", stream, indentLevel1);
dumpOrNullArrayIfNotEmpty(kern.tokens.crossThreadPayloadArgs.enqueuedLocalWorkSize, "enqueuedLocalWorkSize", stream, indentLevel1);
dumpOrNullArrayIfNotEmpty(kern.tokens.crossThreadPayloadArgs.numWorkGroups, "numWorkGroups", stream, indentLevel1);
dumpOrNullArrayIfNotEmpty(kern.tokens.crossThreadPayloadArgs.globalWorkOffset, "globalWorkOffset", stream, indentLevel1);
dumpOrNullArrayIfNotEmpty(kern.tokens.crossThreadPayloadArgs.globalWorkSize, "globalWorkSize", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.maxWorkGroupSize, "", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.workDimensions, "", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.simdSize, "", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.parentEvent, "", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.privateMemoryStatelessSize, "", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.localMemoryStatelessWindowSize, "", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.localMemoryStatelessWindowStartAddress, "", stream, indentLevel1);
dumpOrNull(kern.tokens.crossThreadPayloadArgs.preferredWorkgroupMultiple, "", stream, indentLevel1);
dumpVecIfNotEmpty(kern.tokens.crossThreadPayloadArgs.childBlockSimdSize, "Child block simd size(s)", stream, indentLevel1);
if (kern.tokens.kernelArgs.size() != 0) {
stream << "Kernel arguments [" << kern.tokens.kernelArgs.size() << "] :\n";
for (size_t i = 0; i < kern.tokens.kernelArgs.size(); ++i) {
stream << " + kernelArg[" << i << "]:\n";
stream << asString(kern.tokens.kernelArgs[i], indentLevel1 + "| ");
}
}
return stream.str();
}
std::string asString(ArgObjectType type, ArgObjectTypeSpecialized typeSpecialized) {
std::string typeAsStr;
switch (type) {
default:
UNRECOVERABLE_IF(ArgObjectType::None != type);
return "unspecified";
case ArgObjectType::Buffer:
typeAsStr = "BUFFER";
break;
case ArgObjectType::Image:
typeAsStr = "IMAGE";
break;
case ArgObjectType::Sampler:
typeAsStr = "SAMPLER";
break;
case ArgObjectType::Slm:
typeAsStr = "SLM";
break;
}
switch (typeSpecialized) {
default:
UNRECOVERABLE_IF(ArgObjectTypeSpecialized::None != typeSpecialized);
break;
case ArgObjectTypeSpecialized::Vme:
typeAsStr += " [ VME ]";
}
return typeAsStr;
}
std::string asString(const KernelArgFromPatchtokens &arg, const std::string &indent) {
std::stringstream stream;
stream << indent << "Kernel argument of type " << asString(arg.objectType, arg.objectTypeSpecialized) << "\n";
std::string indentLevel1 = indent + " ";
std::string indentLevel2 = indentLevel1 + " ";
dumpOrNull(arg.argInfo, "", stream, indentLevel1);
dumpOrNullObjArg(arg.objectArg, stream, indentLevel1);
dumpOrNull(arg.objectId, "", stream, indentLevel1);
switch (arg.objectType) {
default:
break;
case ArgObjectType::Buffer:
stream << indentLevel1 << "Buffer Metadata:\n";
dumpOrNull(arg.metadata.buffer.bufferOffset, "", stream, indentLevel2);
dumpOrNull(arg.metadata.buffer.pureStateful, "", stream, indentLevel2);
break;
case ArgObjectType::Image:
stream << indentLevel1 << "Image Metadata:\n";
dumpOrNull(arg.metadata.image.width, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.height, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.depth, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.channelDataType, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.channelOrder, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.arraySize, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.numSamples, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.numMipLevels, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.flatBaseOffset, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.flatWidth, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.flatHeight, "", stream, indentLevel2);
dumpOrNull(arg.metadata.image.flatPitch, "", stream, indentLevel2);
break;
case ArgObjectType::Sampler:
stream << indentLevel1 << "Sampler Metadata:\n";
dumpOrNull(arg.metadata.sampler.addressMode, "", stream, indentLevel2);
dumpOrNull(arg.metadata.sampler.coordinateSnapWaRequired, "", stream, indentLevel2);
dumpOrNull(arg.metadata.sampler.normalizedCoords, "", stream, indentLevel2);
break;
case ArgObjectType::Slm:
stream << indentLevel1 << "Slm Metadata:\n";
dumpOrNull(arg.metadata.slm.token, "", stream, indentLevel2);
break;
}
switch (arg.objectTypeSpecialized) {
default:
break;
case ArgObjectTypeSpecialized::Vme:
stream << indentLevel1 << "Vme Metadata:\n";
dumpOrNull(arg.metadataSpecialized.vme.mbBlockType, "", stream, indentLevel2);
dumpOrNull(arg.metadataSpecialized.vme.sadAdjustMode, "", stream, indentLevel2);
dumpOrNull(arg.metadataSpecialized.vme.searchPathType, "", stream, indentLevel2);
dumpOrNull(arg.metadataSpecialized.vme.subpixelMode, "", stream, indentLevel2);
break;
}
dumpVecIfNotEmpty(arg.byValMap, " Data passed by value ", stream, indentLevel1);
return stream.str();
}
} // namespace PatchTokenBinary
} // namespace NEO

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <string>
namespace NEO {
namespace PatchTokenBinary {
struct ProgramFromPatchtokens;
struct KernelFromPatchtokens;
struct KernelArgFromPatchtokens;
std::string asString(const ProgramFromPatchtokens &prog);
std::string asString(const KernelFromPatchtokens &kern);
std::string asString(const KernelArgFromPatchtokens &arg, const std::string &indent);
} // namespace PatchTokenBinary
} // namespace NEO

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "core/device_binary_format/patchtokens_decoder.h"
#include "core/helpers/hw_info.h"
#include "runtime/program/kernel_arg_info.h"
#include "igfxfmid.h"
#include <string>
namespace NEO {
namespace PatchTokenBinary {
enum class ValidatorError {
Success = 0,
Undefined = 1,
InvalidBinary = 2,
NotEnoughSlm = 3,
};
constexpr bool isDeviceSupported(GFXCORE_FAMILY device) {
return (device < (sizeof(familyEnabled) / sizeof(familyEnabled[0]))) && familyEnabled[device];
}
template <typename UknownTokenValidatorT>
inline ValidatorError validate(const ProgramFromPatchtokens &decodedProgram,
size_t sharedLocalMemorySize,
const UknownTokenValidatorT &tokenValidator,
std::string &outErrReason, std::string &outWarnings) {
if (decodedProgram.decodeStatus != PatchTokenBinary::DecoderError::Success) {
outErrReason = "ProgramFromPatchtokens wasn't successfully decoded";
return ValidatorError::InvalidBinary;
}
if (decodedProgram.programScopeTokens.allocateConstantMemorySurface.size() > 1) {
outErrReason = "Unhandled number of global constants surfaces > 1";
return ValidatorError::InvalidBinary;
}
if (decodedProgram.programScopeTokens.allocateGlobalMemorySurface.size() > 1) {
outErrReason = "Unhandled number of global variables surfaces > 1";
return ValidatorError::InvalidBinary;
}
for (const auto &globalConstantPointerToken : decodedProgram.programScopeTokens.constantPointer) {
bool isUnhandled = (globalConstantPointerToken->ConstantBufferIndex != 0);
isUnhandled |= (globalConstantPointerToken->BufferIndex != 0);
isUnhandled |= (globalConstantPointerToken->BufferType != PROGRAM_SCOPE_CONSTANT_BUFFER) && (globalConstantPointerToken->BufferType != PROGRAM_SCOPE_GLOBAL_BUFFER);
isUnhandled |= (globalConstantPointerToken->BufferType == PROGRAM_SCOPE_GLOBAL_BUFFER) && (decodedProgram.programScopeTokens.allocateGlobalMemorySurface.empty());
isUnhandled |= (decodedProgram.programScopeTokens.allocateConstantMemorySurface.empty()) || decodedProgram.programScopeTokens.allocateConstantMemorySurface[0]->InlineDataSize < globalConstantPointerToken->ConstantPointerOffset + sizeof(uint32_t);
if (isUnhandled) {
outErrReason = "Unhandled SPatchConstantPointerProgramBinaryInfo";
return ValidatorError::InvalidBinary;
}
}
for (const auto &globalVariablePointerToken : decodedProgram.programScopeTokens.globalPointer) {
bool isUnhandled = (globalVariablePointerToken->GlobalBufferIndex != 0);
isUnhandled |= (globalVariablePointerToken->BufferIndex != 0);
isUnhandled |= (globalVariablePointerToken->BufferType != PROGRAM_SCOPE_GLOBAL_BUFFER) && (globalVariablePointerToken->BufferType != PROGRAM_SCOPE_CONSTANT_BUFFER);
isUnhandled |= (globalVariablePointerToken->BufferType == PROGRAM_SCOPE_CONSTANT_BUFFER) && (decodedProgram.programScopeTokens.allocateConstantMemorySurface.empty());
isUnhandled |= (decodedProgram.programScopeTokens.allocateGlobalMemorySurface.empty()) || decodedProgram.programScopeTokens.allocateGlobalMemorySurface[0]->InlineDataSize < globalVariablePointerToken->GlobalPointerOffset + sizeof(uint32_t);
if (isUnhandled) {
outErrReason = "Unhandled SPatchGlobalPointerProgramBinaryInfo";
return ValidatorError::InvalidBinary;
}
}
for (const auto &unhandledToken : decodedProgram.unhandledTokens) {
if (false == tokenValidator.isSafeToSkipUnhandledToken(unhandledToken->Token)) {
outErrReason = "Unhandled required program-scope Patch Token : " + std::to_string(unhandledToken->Token);
return ValidatorError::InvalidBinary;
} else {
outWarnings = "Unknown program-scope Patch Token : " + std::to_string(unhandledToken->Token);
}
}
UNRECOVERABLE_IF(nullptr == decodedProgram.header);
if (decodedProgram.header->Version != CURRENT_ICBE_VERSION) {
outErrReason = "Unhandled Version of Patchtokens: expected: " + std::to_string(CURRENT_ICBE_VERSION) + ", got: " + std::to_string(decodedProgram.header->Version);
return ValidatorError::InvalidBinary;
}
if ((decodedProgram.header->GPUPointerSizeInBytes != 4U) && (decodedProgram.header->GPUPointerSizeInBytes != 8U)) {
outErrReason = "Invalid pointer size";
return ValidatorError::InvalidBinary;
}
if (false == isDeviceSupported(static_cast<GFXCORE_FAMILY>(decodedProgram.header->Device))) {
outErrReason = "Unsupported device binary, device GFXCORE_FAMILY : " + std::to_string(decodedProgram.header->Device);
return ValidatorError::InvalidBinary;
}
for (const auto &decodedKernel : decodedProgram.kernels) {
if (decodedKernel.decodeStatus != PatchTokenBinary::DecoderError::Success) {
outErrReason = "KernelFromPatchtokens wasn't successfully decoded";
return ValidatorError::InvalidBinary;
}
UNRECOVERABLE_IF(nullptr == decodedKernel.header);
if (hasInvalidChecksum(decodedKernel)) {
outErrReason = "KernelFromPatchtokens has invalid checksum";
return ValidatorError::InvalidBinary;
}
if (nullptr == decodedKernel.tokens.executionEnvironment) {
outErrReason = "Missing execution environment";
return ValidatorError::InvalidBinary;
} else {
switch (decodedKernel.tokens.executionEnvironment->LargestCompiledSIMDSize) {
case 1:
break;
case 8:
break;
case 16:
break;
case 32:
break;
default:
outErrReason = "Invalid LargestCompiledSIMDSize";
return ValidatorError::InvalidBinary;
}
}
if (decodedKernel.tokens.allocateLocalSurface) {
if (sharedLocalMemorySize < decodedKernel.tokens.allocateLocalSurface->TotalInlineLocalMemorySize) {
outErrReason = "KernelFromPatchtokens requires too much SLM";
return ValidatorError::NotEnoughSlm;
}
}
for (auto &kernelArg : decodedKernel.tokens.kernelArgs) {
if (kernelArg.argInfo == nullptr) {
outErrReason = "Missing kernelArgInfo";
return ValidatorError::InvalidBinary;
}
auto argInfoInlineData = getInlineData(kernelArg.argInfo);
auto accessQualifier = KernelArgMetadata::parseAccessQualifier(parseLimitedString(argInfoInlineData.accessQualifier.begin(), argInfoInlineData.accessQualifier.size()));
if (KernelArgMetadata::AccessQualifier::Unknown == accessQualifier) {
outErrReason = "Unhandled access qualifier";
return ValidatorError::InvalidBinary;
}
auto addressQualifier = KernelArgMetadata::parseAddressSpace(parseLimitedString(argInfoInlineData.addressQualifier.begin(), argInfoInlineData.addressQualifier.size()));
if (KernelArgMetadata::AddressSpaceQualifier::Unknown == addressQualifier) {
outErrReason = "Unhandled address qualifier";
return ValidatorError::InvalidBinary;
}
}
for (const auto &unhandledToken : decodedKernel.unhandledTokens) {
if (false == tokenValidator.isSafeToSkipUnhandledToken(unhandledToken->Token)) {
outErrReason = "Unhandled required kernel-scope Patch Token : " + std::to_string(unhandledToken->Token);
return ValidatorError::InvalidBinary;
} else {
outWarnings = "Unknown kernel-scope Patch Token : " + std::to_string(unhandledToken->Token);
}
}
}
return ValidatorError::Success;
}
} // namespace PatchTokenBinary
} // namespace NEO

View File

@@ -9,8 +9,8 @@
#include "core/compiler_interface/linker.h"
#include "core/debug_settings/debug_settings_manager.h"
#include "core/device_binary_format/patchtokens_decoder.h"
#include "core/program/program_info.h"
#include "runtime/compiler_interface/patchtokens_decoder.h"
#include "runtime/program/kernel_info.h"
#include "runtime/program/kernel_info_from_patchtokens.h"

View File

@@ -0,0 +1,15 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_DEVICE_BINARY_FORMAT_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_decoder_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_dumper_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_tests.h
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_validator_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_DEVICE_BINARY_FORMAT_TESTS ${NEO_DEVICE_BINARY_FORMAT_TESTS})

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,333 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "core/device_binary_format/patchtokens_decoder.h"
#include "igfxfmid.h"
#include <vector>
extern GFXCORE_FAMILY renderCoreFamily;
namespace PatchTokensTestData {
template <typename TokenT>
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<uint32_t>(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<uint8_t> &storage) {
auto offset = storage.size();
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(str.c_str()), reinterpret_cast<const uint8_t *>(str.c_str()) + str.size());
return static_cast<uint32_t>(offset);
}
inline uint32_t pushBackStringToken(const std::string &str, uint32_t stringIndex, std::vector<uint8_t> &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<iOpenCL::SPatchString *>(outStream.data() + off);
*tok = initToken<iOpenCL::SPatchString>(iOpenCL::PATCH_TOKEN::PATCH_TOKEN_STRING);
tok->StringSize = static_cast<uint32_t>(str.length());
tok->Size += tok->StringSize;
tok->Index = stringIndex;
pushBackString(str, outStream);
return static_cast<uint32_t>(off);
};
inline uint32_t pushBackArgInfoToken(std::vector<uint8_t> &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<uint32_t>(addressQualifier.size());
tok.AccessQualifierSize = static_cast<uint32_t>(accessQualifier.size());
tok.ArgumentNameSize = static_cast<uint32_t>(argName.size());
tok.TypeNameSize = static_cast<uint32_t>(typeName.size());
tok.TypeQualifierSize = static_cast<uint32_t>(typeQualifier.size());
tok.Size = sizeof(iOpenCL::SPatchKernelArgumentInfo) + tok.AddressQualifierSize + tok.AccessQualifierSize + tok.ArgumentNameSize + tok.TypeNameSize + tok.TypeQualifierSize;
outStream.insert(outStream.end(), reinterpret_cast<const uint8_t *>(&tok), reinterpret_cast<const uint8_t *>(&tok) + sizeof(tok));
pushBackString(addressQualifier, outStream);
pushBackString(accessQualifier, outStream);
pushBackString(argName, outStream);
pushBackString(typeName, outStream);
pushBackString(typeQualifier, outStream);
return static_cast<uint32_t>(off);
}
struct ValidEmptyProgram : NEO::PatchTokenBinary::ProgramFromPatchtokens {
ValidEmptyProgram() {
iOpenCL::SProgramBinaryHeader headerTok = {};
headerTok.Magic = iOpenCL::MAGIC_CL;
headerTok.Version = iOpenCL::CURRENT_ICBE_VERSION;
headerTok.Device = renderCoreFamily;
headerTok.GPUPointerSizeInBytes = sizeof(uintptr_t);
this->decodeStatus = NEO::PatchTokenBinary::DecoderError::Success;
storage.insert(storage.end(), reinterpret_cast<uint8_t *>(&headerTok), reinterpret_cast<uint8_t *>((&headerTok) + 1));
recalcTokPtr();
}
void recalcTokPtr() {
this->blobs.programInfo = storage;
this->headerMutable = reinterpret_cast<iOpenCL::SProgramBinaryHeader *>(storage.data());
this->header = this->headerMutable;
}
std::vector<uint8_t> 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<uint8_t *>(&constSurfTok), reinterpret_cast<uint8_t *>((&constSurfTok) + 1));
storage.resize(storage.size() + constSurfTok.InlineDataSize);
recalcTokPtr();
}
void recalcTokPtr() {
ValidEmptyProgram::recalcTokPtr();
this->constSurfMutable = reinterpret_cast<iOpenCL::SPatchAllocateConstantMemorySurfaceProgramBinaryInfo *>(storage.data() + sizeof(*this->headerMutable));
this->programScopeTokens.allocateConstantMemorySurface[0] = this->constSurfMutable;
this->blobs.patchList = ArrayRef<const uint8_t>(storage.data() + sizeof(*this->headerMutable), storage.size() - sizeof(*this->headerMutable));
this->headerMutable->PatchListSize = static_cast<uint32_t>(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<uint8_t *>(&globalSurfTok), reinterpret_cast<uint8_t *>((&globalSurfTok) + 1));
storage.resize(storage.size() + globalSurfTok.InlineDataSize);
recalcTokPtr();
}
void recalcTokPtr() {
ValidEmptyProgram::recalcTokPtr();
this->globalSurfMutable = reinterpret_cast<iOpenCL::SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *>(storage.data() + sizeof(*this->headerMutable));
this->programScopeTokens.allocateGlobalMemorySurface[0] = this->globalSurfMutable;
this->blobs.patchList = ArrayRef<const uint8_t>(storage.data() + sizeof(*this->headerMutable), storage.size() - sizeof(*this->headerMutable));
this->headerMutable->PatchListSize = static_cast<uint32_t>(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<uint8_t *>(&constantPointerTok), reinterpret_cast<uint8_t *>((&constantPointerTok) + 1));
recalcTokPtr();
}
void recalcTokPtr() {
ValidProgramWithConstantSurface::recalcTokPtr();
this->constantPointerMutable = reinterpret_cast<iOpenCL::SPatchConstantPointerProgramBinaryInfo *>(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<uint8_t *>(&globalPointerTok), reinterpret_cast<uint8_t *>((&globalPointerTok) + 1));
recalcTokPtr();
}
void recalcTokPtr() {
ValidProgramWithGlobalSurface::recalcTokPtr();
this->globalPointerMutable = reinterpret_cast<iOpenCL::SPatchGlobalPointerProgramBinaryInfo *>(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<iOpenCL::SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo *>(storage.data() + globalVariableTokensOffset);
this->programScopeTokens.allocateGlobalMemorySurface[0] = this->globalSurfMutable;
this->blobs.patchList = ArrayRef<const uint8_t>(storage.data() + sizeof(*this->headerMutable), storage.size() - sizeof(*this->headerMutable));
this->headerMutable->PatchListSize = static_cast<uint32_t>(this->blobs.patchList.size());
this->globalPointerMutable = reinterpret_cast<iOpenCL::SPatchGlobalPointerProgramBinaryInfo *>(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<uint8_t> &storage) {
NEO::PatchTokenBinary::KernelFromPatchtokens ret;
iOpenCL::SKernelBinaryHeaderCommon headerTokInl = {};
auto execEnvTokInl = initToken<iOpenCL::SPatchExecutionEnvironment>(iOpenCL::PATCH_TOKEN_EXECUTION_ENVIRONMENT);
execEnvTokInl.LargestCompiledSIMDSize = 32U;
execEnvTokInl.CompiledSIMD32 = 1U;
headerTokInl.PatchListSize = sizeof(execEnvTokInl);
ret.decodeStatus = NEO::PatchTokenBinary::DecoderError::Success;
ret.name = "test_kernel";
headerTokInl.KernelNameSize = static_cast<uint32_t>(ret.name.size());
auto kernOffset = storage.size();
storage.reserve(storage.size() + 512);
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&headerTokInl), reinterpret_cast<const uint8_t *>((&headerTokInl) + 1));
auto headerTok = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(&*(storage.begin() + kernOffset));
ret.NEO::PatchTokenBinary::KernelFromPatchtokens::header = headerTok;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(ret.name.begin()), reinterpret_cast<const uint8_t *>(ret.name.end()));
auto execEnvOffset = storage.size();
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&execEnvTokInl), reinterpret_cast<const uint8_t *>((&execEnvTokInl) + 1));
ret.blobs.kernelInfo = ArrayRef<const uint8_t>(storage.data() + kernOffset, storage.data() + kernOffset + storage.size());
headerTok->CheckSum = NEO::PatchTokenBinary::calcKernelChecksum(ret.blobs.kernelInfo);
ret.blobs.patchList = ArrayRef<const uint8_t>(storage.data() + execEnvOffset, storage.data() + storage.size());
ret.tokens.executionEnvironment = reinterpret_cast<iOpenCL::SPatchExecutionEnvironment *>(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::PatchTokenBinary::DecoderError::Success;
kernExecEnvOffset = ptrDiff(this->kernels[0].blobs.patchList.begin(), storage.data());
recalcTokPtr();
}
void recalcTokPtr() {
ValidEmptyProgram::recalcTokPtr();
this->kernels[0].blobs.kernelInfo = ArrayRef<const uint8_t>(storage.data() + kernOffset, storage.data() + storage.size());
kernelHeaderMutable = reinterpret_cast<iOpenCL::SKernelBinaryHeaderCommon *>(&*(storage.begin() + kernOffset));
this->kernels[0].header = kernelHeaderMutable;
char *name = reinterpret_cast<char *>(storage.data() + kernOffset + sizeof(iOpenCL::SKernelBinaryHeaderCommon));
this->kernels[0].name = ArrayRef<const char>(name, name + kernelHeaderMutable->KernelNameSize);
kernelExecEnvMutable = reinterpret_cast<iOpenCL::SPatchExecutionEnvironment *>(&*(storage.begin() + kernExecEnvOffset));
this->kernels[0].tokens.executionEnvironment = kernelExecEnvMutable;
this->kernels[0].blobs.patchList = ArrayRef<const uint8_t>(storage.data() + kernExecEnvOffset, storage.data() + storage.size());
this->kernelHeaderMutable->PatchListSize = static_cast<uint32_t>(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<const uint8_t *>(&slmTok), reinterpret_cast<const uint8_t *>((&slmTok) + 1));
recalcTokPtr();
}
void recalcTokPtr() {
ValidProgramWithKernel::recalcTokPtr();
slmMutable = reinterpret_cast<iOpenCL::SPatchAllocateLocalSurface *>(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<iOpenCL::SPatchKernelArgumentInfo *>(storage.data() + kernelArgOffset);
this->kernels[0].tokens.kernelArgs[0].argInfo = arg0InfoMutable;
arg0InfoAddressQualifierMutable = reinterpret_cast<char *>(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;
};
} // namespace PatchTokensTestData

View File

@@ -0,0 +1,539 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "core/device_binary_format/patchtokens_decoder.h"
#include "core/device_binary_format/patchtokens_validator.inl"
#include "core/unit_tests/device_binary_format/patchtokens_tests.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
struct UknownTokenValidator {
UknownTokenValidator(bool isSafeToSkip = true) : isSafeToSkip(isSafeToSkip) {
}
bool isSafeToSkipUnhandledToken(uint32_t token) const {
return isSafeToSkip;
}
bool isSafeToSkip = true;
};
TEST(PatchtokensValidator, GivenValidProgramThenValidationSucceeds) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidOrUnknownStatusThenValidationFails) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
prog.decodeStatus = NEO::PatchTokenBinary::DecoderError::Undefined;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("ProgramFromPatchtokens wasn't successfully decoded", error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
warning.clear();
prog.decodeStatus = NEO::PatchTokenBinary::DecoderError::InvalidBinary;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("ProgramFromPatchtokens wasn't successfully decoded", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithASingleConstantSurfaceThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithConstantSurface prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithMultipleConstantSurfacesThenValidationFails) {
PatchTokensTestData::ValidProgramWithConstantSurface prog;
std::string error, warning;
iOpenCL::SPatchAllocateConstantMemorySurfaceProgramBinaryInfo constSurface2 = *prog.programScopeTokens.allocateConstantMemorySurface[0];
prog.programScopeTokens.allocateConstantMemorySurface.push_back(&constSurface2);
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled number of global constants surfaces > 1", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithASingleGlobalSurfaceThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithGlobalSurface prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithMultipleGlobalSurfacesThenValidationFails) {
PatchTokensTestData::ValidProgramWithGlobalSurface prog;
std::string error, warning;
iOpenCL::SPatchAllocateGlobalMemorySurfaceProgramBinaryInfo globSurface2 = *prog.programScopeTokens.allocateGlobalMemorySurface[0];
prog.programScopeTokens.allocateGlobalMemorySurface.push_back(&globSurface2);
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled number of global variables surfaces > 1", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithValidConstantPointerThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerBufferIndexThenValidationFails) {
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog;
std::string error, warning;
prog.constantPointerMutable->BufferIndex = 1;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidGpuPointerSizeThenValidationFails) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
prog.headerMutable->GPUPointerSizeInBytes = 0U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Invalid pointer size", error.c_str());
EXPECT_TRUE(warning.empty());
prog.headerMutable->GPUPointerSizeInBytes = 1U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 2U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 3U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 4U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 5U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 6U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 7U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 8U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 9U;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
}
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerConstantBufferIndexThenValidationFails) {
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog;
std::string error, warning;
prog.constantPointerMutable->ConstantBufferIndex = 1;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerBufferTypeThenValidationFails) {
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog;
std::string error, warning;
prog.constantPointerMutable->BufferType = iOpenCL::NUM_PROGRAM_SCOPE_BUFFER_TYPE;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerOffsetThenValidationFails) {
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog;
std::string error, warning;
prog.constantPointerMutable->ConstantPointerOffset = prog.constSurfMutable->InlineDataSize;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithoutConstantSurfaceButWithConstantPointerThenValidationFails) {
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog;
std::string error, warning;
prog.programScopeTokens.allocateConstantMemorySurface.clear();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchConstantPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithValidGlobalPointerThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenInvalidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationFails) {
std::string error, warning;
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer progGlobalVar;
progGlobalVar.globalPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_CONSTANT_BUFFER;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(progGlobalVar, 0U, UknownTokenValidator(), error, warning));
EXPECT_FALSE(error.empty());
EXPECT_TRUE(warning.empty());
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer progConstVar;
progConstVar.constantPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(progConstVar, 0U, UknownTokenValidator(), error, warning));
EXPECT_FALSE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferIndexThenValidationFails) {
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog;
std::string error, warning;
prog.globalPointerMutable->BufferIndex = 1;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerGlobalBufferIndexThenValidationFails) {
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog;
std::string error, warning;
prog.globalPointerMutable->GlobalBufferIndex = 1;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerBufferTypeThenValidationFails) {
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog;
std::string error, warning;
prog.globalPointerMutable->BufferType = iOpenCL::NUM_PROGRAM_SCOPE_BUFFER_TYPE;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidGlobalPointerOffsetThenValidationFails) {
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog;
std::string error, warning;
prog.globalPointerMutable->GlobalPointerOffset = prog.globalSurfMutable->InlineDataSize;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithoutGlobalSurfaceButWithGlobalPointerThenValidationFails) {
PatchTokensTestData::ValidProgramWithGlobalSurfaceAndPointer prog;
std::string error, warning;
prog.programScopeTokens.allocateGlobalMemorySurface.clear();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("Unhandled SPatchGlobalPointerProgramBinaryInfo", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithUnknownPatchTokenWhenUknownTokenCantBeSkippedThenValidationFails) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
iOpenCL::SPatchItemHeader unknownToken = {};
unknownToken.Token = iOpenCL::NUM_PATCH_TOKENS + 1;
prog.unhandledTokens.push_back(&unknownToken);
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(false), error, warning));
auto expectedError = "Unhandled required program-scope Patch Token : " + std::to_string(unknownToken.Token);
EXPECT_STREQ(expectedError.c_str(), error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithUnknownPatchTokenWhenUknownTokenCanBeSkippedThenValidationSucceedsAndEmitsWarning) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
iOpenCL::SPatchItemHeader unknownToken = {};
unknownToken.Token = iOpenCL::NUM_PATCH_TOKENS + 1;
prog.unhandledTokens.push_back(&unknownToken);
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedWarning = "Unknown program-scope Patch Token : " + std::to_string(unknownToken.Token);
EXPECT_TRUE(error.empty());
EXPECT_STREQ(expectedWarning.c_str(), warning.c_str());
}
TEST(PatchtokensValidator, GivenProgramWithUnsupportedPatchTokenVersionThenValidationFails) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
prog.headerMutable->Version = std::numeric_limits<uint32_t>::max();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedError = "Unhandled Version of Patchtokens: expected: " + std::to_string(iOpenCL::CURRENT_ICBE_VERSION) + ", got: " + std::to_string(prog.header->Version);
EXPECT_STREQ(expectedError.c_str(), error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithUnsupportedPlatformThenValidationFails) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
prog.headerMutable->Device = IGFX_MAX_CORE;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedError = "Unsupported device binary, device GFXCORE_FAMILY : " + std::to_string(prog.header->Device);
EXPECT_STREQ(expectedError.c_str(), error.c_str());
EXPECT_EQ(0U, warning.size());
}
TEST(PatchtokensValidator, GivenValidProgramWithKernelThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelHasInvalidOrUnknownStatusThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
prog.kernels[0].decodeStatus = NEO::PatchTokenBinary::DecoderError::Undefined;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("KernelFromPatchtokens wasn't successfully decoded", error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
warning.clear();
prog.kernels[0].decodeStatus = NEO::PatchTokenBinary::DecoderError::InvalidBinary;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("KernelFromPatchtokens wasn't successfully decoded", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelHasInvalidChecksumThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
prog.kernelHeaderMutable->CheckSum += 1;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(), error, warning));
EXPECT_STREQ("KernelFromPatchtokens has invalid checksum", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithKernelUsingSlmThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithKernelUsingSlm prog;
std::string error, warning;
size_t slmSizeAvailable = 1 + prog.kernels[0].tokens.allocateLocalSurface->TotalInlineLocalMemorySize;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, slmSizeAvailable, UknownTokenValidator(), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelUsingSlmWhenKernelRequiresTooMuchSlmThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernelUsingSlm prog;
std::string error, warning;
size_t slmSizeAvailable = -1 + prog.kernels[0].tokens.allocateLocalSurface->TotalInlineLocalMemorySize;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::NotEnoughSlm, NEO::PatchTokenBinary::validate(prog, slmSizeAvailable, UknownTokenValidator(), error, warning));
EXPECT_STREQ("KernelFromPatchtokens requires too much SLM", error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithKernelContainingUnknownPatchTokenWhenUknownTokenCantBeSkippedThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
iOpenCL::SPatchItemHeader unknownToken = {};
unknownToken.Token = iOpenCL::NUM_PATCH_TOKENS + 1;
prog.kernels[0].unhandledTokens.push_back(&unknownToken);
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(false), error, warning));
auto expectedError = "Unhandled required kernel-scope Patch Token : " + std::to_string(unknownToken.Token);
EXPECT_STREQ(expectedError.c_str(), error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithKernelContainingUnknownPatchTokenWhenUknownTokenCanBeSkippedThenValidationSucceedsAndEmitsWarning) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
iOpenCL::SPatchItemHeader unknownToken = {};
unknownToken.Token = iOpenCL::NUM_PATCH_TOKENS + 1;
prog.kernels[0].unhandledTokens.push_back(&unknownToken);
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedWarning = "Unknown kernel-scope Patch Token : " + std::to_string(unknownToken.Token);
EXPECT_TRUE(error.empty());
EXPECT_STREQ(expectedWarning.c_str(), warning.c_str());
}
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelArgsHasProperQualifiersThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
std::string error, warning;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelsArgDoesntHaveKernelArgInfoThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
std::string error, warning;
prog.kernels[0].tokens.kernelArgs[0].argInfo = nullptr;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedError = "Missing kernelArgInfo";
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelsArgHasUnknownAddressSpaceThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
std::string error, warning;
prog.arg0InfoAddressQualifierMutable[2] = '\0';
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedError = "Unhandled address qualifier";
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelsArgHasUnknownAccessQualifierThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
std::string error, warning;
prog.arg0InfoAccessQualifierMutable[2] = '\0';
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedError = "Unhandled access qualifier";
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenKernelWhenExecutionEnvironmentIsMissingThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
prog.kernels[0].tokens.executionEnvironment = nullptr;
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedError = "Missing execution environment";
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenKernelWhenExecutionEnvironmentHasInvalidSimdSizeThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 0U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
auto expectedError = "Invalid LargestCompiledSIMDSize";
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 1U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 2U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 3U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 4U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 5U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 6U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 7U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 8U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 9U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 16U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 32U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::PatchTokenBinary::ValidatorError::Success, NEO::PatchTokenBinary::validate(prog, 0U, UknownTokenValidator(true), error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}

View File

@@ -6,12 +6,12 @@
*/
#include "core/compiler_interface/linker.h"
#include "core/device_binary_format/patchtokens_decoder.h"
#include "core/program/program_info.h"
#include "core/program/program_info_from_patchtokens.h"
#include "core/unit_tests/compiler_interface/linker_mock.h"
#include "runtime/compiler_interface/patchtokens_decoder.h"
#include "core/unit_tests/device_binary_format/patchtokens_tests.h"
#include "runtime/program/kernel_info.h"
#include "unit_tests/compiler_interface/patchtokens_tests.h"
#include "RelocationInfo.h"
#include "gmock/gmock.h"