compute-runtime/shared/source/device_binary_format/patchtokens_validator.cpp

151 lines
6.7 KiB
C++

/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/patchtokens_validator.h"
#include "shared/source/device_binary_format/patchtokens_decoder.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/kernel/kernel_arg_descriptor.h"
#include "igfxfmid.h"
#include <string>
namespace NEO {
namespace PatchTokenBinary {
bool allowUnhandledTokens = true;
DecodeError validate(const ProgramFromPatchtokens &decodedProgram,
std::string &outErrReason, std::string &outWarnings) {
if (decodedProgram.decodeStatus != DecodeError::success) {
outErrReason = "ProgramFromPatchtokens wasn't successfully decoded";
return DecodeError::invalidBinary;
}
if (decodedProgram.programScopeTokens.allocateConstantMemorySurface.size() > 1) {
outErrReason = "Unhandled number of global constants surfaces > 1";
return DecodeError::unhandledBinary;
}
if (decodedProgram.programScopeTokens.allocateGlobalMemorySurface.size() > 1) {
outErrReason = "Unhandled number of global variables surfaces > 1";
return DecodeError::unhandledBinary;
}
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 DecodeError::unhandledBinary;
}
}
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 DecodeError::unhandledBinary;
}
}
for (const auto &unhandledToken : decodedProgram.unhandledTokens) {
if (allowUnhandledTokens) {
outWarnings = "Unknown program-scope Patch Token : " + std::to_string(unhandledToken->Token);
} else {
outErrReason = "Unhandled required program-scope Patch Token : " + std::to_string(unhandledToken->Token);
return DecodeError::unhandledBinary;
}
}
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 DecodeError::unhandledBinary;
}
if ((decodedProgram.header->GPUPointerSizeInBytes != 4U) && (decodedProgram.header->GPUPointerSizeInBytes != 8U)) {
outErrReason = "Invalid pointer size";
return DecodeError::unhandledBinary;
}
for (const auto &decodedKernel : decodedProgram.kernels) {
if (decodedKernel.decodeStatus != DecodeError::success) {
outErrReason = "KernelFromPatchtokens wasn't successfully decoded";
return DecodeError::unhandledBinary;
}
UNRECOVERABLE_IF(nullptr == decodedKernel.header);
if (hasInvalidChecksum(decodedKernel)) {
outErrReason = "KernelFromPatchtokens has invalid checksum";
return DecodeError::unhandledBinary;
}
if (nullptr == decodedKernel.tokens.executionEnvironment) {
outErrReason = "Missing execution environment";
return DecodeError::unhandledBinary;
} else {
switch (decodedKernel.tokens.executionEnvironment->LargestCompiledSIMDSize) {
case 1:
break;
case 8:
break;
case 16:
break;
case 32:
break;
default:
outErrReason = "Invalid LargestCompiledSIMDSize";
return DecodeError::unhandledBinary;
}
}
for (auto &kernelArg : decodedKernel.tokens.kernelArgs) {
if (kernelArg.argInfo == nullptr) {
continue;
}
auto argInfoInlineData = getInlineData(kernelArg.argInfo);
auto accessQualifier = KernelArgMetadata::parseAccessQualifier(parseLimitedString(argInfoInlineData.accessQualifier.begin(), argInfoInlineData.accessQualifier.size()));
if (KernelArgMetadata::AccessUnknown == accessQualifier) {
outErrReason = "Unhandled access qualifier";
return DecodeError::unhandledBinary;
}
auto addressQualifier = KernelArgMetadata::parseAddressSpace(parseLimitedString(argInfoInlineData.addressQualifier.begin(), argInfoInlineData.addressQualifier.size()));
if (KernelArgMetadata::AddrUnknown == addressQualifier) {
outErrReason = "Unhandled address qualifier";
return DecodeError::unhandledBinary;
}
}
for (const auto &unhandledToken : decodedKernel.unhandledTokens) {
if (allowUnhandledTokens) {
outWarnings = "Unknown kernel-scope Patch Token : " + std::to_string(unhandledToken->Token);
} else {
outErrReason = "Unhandled required kernel-scope Patch Token : " + std::to_string(unhandledToken->Token);
return DecodeError::unhandledBinary;
}
}
}
return DecodeError::success;
}
} // namespace PatchTokenBinary
} // namespace NEO