compute-runtime/opencl/test/unit_test/program/kernel_data.cpp

1389 lines
60 KiB
C++

/*
* Copyright (C) 2018-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/patchtokens_decoder.h"
#include "shared/source/helpers/string.h"
#include "opencl/source/platform/platform.h"
#include "opencl/source/program/program.h"
#include "opencl/test/unit_test/fixtures/kernel_data_fixture.h"
#include "opencl/test/unit_test/helpers/gtest_helpers.h"
TEST_F(KernelDataTest, GivenKernelNameWhenBuildingThenProgramIsCorrect) {
kernelName = "myTestKernel";
kernelNameSize = (uint32_t)alignUp(strlen(kernelName.c_str()) + 1, sizeof(uint32_t));
buildAndDecode();
}
TEST_F(KernelDataTest, GivenHeapsWhenBuildingThenProgramIsCorrect) {
char gshData[8] = "a";
char dshData[8] = "bb";
char sshData[8] = "ccc";
char kernelHeapData[8] = "dddd";
pGsh = gshData;
pDsh = dshData;
pSsh = sshData;
pKernelHeap = kernelHeapData;
gshSize = 4;
dshSize = 4;
sshSize = 4;
kernelHeapSize = 4;
buildAndDecode();
}
TEST_F(KernelDataTest, GivenAllocateLocalSurfaceWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchAllocateLocalSurface allocateLocalSurface;
allocateLocalSurface.Token = PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE;
allocateLocalSurface.Size = sizeof(SPatchAllocateLocalSurface);
allocateLocalSurface.Offset = 0; // think this is SSH offset for local memory when we used to have surface state for local memory
allocateLocalSurface.TotalInlineLocalMemorySize = 4; // 4 bytes of local memory just for test
pPatchList = &allocateLocalSurface;
patchListSize = allocateLocalSurface.Size;
buildAndDecode();
EXPECT_EQ_VAL(allocateLocalSurface.TotalInlineLocalMemorySize, pKernelInfo->kernelDescriptor.kernelAttributes.slmInlineSize);
}
TEST_F(KernelDataTest, GivenAllocateStatelessConstantMemoryWithInitWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchAllocateStatelessConstantMemorySurfaceWithInitialization allocateStatelessConstantMemoryWithInit;
allocateStatelessConstantMemoryWithInit.Token = PATCH_TOKEN_ALLOCATE_STATELESS_CONSTANT_MEMORY_SURFACE_WITH_INITIALIZATION;
allocateStatelessConstantMemoryWithInit.Size = sizeof(SPatchAllocateStatelessConstantMemorySurfaceWithInitialization);
allocateStatelessConstantMemoryWithInit.ConstantBufferIndex = 0;
allocateStatelessConstantMemoryWithInit.SurfaceStateHeapOffset = 0xddu;
pPatchList = &allocateStatelessConstantMemoryWithInit;
patchListSize = allocateStatelessConstantMemoryWithInit.Size;
buildAndDecode();
EXPECT_EQ_VAL(0xddu, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.bindful);
}
TEST_F(KernelDataTest, GivenAllocateStatelessGlobalMemoryWithInitWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchAllocateStatelessGlobalMemorySurfaceWithInitialization allocateStatelessGlobalMemoryWithInit;
allocateStatelessGlobalMemoryWithInit.Token = PATCH_TOKEN_ALLOCATE_STATELESS_GLOBAL_MEMORY_SURFACE_WITH_INITIALIZATION;
allocateStatelessGlobalMemoryWithInit.Size = sizeof(SPatchAllocateStatelessGlobalMemorySurfaceWithInitialization);
allocateStatelessGlobalMemoryWithInit.GlobalBufferIndex = 0;
allocateStatelessGlobalMemoryWithInit.SurfaceStateHeapOffset = 0xddu;
pPatchList = &allocateStatelessGlobalMemoryWithInit;
patchListSize = allocateStatelessGlobalMemoryWithInit.Size;
buildAndDecode();
EXPECT_EQ_VAL(0xddu, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.bindful);
}
TEST_F(KernelDataTest, GivenPrintfStringWhenBuildingThenProgramIsCorrect) {
char stringValue[] = "%d\n";
size_t strSize = strlen(stringValue) + 1;
iOpenCL::SPatchString printfString;
printfString.Token = PATCH_TOKEN_STRING;
printfString.Size = static_cast<uint32_t>(sizeof(SPatchString) + strSize);
printfString.Index = 0;
printfString.StringSize = static_cast<uint32_t>(strSize);
iOpenCL::SPatchString emptyString;
emptyString.Token = PATCH_TOKEN_STRING;
emptyString.Size = static_cast<uint32_t>(sizeof(SPatchString));
emptyString.Index = 1;
emptyString.StringSize = 0;
cl_char *pPrintfString = new cl_char[printfString.Size + emptyString.Size];
memcpy_s(pPrintfString, sizeof(SPatchString), &printfString, sizeof(SPatchString));
memcpy_s((cl_char *)pPrintfString + sizeof(printfString), strSize, stringValue, strSize);
memcpy_s((cl_char *)pPrintfString + printfString.Size, emptyString.Size, &emptyString, emptyString.Size);
pPatchList = (void *)pPrintfString;
patchListSize = printfString.Size + emptyString.Size;
buildAndDecode();
EXPECT_EQ_VAL(0, strcmp(stringValue, pKernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap.find(0)->second.c_str()));
delete[] pPrintfString;
}
TEST_F(KernelDataTest, GivenMediaVfeStateWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchMediaVFEState MediaVFEState;
MediaVFEState.Token = PATCH_TOKEN_MEDIA_VFE_STATE;
MediaVFEState.Size = sizeof(SPatchMediaVFEState);
MediaVFEState.PerThreadScratchSpace = 1; // lets say 1KB of perThreadScratchSpace
MediaVFEState.ScratchSpaceOffset = 0;
pPatchList = &MediaVFEState;
patchListSize = MediaVFEState.Size;
buildAndDecode();
EXPECT_EQ_VAL(MediaVFEState.PerThreadScratchSpace, pKernelInfo->kernelDescriptor.kernelAttributes.perThreadScratchSize[0]);
}
TEST_F(KernelDataTest, WhenMediaVfeStateSlot1TokenIsParsedThenCorrectValuesAreSet) {
iOpenCL::SPatchMediaVFEState MediaVFEState;
MediaVFEState.Token = PATCH_TOKEN_MEDIA_VFE_STATE_SLOT1;
MediaVFEState.Size = sizeof(SPatchMediaVFEState);
MediaVFEState.PerThreadScratchSpace = 1;
MediaVFEState.ScratchSpaceOffset = 0;
pPatchList = &MediaVFEState;
patchListSize = MediaVFEState.Size;
buildAndDecode();
EXPECT_EQ_VAL(MediaVFEState.PerThreadScratchSpace, pKernelInfo->kernelDescriptor.kernelAttributes.perThreadScratchSize[1]);
}
TEST_F(KernelDataTest, GivenSyncBufferTokenWhenParsingProgramThenTokenIsFound) {
SPatchAllocateSyncBuffer token;
token.Token = PATCH_TOKEN_ALLOCATE_SYNC_BUFFER;
token.Size = static_cast<uint32_t>(sizeof(SPatchAllocateSyncBuffer));
token.SurfaceStateHeapOffset = 32;
token.DataParamOffset = 1024;
token.DataParamSize = 2;
pPatchList = &token;
patchListSize = token.Size;
buildAndDecode();
EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.usesSyncBuffer);
EXPECT_EQ(token.SurfaceStateHeapOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.syncBufferAddress.bindful);
EXPECT_EQ(token.DataParamOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.syncBufferAddress.stateless);
EXPECT_EQ(token.DataParamSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.syncBufferAddress.pointerSize);
}
TEST_F(KernelDataTest, GivenSamplerArgumentWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchSamplerKernelArgument samplerData;
samplerData.Token = PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT;
samplerData.ArgumentNumber = 3;
samplerData.Offset = 0x40;
samplerData.Type = iOpenCL::SAMPLER_OBJECT_TEXTURE;
samplerData.Size = sizeof(samplerData);
pPatchList = &samplerData;
patchListSize = samplerData.Size;
buildAndDecode();
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(3).is<ArgDescriptor::ArgTSampler>());
EXPECT_EQ_VAL(samplerData.Offset, pKernelInfo->getArgDescriptorAt(3).as<ArgDescSampler>().bindful);
}
TEST_F(KernelDataTest, GivenAcceleratorArgumentWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchSamplerKernelArgument samplerData;
samplerData.Token = PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT;
samplerData.ArgumentNumber = 3;
samplerData.Offset = 0x40;
samplerData.Type = iOpenCL::SAMPLER_OBJECT_VME;
samplerData.Size = sizeof(samplerData);
pPatchList = &samplerData;
patchListSize = samplerData.Size;
buildAndDecode();
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(3).is<ArgDescriptor::ArgTSampler>());
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(3).getExtendedTypeInfo().isAccelerator);
EXPECT_EQ_VAL(samplerData.Offset, pKernelInfo->getArgDescriptorAt(3).as<ArgDescSampler>().bindful);
}
TEST_F(KernelDataTest, GivenBindingTableStateWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchBindingTableState bindingTableState;
bindingTableState.Token = PATCH_TOKEN_BINDING_TABLE_STATE;
bindingTableState.Size = sizeof(SPatchBindingTableState);
bindingTableState.Count = 0xaa;
bindingTableState.Offset = 0xbb;
bindingTableState.SurfaceStateOffset = 0xcc;
pPatchList = &bindingTableState;
patchListSize = bindingTableState.Size;
buildAndDecode();
EXPECT_EQ_CONST(bindingTableState.Count, pKernelInfo->kernelDescriptor.payloadMappings.bindingTable.numEntries);
EXPECT_EQ_CONST(bindingTableState.Offset, pKernelInfo->kernelDescriptor.payloadMappings.bindingTable.tableOffset);
}
TEST_F(KernelDataTest, GivenDataParameterStreamWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchDataParameterStream dataParameterStream;
dataParameterStream.Token = PATCH_TOKEN_DATA_PARAMETER_STREAM;
dataParameterStream.Size = sizeof(SPatchDataParameterStream);
dataParameterStream.DataParameterStreamSize = 64;
pPatchList = &dataParameterStream;
patchListSize = dataParameterStream.Size;
buildAndDecode();
EXPECT_EQ_CONST(dataParameterStream.DataParameterStreamSize, pKernelInfo->kernelDescriptor.kernelAttributes.crossThreadDataSize);
}
TEST_F(KernelDataTest, GivenExecutionEnvironmentNoReqdWorkGroupSizeWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
executionEnvironment.RequiredWorkGroupSizeX = 0;
executionEnvironment.RequiredWorkGroupSizeY = 0;
executionEnvironment.RequiredWorkGroupSizeZ = 0;
executionEnvironment.LargestCompiledSIMDSize = 32;
executionEnvironment.CompiledSubGroupsNumber = 0xaa;
executionEnvironment.HasBarriers = false;
executionEnvironment.DisableMidThreadPreemption = true;
executionEnvironment.HasDeviceEnqueue = false;
executionEnvironment.MayAccessUndeclaredResource = false;
executionEnvironment.UsesFencesForReadWriteImages = false;
executionEnvironment.UsesStatelessSpillFill = false;
executionEnvironment.IsCoherent = true;
executionEnvironment.IsInitializer = false;
executionEnvironment.IsFinalizer = false;
executionEnvironment.SubgroupIndependentForwardProgressRequired = false;
executionEnvironment.CompiledForGreaterThan4GBBuffers = false;
executionEnvironment.IndirectStatelessCount = 0;
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
EXPECT_EQ_VAL(0, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[0]);
EXPECT_EQ_VAL(0, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[1]);
EXPECT_EQ_VAL(0, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[2]);
EXPECT_FALSE(pKernelInfo->hasIndirectStatelessAccess);
}
TEST_F(KernelDataTest, GivenExecutionEnvironmentWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
executionEnvironment.RequiredWorkGroupSizeX = 32;
executionEnvironment.RequiredWorkGroupSizeY = 16;
executionEnvironment.RequiredWorkGroupSizeZ = 8;
executionEnvironment.LargestCompiledSIMDSize = 32;
executionEnvironment.CompiledSubGroupsNumber = 0xaa;
executionEnvironment.HasBarriers = false;
executionEnvironment.DisableMidThreadPreemption = true;
executionEnvironment.HasDeviceEnqueue = false;
executionEnvironment.MayAccessUndeclaredResource = false;
executionEnvironment.UsesFencesForReadWriteImages = false;
executionEnvironment.UsesStatelessSpillFill = false;
executionEnvironment.IsCoherent = true;
executionEnvironment.IsInitializer = false;
executionEnvironment.IsFinalizer = false;
executionEnvironment.SubgroupIndependentForwardProgressRequired = false;
executionEnvironment.CompiledForGreaterThan4GBBuffers = false;
executionEnvironment.IndirectStatelessCount = 1;
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
EXPECT_EQ(32u, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[0]);
EXPECT_EQ(16u, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[1]);
EXPECT_EQ(8u, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[2]);
EXPECT_TRUE(pKernelInfo->hasIndirectStatelessAccess);
EXPECT_EQ(KernelDescriptor::BindfulAndStateless, pKernelInfo->kernelDescriptor.kernelAttributes.bufferAddressingMode);
}
TEST_F(KernelDataTest, GivenExecutionEnvironmentCompiledForGreaterThan4gbBuffersWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
executionEnvironment.RequiredWorkGroupSizeX = 32;
executionEnvironment.RequiredWorkGroupSizeY = 16;
executionEnvironment.RequiredWorkGroupSizeZ = 8;
executionEnvironment.LargestCompiledSIMDSize = 32;
executionEnvironment.CompiledSubGroupsNumber = 0xaa;
executionEnvironment.HasBarriers = false;
executionEnvironment.DisableMidThreadPreemption = true;
executionEnvironment.HasDeviceEnqueue = false;
executionEnvironment.MayAccessUndeclaredResource = false;
executionEnvironment.UsesFencesForReadWriteImages = false;
executionEnvironment.UsesStatelessSpillFill = false;
executionEnvironment.IsCoherent = true;
executionEnvironment.IsInitializer = false;
executionEnvironment.IsFinalizer = false;
executionEnvironment.SubgroupIndependentForwardProgressRequired = false;
executionEnvironment.CompiledForGreaterThan4GBBuffers = true;
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
EXPECT_EQ(KernelDescriptor::Stateless, pKernelInfo->kernelDescriptor.kernelAttributes.bufferAddressingMode);
}
TEST_F(KernelDataTest, GivenExecutionEnvironmentDoesntHaveDeviceEnqueueWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
executionEnvironment.HasDeviceEnqueue = false;
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
EXPECT_EQ_VAL(0u, program->getParentKernelInfoArray(rootDeviceIndex).size());
}
TEST_F(KernelDataTest, GivenExecutionEnvironmentHasDeviceEnqueueWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
executionEnvironment.HasDeviceEnqueue = true;
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
EXPECT_EQ_VAL(1u, program->getParentKernelInfoArray(rootDeviceIndex).size());
}
TEST_F(KernelDataTest, GivenExecutionEnvironmentDoesntRequireSubgroupIndependentForwardProgressWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
executionEnvironment.SubgroupIndependentForwardProgressRequired = false;
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
EXPECT_EQ_VAL(0u, program->getSubgroupKernelInfoArray(rootDeviceIndex).size());
}
TEST_F(KernelDataTest, GivenExecutionEnvironmentRequiresSubgroupIndependentForwardProgressWhenBuildingThenProgramIsCorrect) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
executionEnvironment.SubgroupIndependentForwardProgressRequired = true;
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
EXPECT_EQ_VAL(1u, program->getSubgroupKernelInfoArray(rootDeviceIndex).size());
}
TEST_F(KernelDataTest, WhenDecodingExecutionEnvironmentTokenThenWalkOrderIsForcedToXMajor) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
const uint8_t expectedWalkOrder[3] = {0, 1, 2};
const uint8_t expectedDimsIds[3] = {0, 1, 2};
EXPECT_EQ(0, memcmp(expectedWalkOrder, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupWalkOrder, sizeof(expectedWalkOrder)));
EXPECT_EQ(0, memcmp(expectedDimsIds, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupDimensionsOrder, sizeof(expectedDimsIds)));
EXPECT_FALSE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.requiresWorkgroupWalkOrder);
}
TEST_F(KernelDataTest, whenWorkgroupOrderIsSpecifiedViaPatchTokenThenProperWorkGroupOrderIsParsed) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
//dim0 : [0 : 1]; dim1 : [2 : 3]; dim2 : [4 : 5]
executionEnvironment.WorkgroupWalkOrderDims = 1 | (2 << 2);
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
uint8_t expectedWalkOrder[3] = {1, 2, 0};
uint8_t expectedDimsIds[3] = {2, 0, 1};
EXPECT_EQ(0, memcmp(expectedWalkOrder, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupWalkOrder, sizeof(expectedWalkOrder)));
EXPECT_EQ(0, memcmp(expectedDimsIds, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupDimensionsOrder, sizeof(expectedDimsIds)));
EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.requiresWorkgroupWalkOrder);
}
TEST_F(KernelDataTest, whenWorkgroupOrderIsSpecifiedViaPatchToken2ThenProperWorkGroupOrderIsParsed) {
iOpenCL::SPatchExecutionEnvironment executionEnvironment = {};
executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT;
executionEnvironment.Size = sizeof(SPatchExecutionEnvironment);
//dim0 : [0 : 1]; dim1 : [2 : 3]; dim2 : [4 : 5]
executionEnvironment.WorkgroupWalkOrderDims = 2 | (1 << 4);
pPatchList = &executionEnvironment;
patchListSize = executionEnvironment.Size;
buildAndDecode();
uint8_t expectedWalkOrder[3] = {2, 0, 1};
uint8_t expectedDimsIds[3] = {1, 2, 0};
EXPECT_EQ(0, memcmp(expectedWalkOrder, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupWalkOrder, sizeof(expectedWalkOrder)));
EXPECT_EQ(0, memcmp(expectedDimsIds, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupDimensionsOrder, sizeof(expectedDimsIds)));
EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.requiresWorkgroupWalkOrder);
}
// Test all the different data parameters with the same "made up" data
class DataParameterTest : public KernelDataTest, public testing::WithParamInterface<uint32_t> {};
TEST_P(DataParameterTest, GivenTokenTypeWhenBuildingThenProgramIsCorrect) {
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = GetParam();
dataParameterToken.ArgumentNumber = 1;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
dataParameterToken.Offset = 0;
dataParameterToken.SourceOffset = 8;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
if (DATA_PARAMETER_KERNEL_ARGUMENT == GetParam()) {
ASSERT_NE(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(dataParameterToken.ArgumentNumber, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].argNum);
EXPECT_EQ(dataParameterToken.Offset, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].byValueElement.offset);
EXPECT_EQ(dataParameterToken.SourceOffset, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].byValueElement.sourceOffset);
EXPECT_EQ(dataParameterToken.DataSize, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].byValueElement.size);
} else {
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
}
if (pKernelInfo->kernelDescriptor.payloadMappings.explicitArgs.size() > 0) {
EXPECT_EQ(dataParameterToken.ArgumentNumber + 1, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgs.size());
const auto &arg = pKernelInfo->getArgDescriptorAt(dataParameterToken.ArgumentNumber);
if (arg.is<ArgDescriptor::ArgTPointer>()) {
const auto &argAsPtr = arg.as<ArgDescPointer>();
EXPECT_EQ(GetParam() == DATA_PARAMETER_BUFFER_STATEFUL, argAsPtr.isPureStateful());
}
}
}
// note that we start at '2' because we test kernel arg tokens elsewhere
INSTANTIATE_TEST_CASE_P(DataParameterTests,
DataParameterTest,
testing::Range(2u, static_cast<uint32_t>(NUM_DATA_PARAMETER_TOKENS)));
class KernelDataParameterTest : public KernelDataTest {};
TEST_F(KernelDataParameterTest, GivenDataParameterBufferOffsetWhenBuildingThenProgramIsCorrect) {
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_BUFFER_OFFSET;
dataParameterToken.ArgumentNumber = 1;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
dataParameterToken.Offset = 128;
dataParameterToken.SourceOffset = 8;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgs.size());
EXPECT_EQ_VAL(pKernelInfo->getArgDescriptorAt(1).as<ArgDescPointer>().bufferOffset, dataParameterToken.Offset)
}
TEST_F(KernelDataParameterTest, givenDataParameterBufferStatefulWhenDecodingThenSetArgAsPureStateful) {
SPatchDataParameterBuffer dataParameterToken = {};
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_BUFFER_STATEFUL;
dataParameterToken.ArgumentNumber = 1;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(1).as<ArgDescPointer>().isPureStateful());
}
TEST_F(KernelDataParameterTest, givenUnknownDataParameterWhenDecodedThenParameterIsIgnored) {
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = NUM_DATA_PARAMETER_TOKENS + 1;
dataParameterToken.ArgumentNumber = 1;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
dataParameterToken.Offset = 0;
dataParameterToken.SourceOffset = 8;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ_VAL(0u, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
}
TEST_F(KernelDataTest, GivenDataParameterSumOfLocalMemoryObjectArgumentSizesWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetCrossThread = 4;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_SUM_OF_LOCAL_MEMORY_OBJECT_ARGUMENT_SIZES;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetCrossThread;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
const auto &argAsPtr = pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescPointer>();
EXPECT_EQ(alignment, argAsPtr.requiredSlmAlignment);
ASSERT_EQ(offsetCrossThread, argAsPtr.slmOffset);
}
TEST_F(KernelDataTest, GivenDataParameterImageWidthWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetImgWidth = 4;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_WIDTH;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetImgWidth;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetImgWidth, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.imgWidth);
}
TEST_F(KernelDataTest, GivenDataParameterImageHeightWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetImgHeight = 8;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_HEIGHT;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetImgHeight;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetImgHeight, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.imgHeight);
}
TEST_F(KernelDataTest, GivenDataParameterImageDepthWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetImgDepth = 12;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_DEPTH;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetImgDepth;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetImgDepth, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.imgDepth);
}
TEST_F(KernelDataTest, GivenDataParameterImageNumSamplersWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetNumSamples = 60;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_NUM_SAMPLES;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetNumSamples;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetNumSamples, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.numSamples);
}
TEST_F(KernelDataTest, GivenDataParameterImageNumMipLevelsWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetNumMipLevels = 60;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_NUM_MIP_LEVELS;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetNumMipLevels;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetNumMipLevels, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.numMipLevels);
}
TEST_F(KernelDataTest, givenFlatImageDataParamTokenWhenDecodingThenSetAllOffsets) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
auto testToken = [&](iOpenCL::DATA_PARAMETER_TOKEN token, uint32_t offsetToken) {
{
// reset program
if (pKernelData) {
alignedFree(pKernelData);
}
program = std::make_unique<MockProgram>(pContext, false, toClDeviceVector(*pContext->getDevice(0)));
}
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = token;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetToken;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
};
testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_BASEOFFSET, 10u);
EXPECT_EQ(10u, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.flatBaseOffset);
testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_WIDTH, 14u);
EXPECT_EQ(14u, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.flatWidth);
testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_HEIGHT, 16u);
EXPECT_EQ(16u, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.flatHeight);
testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_PITCH, 18u);
EXPECT_EQ(18u, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.flatPitch);
}
TEST_F(KernelDataTest, GivenDataParameterImageDataTypeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetChannelDataType = 52;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_CHANNEL_DATA_TYPE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetChannelDataType;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetChannelDataType, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.channelDataType);
}
TEST_F(KernelDataTest, GivenDataParameterImageChannelOrderWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetChannelOrder = 56;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_CHANNEL_ORDER;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetChannelOrder;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetChannelOrder, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.channelOrder);
}
TEST_F(KernelDataTest, GivenDataParameterImageArraySizeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetImageArraySize = 60;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_IMAGE_ARRAY_SIZE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetImageArraySize;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetImageArraySize, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescImage>().metadataPayload.arraySize);
}
TEST_F(KernelDataTest, GivenDataParameterWorkDimensionsWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetWorkDim = 12;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_WORK_DIMENSIONS;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetWorkDim;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetWorkDim, pKernelInfo->kernelDescriptor.payloadMappings.dispatchTraits.workDim);
}
TEST_F(KernelDataTest, GivenDataParameterSimdSizeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 17;
uint32_t alignment = 16;
uint32_t offsetSimdSize = 16;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_SIMD_SIZE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetSimdSize;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetSimdSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.simdSize);
}
TEST_F(KernelDataTest, GivenParameterPrivateMemoryStatelessSizeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 17;
uint32_t alignment = 16;
uint32_t offset = 16;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_PRIVATE_MEMORY_STATELESS_SIZE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offset;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size());
}
TEST_F(KernelDataTest, GivenDataParameterLocalMemoryStatelessWindowSizeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 17;
uint32_t alignment = 16;
uint32_t offset = 16;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_SIZE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offset;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size());
}
TEST_F(KernelDataTest, GivenDataParameterLocalMemoryStatelessWindowStartAddressWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 17;
uint32_t alignment = 16;
uint32_t offset = 16;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_START_ADDRESS;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offset;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size());
}
TEST_F(KernelDataTest, GivenDataParameterNumWorkGroupsWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 4;
uint32_t offsetNumWorkGroups[3] = {0, 4, 8};
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_NUM_WORK_GROUPS;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetNumWorkGroups[argumentNumber];
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = argumentNumber * alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetNumWorkGroups[argumentNumber], pKernelInfo->kernelDescriptor.payloadMappings.dispatchTraits.numWorkGroups[argumentNumber]);
}
TEST_F(KernelDataTest, GivenDataParameterMaxWorkgroupSizeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 4;
uint32_t offsetMaxWorkGroupSize = 4;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_MAX_WORKGROUP_SIZE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetMaxWorkGroupSize;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(offsetMaxWorkGroupSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.maxWorkGroupSize);
}
TEST_F(KernelDataTest, GivenDataParameterSamplerAddressModeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 0;
uint32_t dataOffset = 20;
uint32_t dataSize = sizeof(uint32_t);
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_SAMPLER_ADDRESS_MODE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = dataOffset;
dataParameterToken.DataSize = dataSize;
dataParameterToken.SourceOffset = 0;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(1U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(dataOffset, pKernelInfo->getArgDescriptorAt(0).as<ArgDescSampler>().metadataPayload.samplerAddressingMode);
}
TEST_F(KernelDataTest, GivenDataParameterSamplerCoordinateSnapWaIsRequiredThenKernelInfoIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t dataOffset = 20;
uint32_t dataSize = sizeof(uint32_t);
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_SAMPLER_COORDINATE_SNAP_WA_REQUIRED;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = dataOffset;
dataParameterToken.DataSize = dataSize;
dataParameterToken.SourceOffset = 0;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(dataOffset, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescSampler>().metadataPayload.samplerSnapWa);
}
TEST_F(KernelDataTest, GivenDataParameterSamplerNormalizedCoordsThenKernelInfoIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t dataOffset = 20;
uint32_t dataSize = sizeof(uint32_t);
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_SAMPLER_NORMALIZED_COORDS;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = dataOffset;
dataParameterToken.DataSize = dataSize;
dataParameterToken.SourceOffset = 0;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ(dataOffset, pKernelInfo->getArgDescriptorAt(argumentNumber).as<ArgDescSampler>().metadataPayload.samplerNormalizedCoords);
}
TEST_F(KernelDataTest, GivenDataParameterKernelArgumentWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 0;
uint32_t dataOffset = 20;
uint32_t dataSize = sizeof(uint32_t);
SPatchDataParameterBuffer dataParameterTokens[2];
dataParameterTokens[0].Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterTokens[0].Size = sizeof(SPatchDataParameterBuffer);
dataParameterTokens[0].Type = DATA_PARAMETER_KERNEL_ARGUMENT;
dataParameterTokens[0].ArgumentNumber = argumentNumber;
dataParameterTokens[0].Offset = dataOffset + dataSize * 0;
dataParameterTokens[0].DataSize = dataSize;
dataParameterTokens[0].SourceOffset = 0;
dataParameterTokens[0].LocationIndex = 0x0;
dataParameterTokens[0].LocationIndex2 = 0x0;
dataParameterTokens[1].Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterTokens[1].Size = sizeof(SPatchDataParameterBuffer);
dataParameterTokens[1].Type = DATA_PARAMETER_KERNEL_ARGUMENT;
dataParameterTokens[1].ArgumentNumber = argumentNumber;
dataParameterTokens[1].Offset = dataOffset + dataSize * 1;
dataParameterTokens[1].DataSize = dataSize;
dataParameterTokens[1].SourceOffset = dataSize * 1;
dataParameterTokens[1].LocationIndex = 0x0;
dataParameterTokens[1].LocationIndex2 = 0x0;
pPatchList = &dataParameterTokens[0];
patchListSize = dataParameterTokens[0].Size * (sizeof(dataParameterTokens) / sizeof(SPatchDataParameterBuffer));
buildAndDecode();
ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(1u, pKernelInfo->getExplicitArgs().size());
auto &elements = pKernelInfo->getArgDescriptorAt(0).as<ArgDescValue>().elements;
ASSERT_EQ(2u, elements.size());
EXPECT_EQ(dataSize, elements[0].size);
EXPECT_EQ(dataOffset + dataSize * 0, elements[0].offset);
EXPECT_EQ(dataSize, elements[1].size);
EXPECT_EQ(dataOffset + dataSize * 1, elements[1].offset);
}
TEST_F(KernelDataTest, GivenPatchTokenAllocateLocalSurfaceWhenBuildingThenProgramIsCorrect) {
SPatchAllocateLocalSurface slmToken;
slmToken.TotalInlineLocalMemorySize = 1024;
slmToken.Size = sizeof(SPatchAllocateLocalSurface);
slmToken.Token = PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE;
pPatchList = &slmToken;
patchListSize = slmToken.Size;
buildAndDecode();
EXPECT_EQ(1024u, pKernelInfo->kernelDescriptor.kernelAttributes.slmInlineSize);
}
TEST_F(KernelDataTest, GivenPatchTokenAllocateStatelessPrintfSurfaceWhenBuildingThenProgramIsCorrect) {
SPatchAllocateStatelessPrintfSurface printfSurface;
printfSurface.Token = PATCH_TOKEN_ALLOCATE_STATELESS_PRINTF_SURFACE;
printfSurface.Size = static_cast<uint32_t>(sizeof(SPatchAllocateStatelessPrintfSurface));
printfSurface.PrintfSurfaceIndex = 33;
printfSurface.SurfaceStateHeapOffset = 0x1FF0;
printfSurface.DataParamOffset = 0x3FF0;
printfSurface.DataParamSize = 0xFF;
pPatchList = &printfSurface;
patchListSize = printfSurface.Size;
buildAndDecode();
EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.usesPrintf);
EXPECT_EQ(printfSurface.SurfaceStateHeapOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress.bindful);
EXPECT_EQ(printfSurface.DataParamOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress.stateless);
EXPECT_EQ(printfSurface.DataParamSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress.pointerSize);
}
TEST_F(KernelDataTest, GivenPatchTokenSamplerStateArrayWhenBuildingThenProgramIsCorrect) {
SPatchSamplerStateArray token;
token.Token = PATCH_TOKEN_SAMPLER_STATE_ARRAY;
token.Size = static_cast<uint32_t>(sizeof(SPatchSamplerStateArray));
token.Offset = 33;
token.Count = 0xF0;
token.BorderColorOffset = 0x3FF0;
pPatchList = &token;
patchListSize = token.Size;
buildAndDecode();
EXPECT_EQ_VAL(token.Offset, pKernelInfo->kernelDescriptor.payloadMappings.samplerTable.tableOffset);
EXPECT_EQ_VAL(token.Count, pKernelInfo->kernelDescriptor.payloadMappings.samplerTable.numSamplers);
EXPECT_EQ_VAL(token.BorderColorOffset, pKernelInfo->kernelDescriptor.payloadMappings.samplerTable.borderColor);
}
TEST_F(KernelDataTest, GivenPatchTokenAllocateStatelessPrivateMemoryWhenBuildingThenProgramIsCorrect) {
SPatchAllocateStatelessPrivateSurface token;
token.Token = PATCH_TOKEN_ALLOCATE_STATELESS_PRIVATE_MEMORY;
token.Size = static_cast<uint32_t>(sizeof(SPatchAllocateStatelessPrivateSurface));
token.SurfaceStateHeapOffset = 64;
token.DataParamOffset = 40;
token.DataParamSize = 8;
token.PerThreadPrivateMemorySize = 112;
pPatchList = &token;
patchListSize = token.Size;
buildAndDecode();
EXPECT_EQ_VAL(token.SurfaceStateHeapOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.privateMemoryAddress.bindful);
EXPECT_EQ_VAL(token.DataParamOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.privateMemoryAddress.stateless);
EXPECT_EQ_VAL(token.DataParamSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.privateMemoryAddress.pointerSize);
EXPECT_EQ_VAL(PatchTokenBinary::getPerHwThreadPrivateSurfaceSize(token, pKernelInfo->kernelDescriptor.kernelAttributes.simdSize), pKernelInfo->kernelDescriptor.kernelAttributes.perHwThreadPrivateMemorySize);
}
TEST_F(KernelDataTest, GivenDataParameterVmeMbBlockTypeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 16;
uint32_t offsetVmeMbBlockType = 0xaa;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_VME_MB_BLOCK_TYPE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetVmeMbBlockType;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor);
ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size());
auto vmeArgDesc = reinterpret_cast<NEO::ArgDescVme *>(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get());
EXPECT_EQ(offsetVmeMbBlockType, vmeArgDesc->mbBlockType);
}
TEST_F(KernelDataTest, GivenDataParameterDataVmeSubpixelModeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 17;
uint32_t offsetVmeSubpixelMode = 0xab;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_VME_SUBPIXEL_MODE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetVmeSubpixelMode;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor);
ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size());
auto vmeArgDesc = reinterpret_cast<NEO::ArgDescVme *>(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get());
EXPECT_EQ(offsetVmeSubpixelMode, vmeArgDesc->subpixelMode);
}
TEST_F(KernelDataTest, GivenDataParameterVmeSadAdjustModeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 18;
uint32_t offsetVmeSadAdjustMode = 0xac;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_VME_SAD_ADJUST_MODE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetVmeSadAdjustMode;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor);
ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size());
auto vmeArgDesc = reinterpret_cast<NEO::ArgDescVme *>(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get());
EXPECT_EQ(offsetVmeSadAdjustMode, vmeArgDesc->sadAdjustMode);
}
TEST_F(KernelDataTest, GivenDataParameterVmeSearchPathTypeWhenBuildingThenProgramIsCorrect) {
uint32_t argumentNumber = 1;
uint32_t alignment = 19;
uint32_t offsetVmeSearchPathType = 0xad;
SPatchDataParameterBuffer dataParameterToken;
dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER;
dataParameterToken.Size = sizeof(SPatchDataParameterBuffer);
dataParameterToken.Type = DATA_PARAMETER_VME_SEARCH_PATH_TYPE;
dataParameterToken.ArgumentNumber = argumentNumber;
dataParameterToken.Offset = offsetVmeSearchPathType;
dataParameterToken.DataSize = sizeof(uint32_t);
dataParameterToken.SourceOffset = alignment;
dataParameterToken.LocationIndex = 0x0;
dataParameterToken.LocationIndex2 = 0x0;
pPatchList = &dataParameterToken;
patchListSize = dataParameterToken.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size());
EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor);
ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size());
auto vmeArgDesc = reinterpret_cast<NEO::ArgDescVme *>(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get());
EXPECT_EQ(offsetVmeSearchPathType, vmeArgDesc->searchPathType);
}
TEST_F(KernelDataTest, GivenPatchTokenStateSipWhenBuildingThenProgramIsCorrect) {
SPatchStateSIP token;
token.Token = PATCH_TOKEN_STATE_SIP;
token.Size = static_cast<uint32_t>(sizeof(SPatchStateSIP));
token.SystemKernelOffset = 33;
pPatchList = &token;
patchListSize = token.Size;
buildAndDecode();
EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size());
EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size());
EXPECT_EQ_VAL(token.SystemKernelOffset, pKernelInfo->systemKernelOffset);
}
TEST_F(KernelDataTest, givenSymbolTablePatchTokenThenLinkerInputIsCreated) {
SPatchFunctionTableInfo token;
token.Token = PATCH_TOKEN_PROGRAM_SYMBOL_TABLE;
token.Size = static_cast<uint32_t>(sizeof(SPatchFunctionTableInfo));
token.NumEntries = 0;
pPatchList = &token;
patchListSize = token.Size;
buildAndDecode();
EXPECT_NE(nullptr, program->getLinkerInput(pContext->getDevice(0)->getRootDeviceIndex()));
}
TEST_F(KernelDataTest, givenRelocationTablePatchTokenThenLinkerInputIsCreated) {
SPatchFunctionTableInfo token;
token.Token = PATCH_TOKEN_PROGRAM_RELOCATION_TABLE;
token.Size = static_cast<uint32_t>(sizeof(SPatchFunctionTableInfo));
token.NumEntries = 0;
pPatchList = &token;
patchListSize = token.Size;
buildAndDecode();
EXPECT_NE(nullptr, program->getLinkerInput(pContext->getDevice(0)->getRootDeviceIndex()));
}