mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 21:18:24 +08:00
Decoder decodes the binary to kernel heaps and patch token data, which is in a human readible form. Encoder encodes it back to binary form. Change-Id: Id07b1294ba24360e90c824171741cf14bd43cfad
315 lines
14 KiB
C++
315 lines
14 KiB
C++
/*
|
|
* Copyright (C) 2018 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "mock/mock_decoder.h"
|
|
#include "runtime/helpers/array_count.h"
|
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include <fstream>
|
|
|
|
namespace OCLRT {
|
|
TEST(DecoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
|
|
const char *argv[] = {
|
|
"cloc",
|
|
"decoder",
|
|
"-file",
|
|
"test_files/binary.bin",
|
|
"-patch",
|
|
"test_files/patch",
|
|
"-dump",
|
|
"test_files/created"};
|
|
|
|
MockDecoder decoder;
|
|
EXPECT_EQ(0, decoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
|
}
|
|
|
|
TEST(DecoderTests, WhenMissingParametersThenValidateInputReturnsErrorCode) {
|
|
const char *argv[] = {
|
|
"cloc",
|
|
"decoder",
|
|
"-file",
|
|
"test_files/binary.bin",
|
|
"-patch",
|
|
"test_files"};
|
|
|
|
MockDecoder decoder;
|
|
EXPECT_NE(0, decoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
|
}
|
|
|
|
TEST(DecoderTests, GivenWrongParametersWhenParsingParametersThenValidateInputReturnsErrorCode) {
|
|
const char *argv[] = {
|
|
"cloc",
|
|
"decoder",
|
|
"-file",
|
|
"test_files/no_extension",
|
|
"-patch",
|
|
"test_files",
|
|
"-dump",
|
|
"test_files/created"};
|
|
|
|
MockDecoder decoder;
|
|
EXPECT_NE(0, decoder.validateInput(static_cast<uint32_t>(arrayCount<const char *>(argv)), argv));
|
|
}
|
|
|
|
TEST(DecoderTests, GivenValidSizeStringWhenGettingSizeThenProperOutcomeIsExpectedAndExceptionIsNotThrown) {
|
|
MockDecoder decoder;
|
|
EXPECT_EQ(static_cast<uint8_t>(1), decoder.getSize("uint8_t"));
|
|
EXPECT_EQ(static_cast<uint8_t>(2), decoder.getSize("uint16_t"));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), decoder.getSize("uint32_t"));
|
|
EXPECT_EQ(static_cast<uint8_t>(8), decoder.getSize("uint64_t"));
|
|
}
|
|
|
|
TEST(DecoderTests, GivenProperStructWhenReadingStructFieldsThenFieldsVectorGetsPopulatedCorrectly) {
|
|
std::vector<std::string> lines;
|
|
lines.push_back("/* */");
|
|
lines.push_back("struct SPatchSamplerStateArray :");
|
|
lines.push_back(" SPatchItemHeader");
|
|
lines.push_back("{");
|
|
lines.push_back(" uint64_t SomeField;");
|
|
lines.push_back(" uint32_t Offset;");
|
|
lines.push_back("");
|
|
lines.push_back(" uint16_t Count;");
|
|
lines.push_back(" uint8_t BorderColorOffset;");
|
|
lines.push_back("};");
|
|
|
|
std::vector<PTField> fields;
|
|
MockDecoder decoder;
|
|
size_t pos = 4;
|
|
uint32_t full_size = decoder.readStructFields(lines, pos, fields);
|
|
EXPECT_EQ(static_cast<uint32_t>(15), full_size);
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(8), fields[0].size);
|
|
EXPECT_EQ("SomeField", fields[0].name);
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(4), fields[1].size);
|
|
EXPECT_EQ("Offset", fields[1].name);
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(2), fields[2].size);
|
|
EXPECT_EQ("Count", fields[2].name);
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(1), fields[3].size);
|
|
EXPECT_EQ("BorderColorOffset", fields[3].name);
|
|
}
|
|
|
|
TEST(DecoderTests, GivenProperPatchListFileWhenParsingTokensThenFileIsParsedCorrectly) {
|
|
MockDecoder decoder;
|
|
decoder.pathToPatch = "test_files/";
|
|
decoder.parseTokens();
|
|
|
|
EXPECT_EQ(static_cast<uint32_t>(28), (decoder.programHeader.size));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.programHeader.fields[0].size));
|
|
EXPECT_EQ("Magic", (decoder.programHeader.fields[0].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.programHeader.fields[1].size));
|
|
EXPECT_EQ("Version", (decoder.programHeader.fields[1].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.programHeader.fields[2].size));
|
|
EXPECT_EQ("Device", (decoder.programHeader.fields[2].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.programHeader.fields[3].size));
|
|
EXPECT_EQ("GPUPointerSizeInBytes", (decoder.programHeader.fields[3].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.programHeader.fields[4].size));
|
|
EXPECT_EQ("NumberOfKernels", (decoder.programHeader.fields[4].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.programHeader.fields[5].size));
|
|
EXPECT_EQ("SteppingId", (decoder.programHeader.fields[5].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.programHeader.fields[6].size));
|
|
EXPECT_EQ("PatchListSize", (decoder.programHeader.fields[6].name));
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(40), (decoder.kernelHeader.size));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[0].size));
|
|
EXPECT_EQ("CheckSum", (decoder.kernelHeader.fields[0].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(8), (decoder.kernelHeader.fields[1].size));
|
|
EXPECT_EQ("ShaderHashCode", (decoder.kernelHeader.fields[1].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[2].size));
|
|
EXPECT_EQ("KernelNameSize", (decoder.kernelHeader.fields[2].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[3].size));
|
|
EXPECT_EQ("PatchListSize", (decoder.kernelHeader.fields[3].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[4].size));
|
|
EXPECT_EQ("KernelHeapSize", (decoder.kernelHeader.fields[4].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[5].size));
|
|
EXPECT_EQ("GeneralStateHeapSize", (decoder.kernelHeader.fields[5].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[6].size));
|
|
EXPECT_EQ("DynamicStateHeapSize", (decoder.kernelHeader.fields[6].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[7].size));
|
|
EXPECT_EQ("SurfaceStateHeapSize", (decoder.kernelHeader.fields[7].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.kernelHeader.fields[8].size));
|
|
EXPECT_EQ("KernelUnpaddedSize", (decoder.kernelHeader.fields[8].name));
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[2]->size));
|
|
EXPECT_EQ("PATCH_TOKEN_STATE_SIP", (decoder.patchTokens[2]->name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[2]->fields[0].size));
|
|
EXPECT_EQ("SystemKernelOffset", (decoder.patchTokens[2]->fields[0].name));
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(12), decoder.patchTokens[5]->size);
|
|
EXPECT_EQ("PATCH_TOKEN_SAMPLER_STATE_ARRAY", decoder.patchTokens[5]->name);
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[5]->fields[0].size));
|
|
EXPECT_EQ("Offset", (decoder.patchTokens[5]->fields[0].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[5]->fields[1].size));
|
|
EXPECT_EQ("Count", (decoder.patchTokens[5]->fields[1].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[5]->fields[2].size));
|
|
EXPECT_EQ("BorderColorOffset", (decoder.patchTokens[5]->fields[2].name));
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(8), decoder.patchTokens[42]->size);
|
|
EXPECT_EQ("PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO", decoder.patchTokens[42]->name);
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[42]->fields[0].size));
|
|
EXPECT_EQ("ConstantBufferIndex", (decoder.patchTokens[42]->fields[0].name));
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[42]->fields[1].size));
|
|
EXPECT_EQ("InlineDataSize", (decoder.patchTokens[42]->fields[1].name));
|
|
|
|
EXPECT_EQ(static_cast<uint8_t>(4), decoder.patchTokens[19]->size);
|
|
EXPECT_EQ("PATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD", decoder.patchTokens[19]->name);
|
|
EXPECT_EQ(static_cast<uint8_t>(4), (decoder.patchTokens[19]->fields[0].size));
|
|
EXPECT_EQ("InterfaceDescriptorDataOffset", (decoder.patchTokens[19]->fields[0].name));
|
|
}
|
|
|
|
TEST(DecoderTests, GivenValidBinaryWhenReadingPatchTokensFromBinaryThenBinaryIsReadCorrectly) {
|
|
std::string binaryString;
|
|
std::stringstream binarySS;
|
|
uint8_t byte;
|
|
uint32_t byte4;
|
|
|
|
byte4 = 4;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 16;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 1234;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 5678;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 2;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 12;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte = 255;
|
|
for (auto i = 0; i < 4; ++i) {
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
}
|
|
binaryString = binarySS.str();
|
|
|
|
std::vector<char> binary(binaryString.begin(), binaryString.end());
|
|
MockDecoder decoder;
|
|
std::stringstream out;
|
|
auto PTptr = std::make_unique<PatchToken>();
|
|
PTptr->size = 20;
|
|
PTptr->name = "Example patchtoken";
|
|
PTptr->fields.push_back(PTField{4, "First"});
|
|
PTptr->fields.push_back(PTField{4, "Second"});
|
|
decoder.patchTokens.insert(std::pair<uint8_t, std::unique_ptr<PatchToken>>(4, std::move(PTptr)));
|
|
void *ptr = reinterpret_cast<void *>(binary.data());
|
|
decoder.readPatchTokens(ptr, 28, out);
|
|
std::string s = "Example patchtoken:\n\t4 Token 4\n\t4 Size 16\n\t4 First 1234\n\t4 Second 5678\nUnidentified PatchToken:\n\t4 Token 2\n\t4 Size 12\n\tHex ff ff ff ff\n";
|
|
EXPECT_EQ(s, out.str());
|
|
}
|
|
|
|
TEST(DecoderTests, GivenValidBinaryWhenProcessingBinaryThenProgramAndKernelAndPatchTokensAreReadCorrectly) {
|
|
std::string binaryString;
|
|
|
|
std::stringstream binarySS;
|
|
uint8_t byte;
|
|
uint32_t byte4;
|
|
uint64_t byte8;
|
|
|
|
//ProgramBinaryHeader
|
|
byte4 = 1229870147;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 1042;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 12;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 4;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 1;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 2;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 30;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
|
|
//PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO
|
|
byte4 = 42;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 16;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 14;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte = 0x48;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x65;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x6c;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x6c;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x6f;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x20;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x77;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x6f;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x72;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x6c;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x64;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x21;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0xa;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
byte = 0x0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
|
|
|
|
//KernelBinaryHeader
|
|
byte4 = 242806820;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte8 = 2860607076011376830;
|
|
binarySS.write(reinterpret_cast<char *>(&byte8), sizeof(uint64_t));
|
|
byte4 = 12;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 12;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
|
|
std::string kernelName("HelloWorld");
|
|
binarySS.write(kernelName.c_str(), 12);
|
|
|
|
//PATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD
|
|
byte4 = 19;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 12;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
byte4 = 0;
|
|
binarySS.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
|
|
binaryString = binarySS.str();
|
|
|
|
std::vector<char> binary(binaryString.begin(), binaryString.end());
|
|
std::stringstream ptmFile;
|
|
MockDecoder decoder;
|
|
decoder.pathToPatch = "test_files/";
|
|
decoder.pathToDump = "non_existing_folder/";
|
|
decoder.parseTokens();
|
|
|
|
auto ptr = reinterpret_cast<void *>(binary.data());
|
|
int retVal = decoder.processBinary(ptr, ptmFile);
|
|
EXPECT_EQ(0, retVal);
|
|
|
|
std::string expectedOutput = "ProgramBinaryHeader:\n\t4 Magic 1229870147\n\t4 Version 1042\n\t4 Device 12\n\t4 GPUPointerSizeInBytes 4\n\t4 NumberOfKernels 1\n\t4 SteppingId 2\n\t4 PatchListSize 30\nPATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO:\n\t4 Token 42\n\t4 Size 16\n\t4 ConstantBufferIndex 0\n\t4 InlineDataSize 14\n\tHex 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 a 0\nKernel #0\nKernelBinaryHeader:\n\t4 CheckSum 242806820\n\t8 ShaderHashCode 2860607076011376830\n\t4 KernelNameSize 12\n\t4 PatchListSize 12\n\t4 KernelHeapSize 0\n\t4 GeneralStateHeapSize 0\n\t4 DynamicStateHeapSize 0\n\t4 SurfaceStateHeapSize 0\n\t4 KernelUnpaddedSize 0\n\tKernelName HelloWorld\nPATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD:\n\t4 Token 19\n\t4 Size 12\n\t4 InterfaceDescriptorDataOffset 0\n";
|
|
EXPECT_EQ(expectedOutput, ptmFile.str());
|
|
}
|
|
} // namespace OCLRT
|