Reorganization directory structure [4/n]

Change-Id: Ib868ed62d12ea8f9f123644219ba299e86a658ac
This commit is contained in:
kamdiedrich
2020-02-24 00:22:25 +01:00
parent 7df9945ebe
commit 9e97b42ee6
175 changed files with 28 additions and 22 deletions

View File

@@ -1,7 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
add_subdirectories()

View File

@@ -1,13 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_COMMAND_CONTAINER_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/command_container_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/command_encoder_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_COMMAND_CONTAINER_TESTS ${NEO_CORE_COMMAND_CONTAINER_TESTS})
add_subdirectories()

View File

@@ -1,393 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_container/cmdcontainer.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/mocks/mock_graphics_allocation.h"
#include "test.h"
using namespace NEO;
class CommandContainerTest : public DeviceFixture,
public ::testing::Test {
public:
void SetUp() override {
::testing::Test::SetUp();
DeviceFixture::SetUp();
}
void TearDown() override {
DeviceFixture::TearDown();
::testing::Test::TearDown();
}
};
struct CommandContainerHeapStateTests : public ::testing::Test {
class MyMockCommandContainer : public CommandContainer {
public:
using CommandContainer::dirtyHeaps;
};
MyMockCommandContainer myCommandContainer;
};
TEST_F(CommandContainerHeapStateTests, givenDirtyHeapsWhenSettingStateForAllThenValuesAreCorrect) {
EXPECT_EQ(std::numeric_limits<uint32_t>::max(), myCommandContainer.dirtyHeaps);
EXPECT_TRUE(myCommandContainer.isAnyHeapDirty());
myCommandContainer.setDirtyStateForAllHeaps(false);
EXPECT_EQ(0u, myCommandContainer.dirtyHeaps);
EXPECT_FALSE(myCommandContainer.isAnyHeapDirty());
for (uint32_t i = 0; i < HeapType::NUM_TYPES; i++) {
HeapType heapType = static_cast<HeapType>(i);
EXPECT_FALSE(myCommandContainer.isHeapDirty(heapType));
}
myCommandContainer.setDirtyStateForAllHeaps(true);
EXPECT_EQ(std::numeric_limits<uint32_t>::max(), myCommandContainer.dirtyHeaps);
for (uint32_t i = 0; i < HeapType::NUM_TYPES; i++) {
HeapType heapType = static_cast<HeapType>(i);
EXPECT_TRUE(myCommandContainer.isHeapDirty(heapType));
}
}
TEST_F(CommandContainerHeapStateTests, givenDirtyHeapsWhenSettingStateForSingleHeapThenValuesAreCorrect) {
myCommandContainer.dirtyHeaps = 0;
EXPECT_FALSE(myCommandContainer.isAnyHeapDirty());
uint32_t controlVariable = 0;
for (uint32_t i = 0; i < HeapType::NUM_TYPES; i++) {
HeapType heapType = static_cast<HeapType>(i);
EXPECT_FALSE(myCommandContainer.isHeapDirty(heapType));
myCommandContainer.setHeapDirty(heapType);
EXPECT_TRUE(myCommandContainer.isHeapDirty(heapType));
EXPECT_TRUE(myCommandContainer.isAnyHeapDirty());
controlVariable |= (1 << i);
EXPECT_EQ(controlVariable, myCommandContainer.dirtyHeaps);
}
for (uint32_t i = 0; i < HeapType::NUM_TYPES; i++) {
HeapType heapType = static_cast<HeapType>(i);
EXPECT_TRUE(myCommandContainer.isHeapDirty(heapType));
}
}
TEST_F(CommandContainerTest, givenCmdContainerWhenAllocatingHeapsThenSetCorrectAllocationTypes) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
for (uint32_t i = 0; i < HeapType::NUM_TYPES; i++) {
HeapType heapType = static_cast<HeapType>(i);
auto heap = cmdContainer.getIndirectHeap(heapType);
if (HeapType::INDIRECT_OBJECT == heapType) {
EXPECT_EQ(GraphicsAllocation::AllocationType::INTERNAL_HEAP, heap->getGraphicsAllocation()->getAllocationType());
EXPECT_NE(0u, heap->getHeapGpuStartOffset());
} else {
EXPECT_EQ(GraphicsAllocation::AllocationType::LINEAR_STREAM, heap->getGraphicsAllocation()->getAllocationType());
EXPECT_EQ(0u, heap->getHeapGpuStartOffset());
}
}
}
TEST_F(CommandContainerTest, givenCommandContainerWhenInitializeThenEverythingIsInitialized) {
CommandContainer cmdContainer;
auto status = cmdContainer.initialize(pDevice);
EXPECT_TRUE(status);
EXPECT_EQ(pDevice, cmdContainer.getDevice());
EXPECT_NE(cmdContainer.getHeapHelper(), nullptr);
EXPECT_EQ(cmdContainer.getCmdBufferAllocations().size(), 1u);
EXPECT_NE(cmdContainer.getCommandStream(), nullptr);
for (uint32_t i = 0; i < HeapType::NUM_TYPES; i++) {
auto indirectHeap = cmdContainer.getIndirectHeap(static_cast<HeapType>(i));
auto heapAllocation = cmdContainer.getIndirectHeapAllocation(static_cast<HeapType>(i));
EXPECT_EQ(indirectHeap->getGraphicsAllocation(), heapAllocation);
}
EXPECT_EQ(cmdContainer.getInstructionHeapBaseAddress(), pDevice->getMemoryManager()->getInternalHeapBaseAddress(0));
}
TEST_F(CommandContainerTest, givenCommandContainerWhenInitializeWithoutDeviceThenReturnedFalse) {
CommandContainer cmdContainer;
auto status = cmdContainer.initialize(nullptr);
EXPECT_FALSE(status);
}
TEST_F(CommandContainerTest, givenCommandContainerWhenSettingIndirectHeapAllocationThenAllocationIsSet) {
CommandContainer cmdContainer;
MockGraphicsAllocation mockAllocation;
auto heapType = HeapType::DYNAMIC_STATE;
cmdContainer.setIndirectHeapAllocation(heapType, &mockAllocation);
EXPECT_EQ(cmdContainer.getIndirectHeapAllocation(heapType), &mockAllocation);
}
TEST_F(CommandContainerTest, givenHeapAllocationsWhenDestroyCommandContainerThenHeapAllocationsAreReused) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
cmdContainer->initialize(pDevice);
auto heapAllocationsAddress = cmdContainer->getIndirectHeapAllocation(HeapType::DYNAMIC_STATE)->getUnderlyingBuffer();
cmdContainer.reset(new CommandContainer);
cmdContainer->initialize(pDevice);
bool status = false;
for (uint32_t i = 0; i < HeapType::NUM_TYPES && !status; i++) {
status = cmdContainer->getIndirectHeapAllocation(static_cast<HeapType>(i))->getUnderlyingBuffer() == heapAllocationsAddress;
}
EXPECT_TRUE(status);
}
TEST_F(CommandContainerTest, givenCommandContainerWhenResetTheanStreamsAreNotUsed) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
LinearStream stream;
uint32_t usedSize = 1;
cmdContainer.getCommandStream()->getSpace(usedSize);
EXPECT_EQ(usedSize, cmdContainer.getCommandStream()->getUsed());
cmdContainer.reset();
EXPECT_NE(usedSize, cmdContainer.getCommandStream()->getUsed());
EXPECT_EQ(0u, cmdContainer.getCommandStream()->getUsed());
}
TEST_F(CommandContainerTest, givenCommandContainerWhenWantToAddNullPtrToResidencyContainerThenNothingIsAdded) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
auto size = cmdContainer.getResidencyContainer().size();
cmdContainer.addToResidencyContainer(nullptr);
EXPECT_EQ(cmdContainer.getResidencyContainer().size(), size);
}
TEST_F(CommandContainerTest, givenCommandContainerWhenWantToAddAleradyAddedAllocationThenNothingIsAdded) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
MockGraphicsAllocation mockAllocation;
auto sizeBefore = cmdContainer.getResidencyContainer().size();
cmdContainer.addToResidencyContainer(&mockAllocation);
auto sizeAfterFirstAdd = cmdContainer.getResidencyContainer().size();
EXPECT_NE(sizeBefore, sizeAfterFirstAdd);
cmdContainer.addToResidencyContainer(&mockAllocation);
auto sizeAfterSecondAdd = cmdContainer.getResidencyContainer().size();
EXPECT_EQ(sizeAfterFirstAdd, sizeAfterSecondAdd);
}
TEST_F(CommandContainerTest, givenAvailableSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenExistingAllocationIsReturned) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
cmdContainer->initialize(pDevice);
cmdContainer->setDirtyStateForAllHeaps(false);
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
const size_t sizeRequested = 32;
const size_t alignment = 32;
EXPECT_GE(heap->getAvailableSpace(), sizeRequested + alignment);
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
auto newAllocation = heapRequested->getGraphicsAllocation();
EXPECT_EQ(heap, heapRequested);
EXPECT_EQ(heapAllocation, newAllocation);
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (alignment - 1)) == 0);
EXPECT_FALSE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
}
TEST_F(CommandContainerTest, givenUnalignedAvailableSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenHeapReturnedIsCorrectlyAligned) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
cmdContainer->initialize(pDevice);
cmdContainer->setDirtyStateForAllHeaps(false);
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
const size_t sizeRequested = 32;
const size_t alignment = 32;
heap->getSpace(sizeRequested / 2);
EXPECT_GE(heap->getAvailableSpace(), sizeRequested + alignment);
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
auto newAllocation = heapRequested->getGraphicsAllocation();
EXPECT_EQ(heap, heapRequested);
EXPECT_EQ(heapAllocation, newAllocation);
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (alignment - 1)) == 0);
EXPECT_FALSE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
}
TEST_F(CommandContainerTest, givenNoAlignmentAndAvailableSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenHeapReturnedIsNotAligned) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
cmdContainer->initialize(pDevice);
cmdContainer->setDirtyStateForAllHeaps(false);
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
const size_t sizeRequested = 32;
const size_t alignment = 0;
heap->getSpace(sizeRequested / 2);
EXPECT_GE(heap->getAvailableSpace(), sizeRequested + alignment);
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
auto newAllocation = heapRequested->getGraphicsAllocation();
EXPECT_EQ(heap, heapRequested);
EXPECT_EQ(heapAllocation, newAllocation);
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (sizeRequested / 2)) == sizeRequested / 2);
EXPECT_FALSE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
}
TEST_F(CommandContainerTest, givenNotEnoughSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenNewAllocationIsReturned) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
cmdContainer->initialize(pDevice);
cmdContainer->setDirtyStateForAllHeaps(false);
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
const size_t sizeRequested = 32;
const size_t alignment = 32;
size_t availableSize = heap->getAvailableSpace();
heap->getSpace(availableSize - sizeRequested / 2);
EXPECT_LT(heap->getAvailableSpace(), sizeRequested + alignment);
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
auto newAllocation = heapRequested->getGraphicsAllocation();
EXPECT_EQ(heap, heapRequested);
EXPECT_NE(heapAllocation, newAllocation);
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (alignment - 1)) == 0);
EXPECT_TRUE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
for (auto deallocation : cmdContainer->getDeallocationContainer()) {
cmdContainer->getDevice()->getMemoryManager()->freeGraphicsMemory(deallocation);
}
cmdContainer->getDeallocationContainer().clear();
}
TEST_F(CommandContainerTest, whenAllocateNextCmdBufferIsCalledThenNewAllocationIsCreatedAndCommandStreamReplaced) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
cmdContainer->initialize(pDevice);
auto stream = cmdContainer->getCommandStream();
ASSERT_NE(nullptr, stream);
auto initialBuffer = stream->getSpace(0);
EXPECT_NE(nullptr, initialBuffer);
cmdContainer->allocateNextCommandBuffer();
auto nextBuffer = stream->getSpace(0);
auto sizeUsed = stream->getUsed();
auto availableSize = stream->getMaxAvailableSpace();
EXPECT_NE(nullptr, nextBuffer);
EXPECT_EQ(0u, sizeUsed);
EXPECT_NE(initialBuffer, nextBuffer);
const size_t cmdBufSize = CommandContainer::defaultListCmdBufferSize;
EXPECT_EQ(cmdBufSize, availableSize);
ASSERT_EQ(2u, cmdContainer->getCmdBufferAllocations().size());
EXPECT_EQ(cmdContainer->getCmdBufferAllocations()[1], cmdContainer->getCommandStream()->getGraphicsAllocation());
EXPECT_EQ(cmdContainer->getCmdBufferAllocations()[1], cmdContainer->getResidencyContainer().back());
}
TEST_F(CommandContainerTest, whenResettingCommandContainerThenStoredCmdBuffersAreFreedAndStreamIsReplacedWithInitialBuffer) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
cmdContainer->initialize(pDevice);
cmdContainer->allocateNextCommandBuffer();
cmdContainer->allocateNextCommandBuffer();
EXPECT_EQ(3u, cmdContainer->getCmdBufferAllocations().size());
cmdContainer->reset();
ASSERT_EQ(1u, cmdContainer->getCmdBufferAllocations().size());
auto stream = cmdContainer->getCommandStream();
ASSERT_NE(nullptr, stream);
auto buffer = stream->getSpace(0);
const size_t cmdBufSize = CommandContainer::defaultListCmdBufferSize;
EXPECT_EQ(cmdContainer->getCmdBufferAllocations()[0]->getUnderlyingBuffer(), buffer);
EXPECT_EQ(cmdBufSize, stream->getMaxAvailableSpace());
}
class CommandContainerHeaps : public DeviceFixture,
public ::testing::TestWithParam<IndirectHeap::Type> {
public:
void SetUp() override {
DeviceFixture::SetUp();
}
void TearDown() override {
DeviceFixture::TearDown();
}
};
INSTANTIATE_TEST_CASE_P(
Device,
CommandContainerHeaps,
testing::Values(
IndirectHeap::DYNAMIC_STATE,
IndirectHeap::INDIRECT_OBJECT,
IndirectHeap::SURFACE_STATE));
TEST_P(CommandContainerHeaps, givenCommandContainerWhenGetAllowHeapGrowCalledThenHeapIsReturned) {
HeapType heap = GetParam();
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
auto usedSpaceBefore = cmdContainer.getIndirectHeap(heap)->getUsed();
size_t size = 5000;
void *ptr = cmdContainer.getHeapSpaceAllowGrow(heap, size);
ASSERT_NE(nullptr, ptr);
auto usedSpaceAfter = cmdContainer.getIndirectHeap(heap)->getUsed();
ASSERT_EQ(usedSpaceBefore + size, usedSpaceAfter);
}
TEST_P(CommandContainerHeaps, givenCommandContainerWhenGetingMoreThanAvailableSizeThenBiggerHeapIsReturned) {
HeapType heap = GetParam();
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
auto usedSpaceBefore = cmdContainer.getIndirectHeap(heap)->getUsed();
auto availableSizeBefore = cmdContainer.getIndirectHeap(heap)->getAvailableSpace();
void *ptr = cmdContainer.getHeapSpaceAllowGrow(heap, availableSizeBefore + 1);
ASSERT_NE(nullptr, ptr);
auto usedSpaceAfter = cmdContainer.getIndirectHeap(heap)->getUsed();
auto availableSizeAfter = cmdContainer.getIndirectHeap(heap)->getAvailableSpace();
EXPECT_GT(usedSpaceAfter + availableSizeAfter, usedSpaceBefore + availableSizeBefore);
}
TEST_F(CommandContainerTest, givenCommandContainerWhenDestructionThenNonHeapAllocationAreNotDestroyed) {
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer());
MockGraphicsAllocation alloc;
size_t size = 0x1000;
alloc.setSize(size);
cmdContainer->initialize(pDevice);
cmdContainer->getDeallocationContainer().push_back(&alloc);
cmdContainer.reset();
EXPECT_EQ(alloc.getUnderlyingBufferSize(), size);
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_container/command_encoder.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "test.h"
using namespace NEO;
class CommandEncoderTests : public DeviceFixture,
public ::testing::Test {
public:
void SetUp() override {
::testing::Test::SetUp();
DeviceFixture::SetUp();
}
void TearDown() override {
DeviceFixture::TearDown();
::testing::Test::TearDown();
}
};
HWTEST_F(CommandEncoderTests, givenImmDataWriteWhenProgrammingMiFlushDwThenSetAllRequiredFields) {
using MI_FLUSH_DW = typename FamilyType::MI_FLUSH_DW;
uint8_t buffer[2 * sizeof(MI_FLUSH_DW)] = {};
LinearStream linearStream(buffer, sizeof(buffer));
uint64_t gpuAddress = 0x1230000;
uint64_t immData = 456;
EncodeMiFlushDW<FamilyType>::programMiFlushDw(linearStream, gpuAddress, immData);
auto miFlushDwCmd = reinterpret_cast<MI_FLUSH_DW *>(buffer);
EXPECT_EQ(sizeof(MI_FLUSH_DW), linearStream.getUsed());
EXPECT_EQ(MI_FLUSH_DW::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA_QWORD, miFlushDwCmd->getPostSyncOperation());
EXPECT_EQ(gpuAddress, miFlushDwCmd->getDestinationAddress());
EXPECT_EQ(immData, miFlushDwCmd->getImmediateData());
}

View File

@@ -1,17 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_COMPILER_INTERFACE_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/compiler_cache_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/compiler_options_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/intermediate_representations_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/linker_mock.h
${CMAKE_CURRENT_SOURCE_DIR}/linker_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_COMPILER_INTERFACE_TESTS ${NEO_CORE_COMPILER_INTERFACE_TESTS})

View File

@@ -1,370 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/compiler_interface/compiler_cache.h"
#include "shared/source/compiler_interface/compiler_interface.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/hash.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/helpers/string.h"
#include "opencl/source/compiler_interface/default_cl_cache_config.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/global_environment.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "opencl/test/unit_test/mocks/mock_program.h"
#include "test.h"
#include <array>
#include <list>
#include <memory>
using namespace NEO;
using namespace std;
class CompilerCacheMock : public CompilerCache {
public:
CompilerCacheMock() : CompilerCache(CompilerCacheConfig{}) {
}
bool cacheBinary(const std::string kernelFileHash, const char *pBinary, uint32_t binarySize) override {
cacheInvoked++;
return cacheResult;
}
std::unique_ptr<char[]> loadCachedBinary(const std::string kernelFileHash, size_t &cachedBinarySize) override {
return loadResult ? std::unique_ptr<char[]>{new char[1]} : nullptr;
}
bool cacheResult = false;
uint32_t cacheInvoked = 0u;
bool loadResult = false;
};
TEST(HashGeneration, givenMisalignedBufferWhenPassedToUpdateFunctionThenProperPtrDataIsUsed) {
Hash hash;
auto originalPtr = alignedMalloc(1024, MemoryConstants::pageSize);
memset(originalPtr, 0xFF, 1024);
char *misalignedPtr = (char *)originalPtr;
misalignedPtr++;
//values really used
misalignedPtr[0] = 1;
misalignedPtr[1] = 2;
misalignedPtr[2] = 3;
misalignedPtr[3] = 4;
misalignedPtr[4] = 5;
//values not used should be ommitted
misalignedPtr[5] = 6;
misalignedPtr[6] = 7;
hash.update(misalignedPtr, 3);
auto hash1 = hash.finish();
hash.reset();
hash.update(misalignedPtr, 4);
auto hash2 = hash.finish();
hash.reset();
hash.update(misalignedPtr, 5);
auto hash3 = hash.finish();
hash.reset();
hash.update(misalignedPtr, 6);
auto hash4 = hash.finish();
EXPECT_NE(hash1, hash2);
EXPECT_NE(hash1, hash3);
EXPECT_NE(hash1, hash4);
EXPECT_NE(hash2, hash3);
EXPECT_NE(hash2, hash4);
EXPECT_NE(hash3, hash4);
auto value2 = hash.getValue(misalignedPtr, 0);
EXPECT_EQ(0u, value2);
alignedFree(originalPtr);
}
TEST(HashGeneration, givenMisalignedBufferWithSizeOneWhenPassedToUpdateFunctionThenProperPtrDataIsUsed) {
Hash hash;
auto originalPtr = alignedMalloc(1024, MemoryConstants::pageSize);
memset(originalPtr, 0xFF, 1024);
char *misalignedPtr = (char *)originalPtr;
misalignedPtr++;
//values really used
misalignedPtr[0] = 1;
//values not used should be ommitted
misalignedPtr[1] = 2;
misalignedPtr[2] = 3;
misalignedPtr[3] = 4;
misalignedPtr[4] = 5;
misalignedPtr[5] = 6;
misalignedPtr[6] = 7;
hash.update(misalignedPtr, 1);
auto value = hash.finish();
EXPECT_EQ(0x088350e6600f29c2u, value);
alignedFree(originalPtr);
}
TEST(CompilerCacheHashTests, WhenHashingThenResultIsDeterministic) {
Hash hash;
std::list<uint64_t> hashes;
char data[4] = "aBc";
for (size_t i = 0; i <= strlen(data); i++) {
hash.reset();
hash.update(data, i);
auto res = hash.finish();
for (auto &in : hashes) {
EXPECT_NE(in, res) << "failed: " << i << " bytes";
}
hashes.push_back(res);
// hash once again to make sure results are the same
hash.reset();
hash.update(data, i);
auto res2 = hash.finish();
EXPECT_EQ(res, res2);
}
}
TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCacheIsReturned) {
static const size_t bufSize = 64;
HardwareInfo hwInfo;
std::set<std::string> hashes;
PLATFORM p1 = {(PRODUCT_FAMILY)1};
PLATFORM p2 = {(PRODUCT_FAMILY)2};
const PLATFORM *platforms[] = {&p1, &p2};
FeatureTable s1;
FeatureTable s2;
s1.ftrSVM = true;
s2.ftrSVM = false;
const FeatureTable *skus[] = {&s1, &s2};
WorkaroundTable w1;
WorkaroundTable w2;
w1.waDoNotUseMIReportPerfCount = true;
w2.waDoNotUseMIReportPerfCount = false;
const WorkaroundTable *was[] = {&w1, &w2};
std::array<std::string, 4> inputArray = {{std::string(""),
std::string("12345678901234567890123456789012"),
std::string("12345678910234567890123456789012"),
std::string("12345678901234567891023456789012")}};
std::array<std::string, 3> optionsArray = {{std::string(""),
std::string("--some --options"),
std::string("--some --different --options")}};
std::array<std::string, 3> internalOptionsArray = {{std::string(""),
std::string("--some --options"),
std::string("--some --different --options")}};
std::unique_ptr<char> buf1(new char[bufSize]);
std::unique_ptr<char> buf2(new char[bufSize]);
std::unique_ptr<char> buf3(new char[bufSize]);
std::unique_ptr<char> buf4(new char[bufSize]);
ArrayRef<char> src;
ArrayRef<char> apiOptions;
ArrayRef<char> internalOptions;
for (auto platform : platforms) {
hwInfo.platform = *platform;
for (auto sku : skus) {
hwInfo.featureTable = *sku;
for (auto wa : was) {
hwInfo.workaroundTable = *wa;
for (size_t i1 = 0; i1 < inputArray.size(); i1++) {
strcpy_s(buf1.get(), bufSize, inputArray[i1].c_str());
src = ArrayRef<char>(buf1.get(), strlen(buf1.get()));
for (size_t i2 = 0; i2 < optionsArray.size(); i2++) {
strcpy_s(buf2.get(), bufSize, optionsArray[i2].c_str());
apiOptions = ArrayRef<char>(buf2.get(), strlen(buf2.get()));
for (size_t i3 = 0; i3 < internalOptionsArray.size(); i3++) {
strcpy_s(buf3.get(), bufSize, internalOptionsArray[i3].c_str());
internalOptions = ArrayRef<char>(buf3.get(), strlen(buf3.get()));
string hash = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions);
if (hashes.find(hash) != hashes.end()) {
FAIL() << "failed: " << i1 << ":" << i2 << ":" << i3;
}
hashes.emplace(hash);
}
}
}
}
}
}
string hash = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions);
string hash2 = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions);
EXPECT_STREQ(hash.c_str(), hash2.c_str());
}
TEST(CompilerCacheTests, GivenEmptyBinaryWhenCachingThenBinaryIsNotCached) {
CompilerCache cache(CompilerCacheConfig{});
bool ret = cache.cacheBinary("some_hash", nullptr, 12u);
EXPECT_FALSE(ret);
const char *tmp1 = "Data";
ret = cache.cacheBinary("some_hash", tmp1, 0u);
EXPECT_FALSE(ret);
}
TEST(CompilerCacheTests, GivenNonExistantConfigWhenLoadingFromCacheThenNullIsReturned) {
CompilerCache cache(CompilerCacheConfig{});
size_t size;
auto ret = cache.loadCachedBinary("----do-not-exists----", size);
EXPECT_EQ(nullptr, ret);
EXPECT_EQ(0U, size);
}
TEST(CompilerCacheTests, GivenExistingConfigWhenLoadingFromCacheThenBinaryIsLoaded) {
CompilerCache cache(getDefaultClCompilerCacheConfig());
static const char *hash = "SOME_HASH";
std::unique_ptr<char> data(new char[32]);
for (size_t i = 0; i < 32; i++)
data.get()[i] = static_cast<char>(i);
bool ret = cache.cacheBinary(hash, static_cast<const char *>(data.get()), 32);
EXPECT_TRUE(ret);
size_t size;
auto loadedBin = cache.loadCachedBinary(hash, size);
EXPECT_NE(nullptr, loadedBin);
EXPECT_NE(0U, size);
}
TEST(CompilerInterfaceCachedTests, GivenNoCachedBinaryWhenBuildingThenErrorIsReturned) {
TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin};
auto src = "#include \"header.h\"\n__kernel k() {}";
inputArgs.src = ArrayRef<const char>(src, strlen(src));
MockCompilerDebugVars fclDebugVars;
fclDebugVars.fileName = gEnvironment->fclGetMockFile();
gEnvironment->fclPushDebugVars(fclDebugVars);
MockCompilerDebugVars igcDebugVars;
igcDebugVars.fileName = gEnvironment->igcGetMockFile();
igcDebugVars.forceBuildFailure = true;
gEnvironment->igcPushDebugVars(igcDebugVars);
std::unique_ptr<CompilerCacheMock> cache(new CompilerCacheMock());
auto compilerInterface = std::unique_ptr<CompilerInterface>(CompilerInterface::createInstance(std::move(cache), true));
TranslationOutput translationOutput;
inputArgs.allowCaching = true;
MockDevice device;
auto err = compilerInterface->build(device, inputArgs, translationOutput);
EXPECT_EQ(TranslationOutput::ErrorCode::BuildFailure, err);
gEnvironment->fclPopDebugVars();
gEnvironment->igcPopDebugVars();
}
TEST(CompilerInterfaceCachedTests, GivenCachedBinaryWhenBuildingThenSuccessIsReturned) {
TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin};
auto src = "#include \"header.h\"\n__kernel k() {}";
inputArgs.src = ArrayRef<const char>(src, strlen(src));
MockCompilerDebugVars fclDebugVars;
fclDebugVars.fileName = gEnvironment->fclGetMockFile();
gEnvironment->fclPushDebugVars(fclDebugVars);
MockCompilerDebugVars igcDebugVars;
igcDebugVars.fileName = gEnvironment->igcGetMockFile();
igcDebugVars.forceBuildFailure = true;
gEnvironment->igcPushDebugVars(igcDebugVars);
std::unique_ptr<CompilerCacheMock> cache(new CompilerCacheMock());
cache->loadResult = true;
auto compilerInterface = std::unique_ptr<CompilerInterface>(CompilerInterface::createInstance(std::move(cache), true));
TranslationOutput translationOutput;
inputArgs.allowCaching = true;
MockDevice device;
auto err = compilerInterface->build(device, inputArgs, translationOutput);
EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
gEnvironment->fclPopDebugVars();
gEnvironment->igcPopDebugVars();
}
TEST(CompilerInterfaceCachedTests, givenKernelWithoutIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsNotCalled) {
MockClDevice device{new MockDevice};
MockContext context(&device, true);
MockProgram program(*device.getExecutionEnvironment(), &context, false, nullptr);
TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin};
auto src = "__kernel k() {}";
inputArgs.src = ArrayRef<const char>(src, strlen(src));
// we force both compilers to fail compilation request
// at the end we expect CL_SUCCESS which means compilation ends in cache
MockCompilerDebugVars fclDebugVars;
fclDebugVars.fileName = gEnvironment->fclGetMockFile();
fclDebugVars.forceBuildFailure = true;
gEnvironment->fclPushDebugVars(fclDebugVars);
MockCompilerDebugVars igcDebugVars;
igcDebugVars.fileName = gEnvironment->igcGetMockFile();
igcDebugVars.forceBuildFailure = true;
gEnvironment->igcPushDebugVars(igcDebugVars);
std::unique_ptr<CompilerCacheMock> cache(new CompilerCacheMock());
cache->loadResult = true;
auto compilerInterface = std::unique_ptr<CompilerInterface>(CompilerInterface::createInstance(std::move(cache), true));
TranslationOutput translationOutput;
inputArgs.allowCaching = true;
auto retVal = compilerInterface->build(device.getDevice(), inputArgs, translationOutput);
EXPECT_EQ(TranslationOutput::ErrorCode::Success, retVal);
gEnvironment->fclPopDebugVars();
gEnvironment->igcPopDebugVars();
}
TEST(CompilerInterfaceCachedTests, givenKernelWithIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsCalled) {
MockClDevice device{new MockDevice};
MockContext context(&device, true);
MockProgram program(*device.getExecutionEnvironment(), &context, false, nullptr);
TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin};
auto src = "#include \"file.h\"\n__kernel k() {}";
inputArgs.src = ArrayRef<const char>(src, strlen(src));
MockCompilerDebugVars fclDebugVars;
fclDebugVars.fileName = gEnvironment->fclGetMockFile();
fclDebugVars.forceBuildFailure = true;
gEnvironment->fclPushDebugVars(fclDebugVars);
std::unique_ptr<CompilerCacheMock> cache(new CompilerCacheMock());
cache->loadResult = true;
auto compilerInterface = std::unique_ptr<CompilerInterface>(CompilerInterface::createInstance(std::move(cache), true));
TranslationOutput translationOutput;
inputArgs.allowCaching = true;
auto retVal = compilerInterface->build(device.getDevice(), inputArgs, translationOutput);
EXPECT_EQ(TranslationOutput::ErrorCode::BuildFailure, retVal);
gEnvironment->fclPopDebugVars();
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "test.h"
#include "compiler_options.h"
TEST(CompilerOptions, WhenConcatenationLengthIsCalledThenReturnsSumOfLengthsAndSeperators) {
using namespace NEO::CompilerOptions;
constexpr auto concatenatedLength = concatenationLength(NEO::CompilerOptions::optDisable);
static_assert(optDisable.length() == concatenatedLength, "");
static_assert(optDisable.length() + 1 + gtpinRera.length() == concatenationLength(optDisable, gtpinRera), "");
static_assert(optDisable.length() + 1 + gtpinRera.length() + 1 + finiteMathOnly.length() == concatenationLength(optDisable, gtpinRera, finiteMathOnly), "");
}
TEST(CompilerOptions, WhenConcatenateIsCalledThenUsesSpaceAsSeparator) {
using namespace NEO::CompilerOptions;
auto concatenated = concatenate(NEO::CompilerOptions::optDisable, NEO::CompilerOptions::finiteMathOnly);
auto expected = (std::string(NEO::CompilerOptions::optDisable) + " " + NEO::CompilerOptions::finiteMathOnly.data());
EXPECT_STREQ(expected.c_str(), concatenated.c_str());
constexpr ConstStringRef toConcatenate[] = {"a", "b", "c"};
constexpr ConstConcatenation<concatenationLength(toConcatenate)> constConcatenationSpecificSize(toConcatenate);
constexpr ConstConcatenation<> constConcatenationDefaultSize(toConcatenate);
EXPECT_TRUE(ConstStringRef("a b c") == constConcatenationSpecificSize);
EXPECT_TRUE(ConstStringRef("a b c") == constConcatenationDefaultSize);
}
TEST(CompilerOptions, WhenConcatenateAppendIsCalledThenAddsSpaceAsSeparatorOnlyIfMissing) {
using namespace NEO::CompilerOptions;
std::string concatenated = NEO::CompilerOptions::optDisable.data();
concatenateAppend(concatenated, NEO::CompilerOptions::finiteMathOnly);
auto expected = (std::string(NEO::CompilerOptions::optDisable) + " " + NEO::CompilerOptions::finiteMathOnly.data());
EXPECT_STREQ(expected.c_str(), concatenated.c_str());
concatenated += " ";
concatenateAppend(concatenated, NEO::CompilerOptions::fastRelaxedMath);
expected += " ";
expected += NEO::CompilerOptions::fastRelaxedMath;
EXPECT_STREQ(expected.c_str(), concatenated.c_str());
}
TEST(CompilerOptions, WhenCheckingForPresenceOfOptionThenRejectsSubstrings) {
EXPECT_FALSE(NEO::CompilerOptions::contains("aaa", "a"));
EXPECT_FALSE(NEO::CompilerOptions::contains("aaa", "aa"));
EXPECT_TRUE(NEO::CompilerOptions::contains("aaa", "aaa"));
EXPECT_FALSE(NEO::CompilerOptions::contains("aaa", "aaaa"));
EXPECT_TRUE(NEO::CompilerOptions::contains("aaaa aaa", "aaaa"));
EXPECT_TRUE(NEO::CompilerOptions::contains("aa aaaa", "aaaa"));
}
TEST(CompilerOptions, WhenTokenizingThenSpaceIsUsedAsSeparator) {
auto tokenizedEmpty = NEO::CompilerOptions::tokenize("");
EXPECT_TRUE(tokenizedEmpty.empty());
auto tokenizedOne = NEO::CompilerOptions::tokenize("abc");
ASSERT_EQ(1U, tokenizedOne.size());
EXPECT_EQ("abc", tokenizedOne[0]);
auto tokenizedOneSkipSpaces = NEO::CompilerOptions::tokenize(" abc ");
ASSERT_EQ(1U, tokenizedOneSkipSpaces.size());
EXPECT_EQ("abc", tokenizedOneSkipSpaces[0]);
auto tokenizedMultiple = NEO::CompilerOptions::tokenize(" -optA -optB c ");
ASSERT_EQ(3U, tokenizedMultiple.size());
EXPECT_EQ("-optA", tokenizedMultiple[0]);
EXPECT_EQ("-optB", tokenizedMultiple[1]);
EXPECT_EQ("c", tokenizedMultiple[2]);
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/compiler_interface/intermediate_representations.h"
#include "test.h"
TEST(HasSameMagic, WhenMagicIsMatchedThenReturnTrue) {
EXPECT_TRUE(NEO::hasSameMagic("abcd", ArrayRef<const char>("abcdefg").toArrayRef<const uint8_t>()));
}
TEST(HasSameMagic, WhenBinaryIsNullptrThenReturnFalse) {
EXPECT_FALSE(NEO::hasSameMagic("abcd", {}));
}
TEST(HasSameMagic, WhenBinaryIsShorterThanExpectedMagicThenReturnFalse) {
EXPECT_FALSE(NEO::hasSameMagic("abcd", ArrayRef<const char>("ab").toArrayRef<const uint8_t>()));
}
TEST(HasSameMagic, WhenMagicIsNotMatchedThenReturnFalse) {
EXPECT_FALSE(NEO::hasSameMagic("abcd", ArrayRef<const char>("abcefg").toArrayRef<const uint8_t>()));
}
static constexpr uint8_t llvmBinary[] = "BC\xc0\xde ";
TEST(IsLlvmBitcode, WhenLlvmMagicWasFoundThenBinaryIsValidLLvm) {
EXPECT_TRUE(NEO::isLlvmBitcode(llvmBinary));
}
TEST(IsLlvmBitcode, WhenBinaryIsNullptrThenBinaryIsNotValidLLvm) {
EXPECT_FALSE(NEO::isLlvmBitcode(ArrayRef<const uint8_t>()));
}
TEST(IsLlvmBitcode, WhenBinaryIsShorterThanLllvMagicThenBinaryIsNotValidLLvm) {
EXPECT_FALSE(NEO::isLlvmBitcode(ArrayRef<const uint8_t>(llvmBinary, 2)));
}
TEST(IsLlvmBitcode, WhenBinaryDoesNotContainLllvMagicThenBinaryIsNotValidLLvm) {
const uint8_t notLlvmBinary[] = "ABCDEFGHIJKLMNO";
EXPECT_FALSE(NEO::isLlvmBitcode(notLlvmBinary));
}
static constexpr uint32_t spirv[16] = {0x03022307};
static constexpr uint32_t spirvInvEndianes[16] = {0x07230203};
TEST(IsSpirVBitcode, WhenSpirvMagicWasFoundThenBinaryIsValidSpirv) {
EXPECT_TRUE(NEO::isSpirVBitcode(ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(&spirv), sizeof(spirv))));
EXPECT_TRUE(NEO::isSpirVBitcode(ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(&spirvInvEndianes), sizeof(spirvInvEndianes))));
}
TEST(IsSpirVBitcode, WhenBinaryIsNullptrThenBinaryIsNotValidSpirv) {
EXPECT_FALSE(NEO::isSpirVBitcode(ArrayRef<const uint8_t>()));
}
TEST(IsSpirVBitcode, WhenBinaryIsShorterThanLllvMagicThenBinaryIsNotValidSpirv) {
EXPECT_FALSE(NEO::isSpirVBitcode(ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(&spirvInvEndianes), 2)));
}
TEST(IsSpirVBitcode, WhenBinaryDoesNotContainLllvMagicThenBinaryIsNotValidSpirv) {
const uint8_t notSpirvBinary[] = "ABCDEFGHIJKLMNO";
EXPECT_FALSE(NEO::isSpirVBitcode(notSpirvBinary));
}

View File

@@ -1,83 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/compiler_interface/linker.h"
#include <functional>
#include <tuple>
template <class BaseClass>
struct WhiteBox;
template <class BaseClass>
struct Mock;
template <>
struct WhiteBox<NEO::LinkerInput> : NEO::LinkerInput {
using BaseClass = NEO::LinkerInput;
using BaseClass::dataRelocations;
using BaseClass::exportedFunctionsSegmentId;
using BaseClass::relocations;
using BaseClass::symbols;
using BaseClass::traits;
using BaseClass::valid;
};
template <typename MockT, typename ReturnT, typename... ArgsT>
struct LightMockConfig {
using MockReturnT = ReturnT;
using OverrideT = std::function<ReturnT(MockT *, ArgsT...)>;
uint32_t timesCalled = 0U;
OverrideT overrideFunc;
};
template <typename ConfigT, typename ObjT, typename... ArgsT>
typename ConfigT::MockReturnT invokeMocked(ConfigT &config, ObjT obj, ArgsT &&... args) {
config.timesCalled += 1;
if (config.overrideFunc) {
return config.overrideFunc(obj, std::forward<ArgsT>(args)...);
} else {
return config.originalFunc(obj, std::forward<ArgsT>(args)...);
}
}
#define LIGHT_MOCK_OVERRIDE_2(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T) \
struct : LightMockConfig<MOCK_T, RETURN_T, ARG0_T, ARG1_T> { \
OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1) -> RETURN_T { \
return obj->BaseT::NAME(std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1)); \
}; \
} NAME##MockConfig; \
\
RETURN_T NAME(ARG0_T arg0, ARG1_T arg1) override { \
return invokeMocked(NAME##MockConfig, this, std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1)); \
}
#define LIGHT_MOCK_OVERRIDE_3(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T, ARG2_T) \
struct : LightMockConfig<MOCK_T, RETURN_T, ARG0_T, ARG1_T, ARG2_T> { \
OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) -> RETURN_T { \
return obj->BaseT::NAME(std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1), std::forward<ARG2_T>(arg2)); \
}; \
} NAME##MockConfig; \
\
RETURN_T NAME(ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) override { \
return invokeMocked(NAME##MockConfig, this, std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1), std::forward<ARG2_T>(arg2)); \
}
template <>
struct Mock<NEO::LinkerInput> : WhiteBox<NEO::LinkerInput> {
using ThisT = Mock<NEO::LinkerInput>;
using BaseT = NEO::LinkerInput;
using WhiteBoxBaseT = WhiteBox<BaseT>;
LIGHT_MOCK_OVERRIDE_2(decodeGlobalVariablesSymbolTable, ThisT, BaseT, bool, const void *, uint32_t);
LIGHT_MOCK_OVERRIDE_3(decodeExportedFunctionsSymbolTable, ThisT, BaseT, bool, const void *, uint32_t, uint32_t);
LIGHT_MOCK_OVERRIDE_3(decodeRelocationTable, ThisT, BaseT, bool, const void *, uint32_t, uint32_t);
};

View File

@@ -1,988 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/ptr_math.h"
#include "RelocationInfo.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "linker_mock.h"
#include <string>
TEST(SegmentTypeTests, givenSegmentTypeWhenAsStringIsCalledThenProperRepresentationIsReturned) {
EXPECT_STREQ("UNKOWN", NEO::asString(NEO::SegmentType::Unknown));
EXPECT_STREQ("GLOBAL_CONSTANTS", NEO::asString(NEO::SegmentType::GlobalConstants));
EXPECT_STREQ("GLOBAL_VARIABLES", NEO::asString(NEO::SegmentType::GlobalVariables));
EXPECT_STREQ("INSTRUCTIONS", NEO::asString(NEO::SegmentType::Instructions));
}
TEST(LinkerInputTraitsTests, whenPointerSizeNotSizeThenDefaultsToHostPointerSize) {
using PointerSize = NEO::LinkerInput::Traits::PointerSize;
auto expectedPointerSize = (sizeof(void *) == 4) ? PointerSize::Ptr32bit : PointerSize::Ptr64bit;
auto pointerSize = NEO::LinkerInput::Traits{}.pointerSize;
EXPECT_EQ(expectedPointerSize, pointerSize);
}
TEST(LinkerInputTests, givenGlobalsSymbolTableThenProperlyDecodesGlobalVariablesAndGlobalConstants) {
NEO::LinkerInput linkerInput;
EXPECT_TRUE(linkerInput.isValid());
vISA::GenSymEntry entry[2] = {{}, {}};
entry[0].s_name[0] = 'A';
entry[0].s_offset = 8;
entry[0].s_size = 16;
entry[0].s_type = vISA::GenSymType::S_GLOBAL_VAR;
entry[1].s_name[0] = 'B';
entry[1].s_offset = 24;
entry[1].s_size = 8;
entry[1].s_type = vISA::GenSymType::S_GLOBAL_VAR_CONST;
EXPECT_EQ(0U, linkerInput.getSymbols().size());
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalConstants);
EXPECT_FALSE(linkerInput.getTraits().exportsFunctions);
auto decodeResult = linkerInput.decodeGlobalVariablesSymbolTable(entry, 2);
EXPECT_TRUE(decodeResult);
EXPECT_TRUE(linkerInput.isValid());
EXPECT_EQ(2U, linkerInput.getSymbols().size());
EXPECT_TRUE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_TRUE(linkerInput.getTraits().exportsGlobalConstants);
EXPECT_FALSE(linkerInput.getTraits().exportsFunctions);
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfInstructionSegments);
auto symbolA = linkerInput.getSymbols().find("A");
ASSERT_NE(linkerInput.getSymbols().end(), symbolA);
EXPECT_EQ(entry[0].s_offset, symbolA->second.offset);
EXPECT_EQ(entry[0].s_size, symbolA->second.size);
EXPECT_EQ(NEO::SegmentType::GlobalVariables, symbolA->second.segment);
auto symbolB = linkerInput.getSymbols().find("B");
ASSERT_NE(linkerInput.getSymbols().end(), symbolB);
EXPECT_EQ(entry[1].s_offset, symbolB->second.offset);
EXPECT_EQ(entry[1].s_size, symbolB->second.size);
EXPECT_EQ(NEO::SegmentType::GlobalConstants, symbolB->second.segment);
auto symbolC = linkerInput.getSymbols().find("C");
EXPECT_EQ(linkerInput.getSymbols().end(), symbolC);
}
TEST(LinkerInputTests, givenFunctionsSymbolTableThenProperlyDecodesGlobalVariablesAndGlobalConstants) {
// Note : this is subject to change in IGC shotly.
// GLOBAL_VAR/CONST will be ultimately allowed only in globalVariables symbol table.
NEO::LinkerInput linkerInput;
vISA::GenSymEntry entry[2] = {{}, {}};
entry[0].s_name[0] = 'A';
entry[0].s_offset = 8;
entry[0].s_size = 16;
entry[0].s_type = vISA::GenSymType::S_GLOBAL_VAR;
entry[1].s_name[0] = 'B';
entry[1].s_offset = 24;
entry[1].s_size = 8;
entry[1].s_type = vISA::GenSymType::S_GLOBAL_VAR_CONST;
EXPECT_EQ(0U, linkerInput.getSymbols().size());
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalConstants);
EXPECT_FALSE(linkerInput.getTraits().exportsFunctions);
auto decodeResult = linkerInput.decodeExportedFunctionsSymbolTable(entry, 2, 3);
EXPECT_TRUE(decodeResult);
EXPECT_TRUE(linkerInput.isValid());
EXPECT_EQ(2U, linkerInput.getSymbols().size());
EXPECT_TRUE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_TRUE(linkerInput.getTraits().exportsGlobalConstants);
EXPECT_FALSE(linkerInput.getTraits().exportsFunctions);
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfInstructionSegments);
auto symbolA = linkerInput.getSymbols().find("A");
ASSERT_NE(linkerInput.getSymbols().end(), symbolA);
EXPECT_EQ(entry[0].s_offset, symbolA->second.offset);
EXPECT_EQ(entry[0].s_size, symbolA->second.size);
EXPECT_EQ(NEO::SegmentType::GlobalVariables, symbolA->second.segment);
auto symbolB = linkerInput.getSymbols().find("B");
ASSERT_NE(linkerInput.getSymbols().end(), symbolB);
EXPECT_EQ(entry[1].s_offset, symbolB->second.offset);
EXPECT_EQ(entry[1].s_size, symbolB->second.size);
EXPECT_EQ(NEO::SegmentType::GlobalConstants, symbolB->second.segment);
auto symbolC = linkerInput.getSymbols().find("C");
EXPECT_EQ(linkerInput.getSymbols().end(), symbolC);
}
TEST(LinkerInputTests, givenGlobalsSymbolTableThenFunctionExportsAreNotAllowed) {
NEO::LinkerInput linkerInput;
vISA::GenSymEntry entry = {};
entry.s_name[0] = 'A';
entry.s_offset = 8;
entry.s_size = 16;
entry.s_type = vISA::GenSymType::S_FUNC;
auto decodeResult = linkerInput.decodeGlobalVariablesSymbolTable(&entry, 1);
EXPECT_FALSE(decodeResult);
EXPECT_FALSE(linkerInput.isValid());
}
TEST(LinkerInputTests, givenFunctionsSymbolTableThenProperlyDecodesExportedFunctions) {
NEO::LinkerInput linkerInput;
vISA::GenSymEntry entry[2] = {{}, {}};
entry[0].s_name[0] = 'A';
entry[0].s_offset = 8;
entry[0].s_size = 16;
entry[0].s_type = vISA::GenSymType::S_FUNC;
entry[1].s_name[0] = 'B';
entry[1].s_offset = 24;
entry[1].s_size = 8;
entry[1].s_type = vISA::GenSymType::S_FUNC;
EXPECT_EQ(0U, linkerInput.getSymbols().size());
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalConstants);
EXPECT_FALSE(linkerInput.getTraits().exportsFunctions);
EXPECT_EQ(-1, linkerInput.getExportedFunctionsSegmentId());
auto decodeResult = linkerInput.decodeExportedFunctionsSymbolTable(entry, 2, 3);
EXPECT_TRUE(decodeResult);
EXPECT_TRUE(linkerInput.isValid());
EXPECT_EQ(2U, linkerInput.getSymbols().size());
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalConstants);
EXPECT_TRUE(linkerInput.getTraits().exportsFunctions);
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfInstructionSegments);
auto symbolA = linkerInput.getSymbols().find("A");
ASSERT_NE(linkerInput.getSymbols().end(), symbolA);
EXPECT_EQ(entry[0].s_offset, symbolA->second.offset);
EXPECT_EQ(entry[0].s_size, symbolA->second.size);
EXPECT_EQ(NEO::SegmentType::Instructions, symbolA->second.segment);
auto symbolB = linkerInput.getSymbols().find("B");
ASSERT_NE(linkerInput.getSymbols().end(), symbolB);
EXPECT_EQ(entry[1].s_offset, symbolB->second.offset);
EXPECT_EQ(entry[1].s_size, symbolB->second.size);
EXPECT_EQ(NEO::SegmentType::Instructions, symbolB->second.segment);
EXPECT_EQ(3, linkerInput.getExportedFunctionsSegmentId());
}
TEST(LinkerInputTests, givenFunctionsSymbolTableThenUndefIsNotAllowed) {
NEO::LinkerInput linkerInput;
vISA::GenSymEntry entry = {};
entry.s_name[0] = 'A';
entry.s_offset = 8;
entry.s_size = 16;
entry.s_type = vISA::GenSymType::S_UNDEF;
auto decodeResult = linkerInput.decodeExportedFunctionsSymbolTable(&entry, 1, 3);
EXPECT_FALSE(decodeResult);
EXPECT_FALSE(linkerInput.isValid());
}
TEST(LinkerInputTests, givenRelocationTableThenRelocationEntriesAreProperlyParsed) {
NEO::LinkerInput linkerInput;
vISA::GenRelocEntry entry = {};
entry.r_symbol[0] = 'A';
entry.r_offset = 8;
entry.r_type = vISA::GenRelocType::R_SYM_ADDR;
auto decodeResult = linkerInput.decodeRelocationTable(&entry, 1, 3);
EXPECT_TRUE(decodeResult);
EXPECT_EQ(0U, linkerInput.getSymbols().size());
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalConstants);
EXPECT_FALSE(linkerInput.getTraits().exportsFunctions);
EXPECT_TRUE(linkerInput.getTraits().requiresPatchingOfInstructionSegments);
decodeResult = linkerInput.decodeRelocationTable(&entry, 1, 1);
EXPECT_TRUE(decodeResult);
EXPECT_TRUE(linkerInput.isValid());
}
TEST(LinkerInputTests, givenRelocationTableThenNoneAsRelocationTypeIsNotAllowed) {
NEO::LinkerInput linkerInput;
vISA::GenRelocEntry entry = {};
entry.r_symbol[0] = 'A';
entry.r_offset = 8;
entry.r_type = vISA::GenRelocType::R_NONE;
auto decodeResult = linkerInput.decodeRelocationTable(&entry, 1, 3);
EXPECT_FALSE(decodeResult);
EXPECT_FALSE(linkerInput.isValid());
}
TEST(LinkerInputTests, whenDataRelocationsAreAddedThenProperTraitsAreSet) {
NEO::LinkerInput linkerInput;
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
NEO::LinkerInput::RelocationInfo relocInfo;
relocInfo.offset = 7U;
relocInfo.relocationSegment = NEO::SegmentType::GlobalConstants;
relocInfo.symbolName = "aaa";
relocInfo.symbolSegment = NEO::SegmentType::GlobalVariables;
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.addDataRelocationInfo(relocInfo);
ASSERT_EQ(1U, linkerInput.getDataRelocations().size());
EXPECT_EQ(relocInfo.offset, linkerInput.getDataRelocations()[0].offset);
EXPECT_EQ(relocInfo.relocationSegment, linkerInput.getDataRelocations()[0].relocationSegment);
EXPECT_EQ(relocInfo.symbolName, linkerInput.getDataRelocations()[0].symbolName);
EXPECT_EQ(relocInfo.symbolSegment, linkerInput.getDataRelocations()[0].symbolSegment);
EXPECT_EQ(relocInfo.type, linkerInput.getDataRelocations()[0].type);
EXPECT_TRUE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
EXPECT_TRUE(linkerInput.isValid());
linkerInput = {};
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
relocInfo.relocationSegment = NEO::SegmentType::GlobalVariables;
relocInfo.symbolSegment = NEO::SegmentType::GlobalConstants;
linkerInput.addDataRelocationInfo(relocInfo);
ASSERT_EQ(1U, linkerInput.getDataRelocations().size());
EXPECT_FALSE(linkerInput.getTraits().requiresPatchingOfGlobalConstantsBuffer);
EXPECT_TRUE(linkerInput.getTraits().requiresPatchingOfGlobalVariablesBuffer);
EXPECT_TRUE(linkerInput.isValid());
}
TEST(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) {
NEO::LinkerInput linkerInput;
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc;
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
NEO::Linker::PatchableSegments patchableInstructionSegments;
NEO::Linker::UnresolvedExternals unresolvedExternals;
bool linkResult = linker.link(globalVar, globalConst, exportedFunc,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
auto relocatedSymbols = linker.extractRelocatedSymbols();
EXPECT_EQ(0U, relocatedSymbols.size());
}
TEST(LinkerTests, givenInvalidLinkerInputThenLinkerFails) {
WhiteBox<NEO::LinkerInput> mockLinkerInput;
mockLinkerInput.valid = false;
NEO::Linker linker(mockLinkerInput);
NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc;
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
NEO::Linker::PatchableSegments patchableInstructionSegments;
NEO::Linker::UnresolvedExternals unresolvedExternals;
bool linkResult = linker.link(globalVar, globalConst, exportedFunc,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_FALSE(linkResult);
}
TEST(LinkerTests, givenUnresolvedExternalWhenPatchingInstructionsThenLinkerFails) {
NEO::LinkerInput linkerInput;
vISA::GenRelocEntry entry = {};
entry.r_symbol[0] = 'A';
entry.r_offset = 8;
entry.r_type = vISA::GenRelocType::R_SYM_ADDR;
auto decodeResult = linkerInput.decodeRelocationTable(&entry, 1, 0);
EXPECT_TRUE(decodeResult);
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> instructionSegment;
instructionSegment.resize(64);
NEO::Linker::PatchableSegment seg0;
seg0.hostPointer = instructionSegment.data();
seg0.segmentSize = instructionSegment.size();
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
bool linkResult = linker.link(globalVar, globalConst, exportedFunc,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_FALSE(linkResult);
auto relocatedSymbols = linker.extractRelocatedSymbols();
EXPECT_EQ(0U, relocatedSymbols.size());
ASSERT_EQ(1U, unresolvedExternals.size());
EXPECT_EQ(0U, unresolvedExternals[0].instructionsSegmentId);
EXPECT_FALSE(unresolvedExternals[0].internalError);
EXPECT_EQ(entry.r_offset, unresolvedExternals[0].unresolvedRelocation.offset);
EXPECT_EQ(std::string(entry.r_symbol), std::string(unresolvedExternals[0].unresolvedRelocation.symbolName));
}
TEST(LinkerTests, givenValidSymbolsAndRelocationsThenInstructionSegmentsAreProperlyPatched) {
NEO::LinkerInput linkerInput;
vISA::GenSymEntry symGlobalVariable = {};
symGlobalVariable.s_name[0] = 'A';
symGlobalVariable.s_offset = 4;
symGlobalVariable.s_size = 16;
symGlobalVariable.s_type = vISA::GenSymType::S_GLOBAL_VAR;
bool decodeSymSuccess = linkerInput.decodeGlobalVariablesSymbolTable(&symGlobalVariable, 1);
vISA::GenSymEntry symGlobalConstant = {};
symGlobalConstant.s_name[0] = 'B';
symGlobalConstant.s_offset = 20;
symGlobalConstant.s_size = 8;
symGlobalConstant.s_type = vISA::GenSymType::S_GLOBAL_VAR_CONST;
decodeSymSuccess = decodeSymSuccess && linkerInput.decodeGlobalVariablesSymbolTable(&symGlobalConstant, 1);
vISA::GenSymEntry symExportedFunc = {};
symExportedFunc.s_name[0] = 'C';
symExportedFunc.s_offset = 16;
symExportedFunc.s_size = 32;
symExportedFunc.s_type = vISA::GenSymType::S_FUNC;
decodeSymSuccess = decodeSymSuccess && linkerInput.decodeExportedFunctionsSymbolTable(&symExportedFunc, 1, 0);
EXPECT_TRUE(decodeSymSuccess);
vISA::GenRelocEntry relocA = {};
relocA.r_symbol[0] = 'A';
relocA.r_offset = 0;
relocA.r_type = vISA::GenRelocType::R_SYM_ADDR;
vISA::GenRelocEntry relocB = {};
relocB.r_symbol[0] = 'B';
relocB.r_offset = 8;
relocB.r_type = vISA::GenRelocType::R_SYM_ADDR;
vISA::GenRelocEntry relocC = {};
relocC.r_symbol[0] = 'C';
relocC.r_offset = 16;
relocC.r_type = vISA::GenRelocType::R_SYM_ADDR;
vISA::GenRelocEntry relocCPartHigh = {};
relocCPartHigh.r_symbol[0] = 'C';
relocCPartHigh.r_offset = 28;
relocCPartHigh.r_type = vISA::GenRelocType::R_SYM_ADDR_32_HI;
vISA::GenRelocEntry relocCPartLow = {};
relocCPartLow.r_symbol[0] = 'C';
relocCPartLow.r_offset = 36;
relocCPartLow.r_type = vISA::GenRelocType::R_SYM_ADDR_32;
vISA::GenRelocEntry relocs[] = {relocA, relocB, relocC, relocCPartHigh, relocCPartLow};
bool decodeRelocSuccess = linkerInput.decodeRelocationTable(&relocs, 5, 0);
EXPECT_TRUE(decodeRelocSuccess);
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
globalVarSegment.gpuAddress = 8;
globalVarSegment.segmentSize = 64;
globalConstSegment.gpuAddress = 128;
globalConstSegment.segmentSize = 256;
exportedFuncSegment.gpuAddress = 4096;
exportedFuncSegment.segmentSize = 1024;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> instructionSegment;
uint32_t initData = 0x77777777;
instructionSegment.resize(64, static_cast<char>(initData));
NEO::Linker::PatchableSegment seg0;
seg0.hostPointer = instructionSegment.data();
seg0.segmentSize = instructionSegment.size();
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals);
EXPECT_TRUE(linkResult);
auto relocatedSymbols = linker.extractRelocatedSymbols();
EXPECT_EQ(0U, unresolvedExternals.size());
EXPECT_EQ(3U, relocatedSymbols.size());
ASSERT_EQ(1U, relocatedSymbols.count(symGlobalVariable.s_name));
ASSERT_EQ(1U, relocatedSymbols.count(symGlobalConstant.s_name));
ASSERT_EQ(1U, relocatedSymbols.count(symGlobalVariable.s_name));
EXPECT_EQ(relocatedSymbols[symGlobalVariable.s_name].gpuAddress, globalVarSegment.gpuAddress + symGlobalVariable.s_offset);
EXPECT_EQ(relocatedSymbols[symGlobalConstant.s_name].gpuAddress, globalConstSegment.gpuAddress + symGlobalConstant.s_offset);
EXPECT_EQ(relocatedSymbols[symExportedFunc.s_name].gpuAddress, exportedFuncSegment.gpuAddress + symExportedFunc.s_offset);
EXPECT_EQ(relocatedSymbols[symGlobalVariable.s_name].gpuAddress, *reinterpret_cast<const uintptr_t *>(instructionSegment.data() + relocA.r_offset));
EXPECT_EQ(relocatedSymbols[symGlobalConstant.s_name].gpuAddress, *reinterpret_cast<const uintptr_t *>(instructionSegment.data() + relocB.r_offset));
EXPECT_EQ(relocatedSymbols[symExportedFunc.s_name].gpuAddress, *reinterpret_cast<const uintptr_t *>(instructionSegment.data() + relocC.r_offset));
auto funcGpuAddressAs64bit = static_cast<uint64_t>(relocatedSymbols[symExportedFunc.s_name].gpuAddress);
auto funcAddressLow = static_cast<uint32_t>(funcGpuAddressAs64bit & 0xffffffff);
auto funcAddressHigh = static_cast<uint32_t>((funcGpuAddressAs64bit >> 32) & 0xffffffff);
EXPECT_EQ(funcAddressLow, *reinterpret_cast<const uint32_t *>(instructionSegment.data() + relocCPartLow.r_offset));
EXPECT_EQ(initData, *reinterpret_cast<const uint32_t *>(instructionSegment.data() + relocCPartLow.r_offset - sizeof(uint32_t)));
EXPECT_EQ(initData, *reinterpret_cast<const uint32_t *>(instructionSegment.data() + relocCPartLow.r_offset + sizeof(uint32_t)));
EXPECT_EQ(funcAddressHigh, *reinterpret_cast<const uint32_t *>(instructionSegment.data() + relocCPartHigh.r_offset));
EXPECT_EQ(initData, *reinterpret_cast<const uint32_t *>(instructionSegment.data() + relocCPartHigh.r_offset - sizeof(uint32_t)));
EXPECT_EQ(initData, *reinterpret_cast<const uint32_t *>(instructionSegment.data() + relocCPartHigh.r_offset + sizeof(uint32_t)));
}
TEST(LinkerTests, givenInvalidSymbolOffsetWhenPatchingInstructionsThenRelocationFails) {
NEO::LinkerInput linkerInput;
vISA::GenSymEntry symGlobalVariable = {};
symGlobalVariable.s_name[0] = 'A';
symGlobalVariable.s_offset = 64;
symGlobalVariable.s_size = 16;
symGlobalVariable.s_type = vISA::GenSymType::S_GLOBAL_VAR;
bool decodeSymSuccess = linkerInput.decodeGlobalVariablesSymbolTable(&symGlobalVariable, 1);
EXPECT_TRUE(decodeSymSuccess);
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
globalVarSegment.gpuAddress = 8;
globalVarSegment.segmentSize = symGlobalVariable.s_offset;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> instructionSegment;
instructionSegment.resize(64, 0);
NEO::Linker::PatchableSegment seg0;
seg0.hostPointer = instructionSegment.data();
seg0.segmentSize = instructionSegment.size();
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_FALSE(linkResult);
auto relocatedSymbols = linker.extractRelocatedSymbols();
EXPECT_EQ(0U, unresolvedExternals.size());
EXPECT_EQ(0U, relocatedSymbols.size());
globalVarSegment.segmentSize = symGlobalVariable.s_offset + symGlobalVariable.s_size;
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals);
EXPECT_TRUE(linkResult);
}
TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfInstructionsFails) {
NEO::LinkerInput linkerInput;
vISA::GenSymEntry symGlobalVariable = {};
symGlobalVariable.s_name[0] = 'A';
symGlobalVariable.s_offset = 64;
symGlobalVariable.s_size = 16;
symGlobalVariable.s_type = vISA::GenSymType::S_GLOBAL_VAR;
bool decodeSymSuccess = linkerInput.decodeGlobalVariablesSymbolTable(&symGlobalVariable, 1);
EXPECT_TRUE(decodeSymSuccess);
vISA::GenRelocEntry relocA = {};
relocA.r_symbol[0] = 'A';
relocA.r_offset = 32;
relocA.r_type = vISA::GenRelocType::R_SYM_ADDR;
bool decodeRelocSuccess = linkerInput.decodeRelocationTable(&relocA, 1, 0);
EXPECT_TRUE(decodeRelocSuccess);
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
globalVarSegment.gpuAddress = 8;
globalVarSegment.segmentSize = symGlobalVariable.s_offset + symGlobalVariable.s_size;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> instructionSegment;
instructionSegment.resize(relocA.r_offset + sizeof(uintptr_t), 0);
NEO::Linker::PatchableSegment seg0;
seg0.hostPointer = instructionSegment.data();
seg0.segmentSize = relocA.r_offset;
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_FALSE(linkResult);
auto relocatedSymbols = linker.extractRelocatedSymbols();
EXPECT_EQ(1U, relocatedSymbols.size());
ASSERT_EQ(1U, unresolvedExternals.size());
EXPECT_TRUE(unresolvedExternals[0].internalError);
patchableInstructionSegments[0].segmentSize = relocA.r_offset + sizeof(uintptr_t);
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_TRUE(linkResult);
}
TEST(LinkerTests, givenUnknownSymbolTypeWhenPatchingInstructionsThenRelocationFails) {
WhiteBox<NEO::LinkerInput> linkerInput;
vISA::GenSymEntry symGlobalVariable = {};
symGlobalVariable.s_name[0] = 'A';
symGlobalVariable.s_offset = 0;
symGlobalVariable.s_size = 16;
symGlobalVariable.s_type = vISA::GenSymType::S_GLOBAL_VAR;
bool decodeSymSuccess = linkerInput.decodeGlobalVariablesSymbolTable(&symGlobalVariable, 1);
EXPECT_TRUE(decodeSymSuccess);
vISA::GenRelocEntry relocA = {};
relocA.r_symbol[0] = 'A';
relocA.r_offset = 0;
relocA.r_type = vISA::GenRelocType::R_SYM_ADDR;
bool decodeRelocSuccess = linkerInput.decodeRelocationTable(&relocA, 1, 0);
EXPECT_TRUE(decodeRelocSuccess);
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
globalVarSegment.gpuAddress = 8;
globalVarSegment.segmentSize = 64;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> instructionSegment;
instructionSegment.resize(64, 0);
NEO::Linker::PatchableSegment seg0;
seg0.hostPointer = instructionSegment.data();
seg0.segmentSize = instructionSegment.size();
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg;
ASSERT_EQ(1U, linkerInput.symbols.count("A"));
linkerInput.symbols["A"].segment = NEO::SegmentType::Unknown;
bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_FALSE(linkResult);
auto relocatedSymbols = linker.extractRelocatedSymbols();
EXPECT_EQ(0U, relocatedSymbols.size());
ASSERT_EQ(0U, unresolvedExternals.size());
linkerInput.symbols["A"].segment = NEO::SegmentType::GlobalVariables;
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
unresolvedExternals);
EXPECT_TRUE(linkResult);
}
TEST(LinkerTests, givenInvalidSourceSegmentWhenPatchingDataSegmentsThenLinkerFails) {
WhiteBox<NEO::LinkerInput> linkerInput;
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo emptySegmentInfo;
NEO::Linker::PatchableSegment emptyPatchableSegment;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> nonEmptypatchableSegmentData;
nonEmptypatchableSegmentData.resize(64, 8U);
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
NEO::LinkerInput::RelocationInfo relocInfo;
relocInfo.offset = 0U;
relocInfo.symbolName = "aaa";
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.dataRelocations.push_back(relocInfo);
{
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
linkerInput.traits.requiresPatchingOfGlobalConstantsBuffer = false;
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::Unknown;
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_FALSE(linkResult);
EXPECT_EQ(1U, unresolvedExternals.size());
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
unresolvedExternals.clear();
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
}
{
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = false;
linkerInput.traits.requiresPatchingOfGlobalConstantsBuffer = true;
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalConstants;
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::Unknown;
unresolvedExternals.clear();
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
emptyPatchableSegment, nonEmptypatchableSegment, {},
unresolvedExternals);
EXPECT_FALSE(linkResult);
EXPECT_EQ(1U, unresolvedExternals.size());
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
unresolvedExternals.clear();
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
emptyPatchableSegment, nonEmptypatchableSegment, {},
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
}
}
TEST(LinkerTests, givenUnknownRelocationSegmentWhenPatchingDataSegmentsThenLinkerFails) {
WhiteBox<NEO::LinkerInput> linkerInput;
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo emptySegmentInfo;
NEO::Linker::PatchableSegment emptyPatchableSegment;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> nonEmptypatchableSegmentData;
nonEmptypatchableSegmentData.resize(64, 8U);
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
NEO::LinkerInput::RelocationInfo relocInfo;
relocInfo.offset = 0U;
relocInfo.symbolName = "aaa";
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.dataRelocations.push_back(relocInfo);
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::Unknown;
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_FALSE(linkResult);
EXPECT_EQ(1U, unresolvedExternals.size());
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
unresolvedExternals.clear();
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
}
TEST(LinkerTests, givenRelocationTypeWithHighPartOfAddressWhenPatchingDataSegmentsThenLinkerFails) {
WhiteBox<NEO::LinkerInput> linkerInput;
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo emptySegmentInfo;
NEO::Linker::PatchableSegment emptyPatchableSegment;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> nonEmptypatchableSegmentData;
nonEmptypatchableSegmentData.resize(64, 8U);
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
NEO::LinkerInput::RelocationInfo relocInfo;
relocInfo.offset = 0U;
relocInfo.symbolName = "aaa";
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::AddressHigh;
linkerInput.dataRelocations.push_back(relocInfo);
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_FALSE(linkResult);
EXPECT_EQ(1U, unresolvedExternals.size());
linkerInput.dataRelocations[0].type = NEO::LinkerInput::RelocationInfo::Type::AddressLow;
unresolvedExternals.clear();
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
}
TEST(LinkerTests, givenValidSymbolsAndRelocationsThenDataSegmentsAreProperlyPatched) {
WhiteBox<NEO::LinkerInput> linkerInput;
NEO::Linker linker(linkerInput);
std::vector<char> globalConstantsSegmentData;
globalConstantsSegmentData.resize(128, 7U);
std::vector<char> globalVariablesSegmentData;
globalVariablesSegmentData.resize(256, 13U);
NEO::Linker::SegmentInfo globalConstantsSegmentInfo, globalVariablesSegmentInfo;
NEO::Linker::UnresolvedExternals unresolvedExternals;
NEO::Linker::PatchableSegment globalConstantsPatchableSegment, globalVariablesPatchableSegment;
globalConstantsSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalConstantsSegmentData.data());
globalConstantsSegmentInfo.segmentSize = globalConstantsSegmentData.size();
globalConstantsPatchableSegment.hostPointer = globalConstantsSegmentData.data();
globalConstantsPatchableSegment.segmentSize = globalConstantsSegmentData.size();
globalVariablesSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalVariablesSegmentData.data());
globalVariablesSegmentInfo.segmentSize = globalVariablesSegmentData.size();
globalVariablesPatchableSegment.hostPointer = globalVariablesSegmentData.data();
globalVariablesPatchableSegment.segmentSize = globalVariablesSegmentData.size();
NEO::LinkerInput::RelocationInfo relocationInfo[5];
// GlobalVar -> GlobalVar
relocationInfo[0].offset = 8U;
relocationInfo[0].relocationSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[0].symbolSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[0].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalConst -> GlobalVar
relocationInfo[1].offset = 24U;
relocationInfo[1].relocationSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[1].symbolSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[1].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalConst -> GlobalConst
relocationInfo[2].offset = 40U;
relocationInfo[2].relocationSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[2].symbolSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[2].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalVar -> GlobalConst
relocationInfo[3].offset = 56U;
relocationInfo[3].relocationSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[3].symbolSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[3].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalVar Low -> GlobalVar
relocationInfo[4].offset = 72;
relocationInfo[4].relocationSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[4].symbolSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[4].type = NEO::LinkerInput::RelocationInfo::Type::AddressLow;
uint32_t initValue = 0;
for (const auto &reloc : relocationInfo) {
linkerInput.addDataRelocationInfo(reloc);
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
if (reloc.type == NEO::LinkerInput::RelocationInfo::Type::Address) {
*reinterpret_cast<uintptr_t *>(ptrOffset(dstRaw, static_cast<size_t>(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data
} else {
*reinterpret_cast<uint32_t *>(ptrOffset(dstRaw, static_cast<size_t>(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data
}
++initValue;
}
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {},
globalVariablesPatchableSegment, globalConstantsPatchableSegment, {},
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
EXPECT_EQ(7U, *reinterpret_cast<uint8_t *>(globalConstantsPatchableSegment.hostPointer));
EXPECT_EQ(13U, *reinterpret_cast<uint8_t *>(globalVariablesPatchableSegment.hostPointer));
initValue = 0;
for (const auto &reloc : relocationInfo) {
void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
uint8_t *src = reinterpret_cast<uint8_t *>(srcRaw);
uint8_t *dst = reinterpret_cast<uint8_t *>(dstRaw);
// make sure no buffer underflow occured
EXPECT_EQ(dst[0], dst[reloc.offset - 1]);
// check patch-incremented value
if (reloc.type == NEO::LinkerInput::RelocationInfo::Type::Address) {
// make sure no buffer overflow occured
EXPECT_EQ(dst[0], dst[reloc.offset + sizeof(uintptr_t)]);
EXPECT_EQ(reinterpret_cast<uintptr_t>(src) + initValue * 4, *reinterpret_cast<uintptr_t *>(dst + reloc.offset)) << initValue;
} else {
// make sure no buffer overflow occured
EXPECT_EQ(dst[0], dst[reloc.offset + sizeof(uint32_t)]);
EXPECT_EQ(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(src)) + initValue * 4, *reinterpret_cast<uint32_t *>(dst + reloc.offset)) << initValue;
}
++initValue;
}
}
TEST(LinkerTests, givenValidSymbolsAndRelocationsWhenPatchin32bitBinaryThenDataSegmentsAreProperlyPatchedWithLowerPartOfTheAddress) {
WhiteBox<NEO::LinkerInput> linkerInput;
linkerInput.setPointerSize(NEO::LinkerInput::Traits::PointerSize::Ptr32bit);
NEO::Linker linker(linkerInput);
std::vector<char> globalConstantsSegmentData;
globalConstantsSegmentData.resize(128, 7U);
std::vector<char> globalVariablesSegmentData;
globalVariablesSegmentData.resize(256, 13U);
NEO::Linker::SegmentInfo globalConstantsSegmentInfo, globalVariablesSegmentInfo;
NEO::Linker::UnresolvedExternals unresolvedExternals;
NEO::Linker::PatchableSegment globalConstantsPatchableSegment, globalVariablesPatchableSegment;
globalConstantsSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalConstantsSegmentData.data());
globalConstantsSegmentInfo.segmentSize = globalConstantsSegmentData.size();
globalConstantsPatchableSegment.hostPointer = globalConstantsSegmentData.data();
globalConstantsPatchableSegment.segmentSize = globalConstantsSegmentData.size();
globalVariablesSegmentInfo.gpuAddress = reinterpret_cast<uintptr_t>(globalVariablesSegmentData.data());
globalVariablesSegmentInfo.segmentSize = globalVariablesSegmentData.size();
globalVariablesPatchableSegment.hostPointer = globalVariablesSegmentData.data();
globalVariablesPatchableSegment.segmentSize = globalVariablesSegmentData.size();
NEO::LinkerInput::RelocationInfo relocationInfo[5];
// GlobalVar -> GlobalVar
relocationInfo[0].offset = 8U;
relocationInfo[0].relocationSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[0].symbolSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[0].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalConst -> GlobalVar
relocationInfo[1].offset = 24U;
relocationInfo[1].relocationSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[1].symbolSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[1].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalConst -> GlobalConst
relocationInfo[2].offset = 40U;
relocationInfo[2].relocationSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[2].symbolSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[2].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalVar -> GlobalConst
relocationInfo[3].offset = 56U;
relocationInfo[3].relocationSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[3].symbolSegment = NEO::SegmentType::GlobalConstants;
relocationInfo[3].type = NEO::LinkerInput::RelocationInfo::Type::Address;
// GlobalVar Low -> GlobalVar
relocationInfo[4].offset = 72;
relocationInfo[4].relocationSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[4].symbolSegment = NEO::SegmentType::GlobalVariables;
relocationInfo[4].type = NEO::LinkerInput::RelocationInfo::Type::AddressLow;
uint32_t initValue = 0;
for (const auto &reloc : relocationInfo) {
linkerInput.addDataRelocationInfo(reloc);
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
*reinterpret_cast<uint32_t *>(ptrOffset(dstRaw, static_cast<size_t>(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data
++initValue;
}
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {},
globalVariablesPatchableSegment, globalConstantsPatchableSegment, {},
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
EXPECT_EQ(7U, *reinterpret_cast<uint8_t *>(globalConstantsPatchableSegment.hostPointer));
EXPECT_EQ(13U, *reinterpret_cast<uint8_t *>(globalVariablesPatchableSegment.hostPointer));
initValue = 0;
for (const auto &reloc : relocationInfo) {
void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer;
uint8_t *src = reinterpret_cast<uint8_t *>(srcRaw);
uint8_t *dst = reinterpret_cast<uint8_t *>(dstRaw);
// make sure no buffer under/overflow occured
EXPECT_EQ(dst[0], dst[reloc.offset - 1]);
EXPECT_EQ(dst[0], dst[reloc.offset + sizeof(uint32_t)]);
// check patch-incremented value
EXPECT_EQ(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(src)) + initValue * 4, *reinterpret_cast<uint32_t *>(dst + reloc.offset)) << initValue;
++initValue;
}
}
TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfDataSegmentsFails) {
WhiteBox<NEO::LinkerInput> linkerInput;
NEO::Linker linker(linkerInput);
NEO::Linker::SegmentInfo emptySegmentInfo;
NEO::Linker::PatchableSegment emptyPatchableSegment;
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<char> nonEmptypatchableSegmentData;
nonEmptypatchableSegmentData.resize(64, 8U);
NEO::Linker::PatchableSegment nonEmptypatchableSegment;
nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data();
nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size();
NEO::LinkerInput::RelocationInfo relocInfo;
relocInfo.offset = 64U;
relocInfo.symbolName = "aaa";
relocInfo.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.dataRelocations.push_back(relocInfo);
linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables;
linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables;
linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true;
bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_FALSE(linkResult);
EXPECT_EQ(1U, unresolvedExternals.size());
linkerInput.dataRelocations[0].offset = 32;
unresolvedExternals.clear();
linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo,
nonEmptypatchableSegment, emptyPatchableSegment, {},
unresolvedExternals);
EXPECT_TRUE(linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
}
TEST(LinkerErrorMessageTests, whenListOfUnresolvedExternalsIsEmptyThenErrorTypeDefaultsToInternalError) {
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<std::string> segmentsNames{"kernel1", "kernel2"};
auto err = NEO::constructLinkerErrorMessage(unresolvedExternals, segmentsNames);
EXPECT_EQ(std::string("Internal linker error"), err);
}
TEST(LinkerErrorMessageTests, givenListOfUnresolvedExternalsThenSymbolNameOrSymbolSegmentTypeGetsEmbededInErrorMessage) {
NEO::Linker::UnresolvedExternals unresolvedExternals;
std::vector<std::string> segmentsNames{"kernel1", "kernel2"};
NEO::Linker::UnresolvedExternal unresolvedExternal = {};
unresolvedExternal.instructionsSegmentId = 1;
unresolvedExternal.internalError = false;
unresolvedExternal.unresolvedRelocation.offset = 64;
unresolvedExternal.unresolvedRelocation.symbolName = "arrayABC";
unresolvedExternal.unresolvedRelocation.relocationSegment = NEO::SegmentType::Instructions;
unresolvedExternals.push_back(unresolvedExternal);
auto err = NEO::constructLinkerErrorMessage(unresolvedExternals, segmentsNames);
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(unresolvedExternal.unresolvedRelocation.symbolName.c_str()));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(segmentsNames[unresolvedExternal.instructionsSegmentId].c_str()));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
EXPECT_THAT(err.c_str(), ::testing::Not(::testing::HasSubstr("internal error")));
unresolvedExternals[0].internalError = true;
err = NEO::constructLinkerErrorMessage(unresolvedExternals, segmentsNames);
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(unresolvedExternal.unresolvedRelocation.symbolName.c_str()));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(segmentsNames[unresolvedExternal.instructionsSegmentId].c_str()));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr("internal linker error"));
err = NEO::constructLinkerErrorMessage(unresolvedExternals, {});
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(unresolvedExternal.unresolvedRelocation.symbolName.c_str()));
EXPECT_THAT(err.c_str(), ::testing::Not(::testing::HasSubstr(segmentsNames[unresolvedExternal.instructionsSegmentId].c_str())));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr("internal linker error"));
unresolvedExternals[0].unresolvedRelocation.relocationSegment = NEO::SegmentType::GlobalConstants;
err = NEO::constructLinkerErrorMessage(unresolvedExternals, {});
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(NEO::asString(NEO::SegmentType::GlobalConstants)));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
unresolvedExternals[0].unresolvedRelocation.relocationSegment = NEO::SegmentType::GlobalVariables;
err = NEO::constructLinkerErrorMessage(unresolvedExternals, {});
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(NEO::asString(NEO::SegmentType::GlobalVariables)));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
unresolvedExternals[0].unresolvedRelocation.relocationSegment = NEO::SegmentType::Unknown;
err = NEO::constructLinkerErrorMessage(unresolvedExternals, {});
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(NEO::asString(NEO::SegmentType::Unknown)));
EXPECT_THAT(err.c_str(), ::testing::HasSubstr(std::to_string(unresolvedExternal.unresolvedRelocation.offset).c_str()));
}

View File

@@ -1,13 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_DEBUG_SETTINGS_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debug_settings_manager_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/debug_settings_manager_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_DEBUG_SETTINGS_TESTS ${NEO_CORE_DEBUG_SETTINGS_TESTS})

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/helpers/file_io.h"
#include "shared/source/utilities/directory.h"
#include <map>
using namespace NEO;
using namespace std;
#undef DECLARE_DEBUG_VARIABLE
class TestDebugFlagsChecker {
public:
static bool isEqual(int32_t returnedValue, bool defaultValue) {
if (returnedValue == 0) {
return !defaultValue;
} else {
return defaultValue;
}
}
static bool isEqual(int32_t returnedValue, int32_t defaultValue) {
return returnedValue == defaultValue;
}
static bool isEqual(string returnedValue, string defaultValue) {
return returnedValue == defaultValue;
}
};
template <DebugFunctionalityLevel DebugLevel>
class TestDebugSettingsManager : public DebugSettingsManager<DebugLevel> {
public:
using DebugSettingsManager<DebugLevel>::dumpFlags;
using DebugSettingsManager<DebugLevel>::settingsDumpFileName;
TestDebugSettingsManager() : DebugSettingsManager<DebugLevel>("") {}
SettingsReader *getSettingsReader() {
return DebugSettingsManager<DebugLevel>::readerImpl.get();
}
};
using FullyEnabledTestDebugManager = TestDebugSettingsManager<DebugFunctionalityLevel::Full>;
using FullyDisabledTestDebugManager = TestDebugSettingsManager<DebugFunctionalityLevel::None>;

View File

@@ -1,146 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/memory_manager/graphics_allocation.h"
#include "helpers/debug_manager_state_restore.h"
#include "utilities/base_object_utils.h"
#include "shared/source/utilities/debug_file_reader.h"
#include "test.h"
#include "debug_settings_manager_fixture.h"
#include <cstdio>
#include <memory>
#include <sstream>
#include <string>
TEST(DebugSettingsManager, WithDebugFunctionality) {
FullyEnabledTestDebugManager debugManager;
EXPECT_FALSE(debugManager.disabled());
EXPECT_EQ(nullptr, debugManager.injectFcn);
}
TEST(DebugSettingsManager, WithDebugFunctionalityHasSettingsReader) {
FullyEnabledTestDebugManager debugManager;
// SettingsReader created
EXPECT_NE(nullptr, debugManager.getSettingsReader());
}
TEST(DebugSettingsManager, WithoutDebugFunctionality) {
FullyDisabledTestDebugManager debugManager;
// Should not be enabled without debug functionality
EXPECT_TRUE(debugManager.disabled());
// SettingsReader not created
EXPECT_EQ(nullptr, debugManager.getSettingsReader());
// debug variables / flags set to default
#define DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description) \
{ \
bool isEqual = TestDebugFlagsChecker::isEqual(debugManager.flags.variableName.get(), defaultValue); \
EXPECT_TRUE(isEqual); \
}
#include "debug_variables.inl"
#undef DECLARE_DEBUG_VARIABLE
}
TEST(DebugSettingsManager, whenDebugManagerIsDisabledThenDebugFunctionalityIsNotAvailableAtCompileTime) {
TestDebugSettingsManager<DebugFunctionalityLevel::None> debugManager;
static_assert(debugManager.disabled(), "");
static_assert(false == debugManager.registryReadAvailable(), "");
}
TEST(DebugSettingsManager, whenDebugManagerIsFullyEnabledThenAllDebugFunctionalityIsAvailableAtCompileTime) {
TestDebugSettingsManager<DebugFunctionalityLevel::Full> debugManager;
static_assert(false == debugManager.disabled(), "");
static_assert(debugManager.registryReadAvailable(), "");
}
TEST(DebugSettingsManager, whenOnlyRegKeysAreEnabledThenAllOtherDebugFunctionalityIsNotAvailableAtCompileTime) {
TestDebugSettingsManager<DebugFunctionalityLevel::RegKeys> debugManager;
static_assert(false == debugManager.disabled(), "");
static_assert(debugManager.registryReadAvailable(), "");
}
TEST(DebugSettingsManager, givenTwoPossibleVariantsOfHardwareInfoOverrideStringThenOutputStringIsTheSame) {
FullyEnabledTestDebugManager debugManager;
std::string hwInfoConfig;
// Set HardwareInfoOverride as regular string (i.e. as in Windows Registry)
std::string str1 = "1x4x8";
debugManager.flags.HardwareInfoOverride.set(str1);
debugManager.getHardwareInfoOverride(hwInfoConfig);
EXPECT_EQ(str1, hwInfoConfig);
// Set HardwareInfoOverride as quoted string (i.e. as in igdrcl.config file)
std::string str2 = "\"1x4x8\"";
debugManager.flags.HardwareInfoOverride.set(str2);
hwInfoConfig = debugManager.flags.HardwareInfoOverride.get();
EXPECT_EQ(str2, hwInfoConfig);
debugManager.getHardwareInfoOverride(hwInfoConfig);
EXPECT_EQ(str1, hwInfoConfig);
}
TEST(DebugSettingsManager, givenStringDebugVariableWhenLongValueExeedingSmallStringOptimizationIsAssignedThenMemoryLeakIsNotReported) {
DebugManagerStateRestore debugManagerStateRestore;
DebugManager.flags.AUBDumpCaptureFileName.set("ThisIsVeryLongStringValueThatExceedSizeSpecifiedBySmallStringOptimizationAndCausesInternalStringBufferResize");
}
TEST(DebugSettingsManager, givenNullAsReaderImplInDebugManagerWhenSettingReaderImplThenItsSetProperly) {
FullyDisabledTestDebugManager debugManager;
auto readerImpl = SettingsReader::create("");
debugManager.setReaderImpl(readerImpl);
EXPECT_EQ(readerImpl, debugManager.getReaderImpl());
}
TEST(DebugSettingsManager, givenReaderImplInDebugManagerWhenSettingDifferentReaderImplThenItsSetProperly) {
FullyDisabledTestDebugManager debugManager;
auto readerImpl = SettingsReader::create("");
debugManager.setReaderImpl(readerImpl);
auto readerImpl2 = SettingsReader::create("");
debugManager.setReaderImpl(readerImpl2);
EXPECT_EQ(readerImpl2, debugManager.getReaderImpl());
}
TEST(DebugSettingsManager, givenPrintDebugSettingsEnabledWhenCallingDumpFlagsThenFlagsAreWrittenToDumpFile) {
testing::internal::CaptureStdout();
FullyEnabledTestDebugManager debugManager;
debugManager.flags.PrintDebugSettings.set(true);
debugManager.flags.LoopAtPlatformInitialize.set(true);
debugManager.flags.Enable64kbpages.set(1);
debugManager.flags.TbxServer.set("192.168.0.1");
// Clear dump files and generate new
std::remove(FullyEnabledTestDebugManager::settingsDumpFileName);
debugManager.dumpFlags();
// Validate allSettingsDumpFile
SettingsFileReader allSettingsReader{FullyEnabledTestDebugManager::settingsDumpFileName};
#define DECLARE_DEBUG_VARIABLE(dataType, varName, defaultValue, description) \
EXPECT_EQ(debugManager.flags.varName.get(), allSettingsReader.getSetting(#varName, defaultValue));
#include "debug_variables.inl"
#undef DECLARE_DEBUG_VARIABLE
std::remove(FullyEnabledTestDebugManager::settingsDumpFileName);
std::string output = testing::internal::GetCapturedStdout();
ASSERT_NE(0u, output.size());
EXPECT_NE(std::string::npos, output.find("Non-default value of debug variable: TbxServer = 192.168.0.1"));
EXPECT_NE(std::string::npos, output.find("Non-default value of debug variable: LoopAtPlatformInitialize = 1"));
EXPECT_NE(std::string::npos, output.find("Non-default value of debug variable: PrintDebugSettings = 1"));
EXPECT_NE(std::string::npos, output.find("Non-default value of debug variable: Enable64kbpages = 1"));
}
TEST(AllocationInfoLogging, givenBaseGraphicsAllocationWhenGettingImplementationSpecificAllocationInfoThenReturnEmptyInfoString) {
GraphicsAllocation graphicsAllocation(0, GraphicsAllocation::AllocationType::UNKNOWN, nullptr, 0ull, 0ull, 0, MemoryPool::MemoryNull);
EXPECT_STREQ(graphicsAllocation.getAllocationInfoString().c_str(), "");
}

View File

@@ -1,23 +0,0 @@
#
# 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}/ar/ar_decoder_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ar/ar_encoder_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/elf/elf_decoder_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/elf/elf_encoder_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_format_ar_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_format_ocl_elf_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_format_patchtokens_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_formats_tests.cpp
${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})

View File

@@ -1,426 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/ar/ar_decoder.h"
#include "test.h"
using namespace NEO::Ar;
TEST(ArDecoderIsAr, WhenNotArThenReturnsFalse) {
ArrayRef<const uint8_t> empty;
EXPECT_FALSE(isAr(empty));
const uint8_t notAr[] = "aaaaa";
EXPECT_FALSE(isAr(notAr));
}
TEST(ArDecoderIsAr, WhenValidArThenReturnsTrue) {
auto emptyAr = ArrayRef<const uint8_t>::fromAny(arMagic.begin(), arMagic.size());
EXPECT_TRUE(isAr(emptyAr));
}
TEST(ArDecoderReadDecimal, WhenNullOrSpaceIsEncounteredThenParsingStops) {
const char spaceDelimited[] = "213 123";
const char nullTerminateDelimited[] = {'4', '5', '6', '\0', '7', '8', '9'};
EXPECT_EQ(213U, readDecimal<sizeof(spaceDelimited)>(spaceDelimited));
EXPECT_EQ(456U, readDecimal<sizeof(nullTerminateDelimited)>(nullTerminateDelimited));
}
TEST(ArDecoderReadDecimal, WhenNullOrSpaceIsNotEncounteredThenParsesTillTheEnd) {
const char noteDelimited[] = "213123";
EXPECT_EQ(2131U, readDecimal<4>(noteDelimited));
}
TEST(ArDecoderIsStringPadding, GivenCharacterThenReturnsTrueOnlyIfArStringPaddingCharacter) {
EXPECT_TRUE(isStringPadding(' '));
EXPECT_TRUE(isStringPadding('/'));
EXPECT_TRUE(isStringPadding('\0'));
EXPECT_FALSE(isStringPadding('\t'));
EXPECT_FALSE(isStringPadding('\r'));
EXPECT_FALSE(isStringPadding('\n'));
EXPECT_FALSE(isStringPadding('0'));
EXPECT_FALSE(isStringPadding('a'));
}
TEST(ArDecoderReadUnpaddedString, GivenPaddedStringTheReturnsUnpaddedStringPart) {
const char paddedString[] = "abcd/ \0";
auto unpadded = readUnpaddedString<sizeof(paddedString)>(paddedString);
EXPECT_EQ(paddedString, unpadded.begin());
EXPECT_EQ(4U, unpadded.size());
}
TEST(ArDecoderReadUnpaddedString, GivenEmptyPaddedStringTheReturnsEmptyString) {
const char paddedString[] = "// \0";
auto unpadded = readUnpaddedString<sizeof(paddedString)>(paddedString);
EXPECT_TRUE(unpadded.empty());
}
TEST(ArDecoderReadUnpaddedString, GivenUnpaddedStringTheReturnsDataInBounds) {
const char paddedString[] = "abcdefgh";
auto unpadded = readUnpaddedString<3>(paddedString);
EXPECT_EQ(paddedString, unpadded.begin());
EXPECT_EQ(3U, unpadded.size());
}
TEST(ArDecoderReadLongFileName, GivenOffsetThenParsesCorrectString) {
const char names[] = "abcde/fgh/ij";
auto name0 = readLongFileName(names, 0U);
auto name1 = readLongFileName(names, 6U);
auto name2 = readLongFileName(names, 10U);
auto name3 = readLongFileName(names, 40U);
EXPECT_EQ(names, name0.begin());
EXPECT_EQ(5U, name0.size());
EXPECT_EQ(names + 6U, name1.begin());
EXPECT_EQ(3U, name1.size());
EXPECT_EQ(names + 10U, name2.begin());
EXPECT_EQ(2U, name2.size());
EXPECT_TRUE(name3.empty());
}
TEST(ArDecoderDecodeAr, GivenNotArThenFailDecoding) {
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr({}, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, ar.magic);
EXPECT_EQ(0U, ar.files.size());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Not an AR archive - mismatched file signature", decodeErrors.c_str());
}
TEST(ArDecoderDecodeAr, GivenValidArThenDecodingSucceeds) {
const uint8_t data[8] = "1234567";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = 'a';
fileEntry0.identifier[1] = '/';
fileEntry0.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data, data + sizeof(data));
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<const char *>(arStorage.data()), ar.magic);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(ar.longFileNamesEntry.fileData.empty());
EXPECT_TRUE(ar.longFileNamesEntry.fileName.empty());
ASSERT_EQ(1U, ar.files.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size()), ar.files[0].fullHeader);
EXPECT_EQ("a", ar.files[0].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader), ar.files[0].fileData.begin());
EXPECT_EQ(8U, ar.files[0].fileData.size());
}
TEST(ArDecoderDecodeAr, GivenArWhenFileEntryHeaderHasEmptyIdentifierThenDecodingFails) {
const uint8_t data[8] = "1234567";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntry0;
fileEntry0.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data, data + sizeof(data));
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, ar.magic);
EXPECT_EQ(0U, ar.files.size());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Corrupt AR archive - file entry does not have identifier : '/ '", decodeErrors.c_str());
}
TEST(ArDecoderDecodeAr, GivenInvalidFileEntryHeaderTrailingMagicThenDecodingSucceedsButWarningIsEmitted) {
const uint8_t data[8] = "1234567";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = 'a';
fileEntry0.identifier[1] = '/';
fileEntry0.fileSizeInBytes[0] = '8';
fileEntry0.trailingMagic[0] = 'a';
fileEntry0.trailingMagic[1] = 'a';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data, data + sizeof(data));
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<const char *>(arStorage.data()), ar.magic);
EXPECT_TRUE(decodeErrors.empty());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(ar.longFileNamesEntry.fileData.empty());
EXPECT_TRUE(ar.longFileNamesEntry.fileName.empty());
ASSERT_EQ(1U, ar.files.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size()), ar.files[0].fullHeader);
EXPECT_EQ("a", ar.files[0].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader), ar.files[0].fileData.begin());
EXPECT_EQ(8U, ar.files[0].fileData.size());
EXPECT_FALSE(decodeWarnings.empty());
EXPECT_STREQ("File entry header with identifier 'a/ ' has invalid header trailing string", decodeWarnings.c_str());
}
TEST(ArDecoderDecodeAr, GivenOutOfBoundsFileEntryDataThenFailDecoding) {
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = 'a';
fileEntry0.identifier[1] = '/';
fileEntry0.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, ar.magic);
EXPECT_EQ(0U, ar.files.size());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Corrupt AR archive - out of bounds data of file entry with idenfitier 'a/ '", decodeErrors.c_str());
}
TEST(ArDecoderDecodeAr, GivenValidTwoFilesEntriesWith2byteAlignedDataThenDecodingSucceeds) {
const uint8_t data0[8] = "1234567";
const uint8_t data1[16] = "9ABCDEFGHIJKLMN";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = 'a';
fileEntry0.identifier[1] = '/';
fileEntry0.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data0, data0 + sizeof(data0));
ArFileEntryHeader fileEntry1;
fileEntry1.identifier[0] = 'b';
fileEntry1.identifier[1] = '/';
fileEntry1.fileSizeInBytes[0] = '1';
fileEntry1.fileSizeInBytes[1] = '6';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry1), reinterpret_cast<const uint8_t *>(&fileEntry1 + 1));
arStorage.insert(arStorage.end(), data1, data1 + sizeof(data1));
ASSERT_EQ(arMagic.size() + 2 * sizeof(ArFileEntryHeader) + sizeof(data0) + sizeof(data1), arStorage.size());
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<const char *>(arStorage.data()), ar.magic);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(ar.longFileNamesEntry.fileData.empty());
EXPECT_TRUE(ar.longFileNamesEntry.fileName.empty());
ASSERT_EQ(2U, ar.files.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size()), ar.files[0].fullHeader);
EXPECT_EQ("a", ar.files[0].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader), ar.files[0].fileData.begin());
EXPECT_EQ(8U, ar.files[0].fileData.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + sizeof(data0)), ar.files[1].fullHeader);
EXPECT_EQ("b", ar.files[1].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + sizeof(data0) + sizeof(ArFileEntryHeader), ar.files[1].fileData.begin());
EXPECT_EQ(16U, ar.files[1].fileData.size());
}
TEST(ArDecoderDecodeAr, GivenValidTwoFileEntriesWith2byteUnalignedDataAndPaddingThenImplicitPaddingIsTakenIntoAccount) {
const uint8_t data0[7] = "123456";
const uint8_t data1[15] = "9ABCDEFGHIJKLM";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = 'a';
fileEntry0.identifier[1] = '/';
fileEntry0.fileSizeInBytes[0] = '7';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data0, data0 + sizeof(data0));
arStorage.push_back('\0'); // implicit 2-byte alignment padding
ArFileEntryHeader fileEntry1;
fileEntry1.identifier[0] = 'b';
fileEntry1.identifier[1] = '/';
fileEntry1.fileSizeInBytes[0] = '1';
fileEntry1.fileSizeInBytes[1] = '5';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry1), reinterpret_cast<const uint8_t *>(&fileEntry1 + 1));
arStorage.insert(arStorage.end(), data1, data1 + sizeof(data1));
arStorage.push_back('\0'); // implicit 2-byte alignment padding
ASSERT_EQ(arMagic.size() + 2 * sizeof(ArFileEntryHeader) + sizeof(data0) + sizeof(data1) + 2, arStorage.size());
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<const char *>(arStorage.data()), ar.magic);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(ar.longFileNamesEntry.fileData.empty());
EXPECT_TRUE(ar.longFileNamesEntry.fileName.empty());
ASSERT_EQ(2U, ar.files.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size()), ar.files[0].fullHeader);
EXPECT_EQ("a", ar.files[0].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader), ar.files[0].fileData.begin());
EXPECT_EQ(7U, ar.files[0].fileData.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + sizeof(data0) + 1), ar.files[1].fullHeader);
EXPECT_EQ("b", ar.files[1].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + sizeof(data0) + 1 + sizeof(ArFileEntryHeader), ar.files[1].fileData.begin());
EXPECT_EQ(15U, ar.files[1].fileData.size());
}
TEST(ArDecoderDecodeAr, GivenSpecialFileWithLongFilenamesThenSpecialFileIsProperlyRecognized) {
const uint8_t names[8] = "123456/";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntrySpecial;
fileEntrySpecial.identifier[0] = '/';
fileEntrySpecial.identifier[1] = '/';
fileEntrySpecial.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntrySpecial), reinterpret_cast<const uint8_t *>(&fileEntrySpecial + 1));
arStorage.insert(arStorage.end(), names, names + sizeof(names));
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<const char *>(arStorage.data()), ar.magic);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size()), ar.longFileNamesEntry.fullHeader);
EXPECT_EQ("//", ar.longFileNamesEntry.fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader), ar.longFileNamesEntry.fileData.begin());
EXPECT_EQ(8U, ar.longFileNamesEntry.fileData.size());
EXPECT_EQ(0U, ar.files.size());
}
TEST(ArDecoderDecodeAr, GivenFilesWithLongFilenamesThenNamesAreProperlyDecoded) {
const uint8_t longNames[] = "my_identifier_is_longer_than_16_charters/my_identifier_is_even_longer_than_previous_one/";
size_t longNamesLen = sizeof(longNames) - 1U; // 88, ignore nullterminate
const uint8_t data0[8] = "1234567";
const uint8_t data1[16] = "9ABCDEFGHIJKLMN";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntrySpecial;
fileEntrySpecial.identifier[0] = '/';
fileEntrySpecial.identifier[1] = '/';
fileEntrySpecial.fileSizeInBytes[0] = '8';
fileEntrySpecial.fileSizeInBytes[1] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntrySpecial), reinterpret_cast<const uint8_t *>(&fileEntrySpecial + 1));
arStorage.insert(arStorage.end(), longNames, longNames + longNamesLen);
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = '/';
fileEntry0.identifier[1] = '0';
fileEntry0.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data0, data0 + sizeof(data0));
ArFileEntryHeader fileEntry1;
fileEntry1.identifier[0] = '/';
fileEntry1.identifier[1] = '4';
fileEntry1.identifier[2] = '1';
fileEntry1.fileSizeInBytes[0] = '1';
fileEntry1.fileSizeInBytes[1] = '6';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry1), reinterpret_cast<const uint8_t *>(&fileEntry1 + 1));
arStorage.insert(arStorage.end(), data1, data1 + sizeof(data1));
ASSERT_EQ(arMagic.size() + 3 * sizeof(ArFileEntryHeader) + longNamesLen + sizeof(data0) + sizeof(data1), arStorage.size());
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<const char *>(arStorage.data()), ar.magic);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size()), ar.longFileNamesEntry.fullHeader);
EXPECT_EQ("//", ar.longFileNamesEntry.fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader), ar.longFileNamesEntry.fileData.begin());
EXPECT_EQ(longNamesLen, ar.longFileNamesEntry.fileData.size());
ASSERT_EQ(2U, ar.files.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + longNamesLen), ar.files[0].fullHeader);
EXPECT_EQ("my_identifier_is_longer_than_16_charters", ar.files[0].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + longNamesLen + sizeof(ArFileEntryHeader), ar.files[0].fileData.begin());
EXPECT_EQ(8U, ar.files[0].fileData.size());
EXPECT_EQ(reinterpret_cast<ArFileEntryHeader *>(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + longNamesLen + sizeof(ArFileEntryHeader) + sizeof(data0)), ar.files[1].fullHeader);
EXPECT_EQ("my_identifier_is_even_longer_than_previous_one", ar.files[1].fileName);
EXPECT_EQ(arStorage.data() + arMagic.size() + sizeof(ArFileEntryHeader) + longNamesLen + sizeof(ArFileEntryHeader) + sizeof(data0) + sizeof(ArFileEntryHeader), ar.files[1].fileData.begin());
EXPECT_EQ(16U, ar.files[1].fileData.size());
}
TEST(ArDecoderDecodeAr, GivenFilesWithLongFilenamesWhenFileNamesSpecialEntryNotPresentThenDecodingFails) {
const uint8_t data0[8] = "1234567";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = '/';
fileEntry0.identifier[1] = '0';
fileEntry0.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data0, data0 + sizeof(data0));
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, ar.magic);
EXPECT_EQ(0U, ar.files.size());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Corrupt AR archive - long file name entry has broken identifier : '/0 '", decodeErrors.c_str());
}
TEST(ArDecoderDecodeAr, GivenFilesWithLongFilenamesWhenLongNameIsOutOfBoundsThenDecodingFails) {
const uint8_t longNames[] = "my_identifier_is_longer_than_16_charters/my_identifier_is_even_longer_than_previous_one/";
size_t longNamesLen = sizeof(longNames) - 1U; // 88, ignore nullterminate
const uint8_t data0[8] = "1234567";
std::vector<uint8_t> arStorage;
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ArFileEntryHeader fileEntrySpecial;
fileEntrySpecial.identifier[0] = '/';
fileEntrySpecial.identifier[1] = '/';
fileEntrySpecial.fileSizeInBytes[0] = '8';
fileEntrySpecial.fileSizeInBytes[1] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntrySpecial), reinterpret_cast<const uint8_t *>(&fileEntrySpecial + 1));
arStorage.insert(arStorage.end(), longNames, longNames + longNamesLen);
ArFileEntryHeader fileEntry0;
fileEntry0.identifier[0] = '/';
fileEntry0.identifier[1] = '1';
fileEntry0.identifier[2] = '0';
fileEntry0.identifier[3] = '0';
fileEntry0.fileSizeInBytes[0] = '8';
arStorage.insert(arStorage.end(), reinterpret_cast<const uint8_t *>(&fileEntry0), reinterpret_cast<const uint8_t *>(&fileEntry0 + 1));
arStorage.insert(arStorage.end(), data0, data0 + sizeof(data0));
std::string decodeErrors;
std::string decodeWarnings;
auto ar = decodeAr(arStorage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, ar.magic);
EXPECT_EQ(0U, ar.files.size());
EXPECT_EQ(nullptr, ar.longFileNamesEntry.fullHeader);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Corrupt AR archive - long file name entry has broken identifier : '/100 '", decodeErrors.c_str());
}

View File

@@ -1,148 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/compiler_interface/intermediate_representations.h"
#include "shared/source/device_binary_format/ar/ar_encoder.h"
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/helpers/string.h"
#include "test.h"
#include <cstring>
using namespace NEO::Ar;
TEST(ArFileEntryHeader, GivenDefaultArFileEntryHeaderThenSectionAreProperlyPopulated) {
ArFileEntryHeader header = {};
EXPECT_EQ(ConstStringRef("/ ", 16), ConstStringRef(header.identifier));
EXPECT_EQ(ConstStringRef("0 ", 12), ConstStringRef(header.fileModificationTimestamp));
EXPECT_EQ(ConstStringRef("0 ", 6), ConstStringRef(header.ownerId));
EXPECT_EQ(ConstStringRef("0 ", 6), ConstStringRef(header.groupId));
EXPECT_EQ(ConstStringRef("644 ", 8), ConstStringRef(header.fileMode));
EXPECT_EQ(ConstStringRef("0 ", 10), ConstStringRef(header.fileSizeInBytes));
EXPECT_EQ(ConstStringRef("\x60\x0A", 2), ConstStringRef(header.trailingMagic));
}
TEST(ArEncoder, GivenTooLongIdentifierThenAppendingFileFails) {
const uint8_t fileData[] = "2357111317192329";
ArEncoder encoder;
EXPECT_EQ(nullptr, encoder.appendFileEntry("my_identifier_is_longer_than_16_charters", fileData));
}
TEST(ArEncoder, GivenEmptyIdentifierThenAppendingFileFails) {
const uint8_t fileData[] = "2357111317192329";
ArEncoder encoder;
EXPECT_EQ(nullptr, encoder.appendFileEntry("", fileData));
}
TEST(ArEncoder, GivenEmptyArThenEncodedFileConsistsOfOnlyArMagic) {
ArEncoder encoder;
auto arData = encoder.encode();
EXPECT_EQ(arMagic.size(), arData.size());
EXPECT_TRUE(NEO::hasSameMagic(arMagic, arData));
}
TEST(ArEncoder, GivenValidFileEntriesThenAppendingFileSucceeds) {
std::string fileName = "file1.txt";
const uint8_t fileData[18] = "23571113171923293";
ArEncoder encoder;
auto returnedSection = encoder.appendFileEntry(fileName, fileData);
ASSERT_NE(nullptr, returnedSection);
ArFileEntryHeader expectedSection;
memcpy_s(expectedSection.identifier, sizeof(expectedSection.identifier), fileName.c_str(), fileName.size());
expectedSection.identifier[fileName.size()] = '/';
expectedSection.fileSizeInBytes[0] = '1';
expectedSection.fileSizeInBytes[1] = '8';
EXPECT_EQ(0, memcmp(returnedSection, &expectedSection, sizeof(expectedSection)));
auto arData = encoder.encode();
EXPECT_TRUE(NEO::hasSameMagic(arMagic, arData));
ASSERT_EQ(arData.size(), arMagic.size() + sizeof(fileData) + sizeof(ArFileEntryHeader));
ArFileEntryHeader *file0 = reinterpret_cast<ArFileEntryHeader *>(arData.data() + arMagic.size());
auto file0Data = arData.data() + arMagic.size() + sizeof(ArFileEntryHeader);
EXPECT_EQ(0, memcmp(file0, &expectedSection, sizeof(expectedSection)));
EXPECT_EQ(0, memcmp(file0Data, fileData, sizeof(fileData)));
}
TEST(ArEncoder, GivenValidTwoFileEntriesWith2byteUnalignedDataThenPaddingIsImplicitlyAdded) {
std::string fileName0 = "a";
std::string fileName1 = "b";
const uint8_t data0[7] = "123456";
const uint8_t data1[16] = "9ABCDEFGHIJKLMN";
ArEncoder encoder;
auto returnedSection = encoder.appendFileEntry(fileName0, data0);
ASSERT_NE(nullptr, returnedSection);
ArFileEntryHeader expectedSection0;
expectedSection0.identifier[0] = 'a';
expectedSection0.identifier[1] = '/';
expectedSection0.fileSizeInBytes[0] = '7';
EXPECT_EQ(0, memcmp(returnedSection, &expectedSection0, sizeof(expectedSection0)));
returnedSection = encoder.appendFileEntry(fileName1, data1);
ASSERT_NE(nullptr, returnedSection);
ArFileEntryHeader expectedSection1;
expectedSection1.identifier[0] = 'b';
expectedSection1.identifier[1] = '/';
expectedSection1.fileSizeInBytes[0] = '1';
expectedSection1.fileSizeInBytes[1] = '6';
EXPECT_EQ(0, memcmp(returnedSection, &expectedSection1, sizeof(expectedSection1)));
auto arData = encoder.encode();
EXPECT_TRUE(NEO::hasSameMagic(arMagic, arData));
ASSERT_EQ(arData.size(), arMagic.size() + sizeof(data0) + sizeof(data1) + 2 * sizeof(ArFileEntryHeader) + 1);
ArFileEntryHeader *file0 = reinterpret_cast<ArFileEntryHeader *>(arData.data() + arMagic.size());
auto file0Data = arData.data() + arMagic.size() + sizeof(ArFileEntryHeader);
ArFileEntryHeader *file1 = reinterpret_cast<ArFileEntryHeader *>(arData.data() + arMagic.size() + sizeof(data0) + sizeof(ArFileEntryHeader) + 1);
auto file1Data = arData.data() + arMagic.size() + sizeof(data0) + 2 * sizeof(ArFileEntryHeader) + 1;
EXPECT_EQ(0, memcmp(file0, &expectedSection0, sizeof(expectedSection0)));
EXPECT_EQ(0, memcmp(file0Data, data0, sizeof(data0)));
EXPECT_EQ(0, memcmp(file1, &expectedSection1, sizeof(expectedSection1)));
EXPECT_EQ(0, memcmp(file1Data, data1, sizeof(data1)));
}
TEST(ArEncoder, GivenValidTwoFileEntriesWhen8BytePaddingIsRequestedThenPaddingFileEntriesAreAddedWhenNeeded) {
std::string fileName0 = "a";
std::string fileName1 = "b";
std::string fileName2 = "c";
const uint8_t data0[4] = "123"; // will require padding before
const uint8_t data1[8] = "9ABCDEF"; // won't require padding before
const uint8_t data2[16] = "9ABCDEF"; // will require padding before
ArEncoder encoder(true);
encoder.appendFileEntry(fileName0, data0);
encoder.appendFileEntry(fileName1, data1);
encoder.appendFileEntry(fileName2, data2);
auto arData = encoder.encode();
EXPECT_TRUE(NEO::hasSameMagic(arMagic, arData));
ASSERT_EQ(arData.size(), arMagic.size() + sizeof(data0) + sizeof(data1) + sizeof(data2) + 5 * sizeof(ArFileEntryHeader) + 16);
auto files = arData.data() + arMagic.size();
ArFileEntryHeader *pad0 = reinterpret_cast<ArFileEntryHeader *>(files);
auto pad0Data = reinterpret_cast<uint8_t *>(pad0) + sizeof(ArFileEntryHeader);
ArFileEntryHeader *file0 = reinterpret_cast<ArFileEntryHeader *>(pad0Data + 8);
auto file0Data = reinterpret_cast<uint8_t *>(file0) + sizeof(ArFileEntryHeader);
ArFileEntryHeader *file1 = reinterpret_cast<ArFileEntryHeader *>(file0Data + sizeof(data0));
auto file1Data = reinterpret_cast<uint8_t *>(file1) + sizeof(ArFileEntryHeader);
ArFileEntryHeader *pad1 = reinterpret_cast<ArFileEntryHeader *>(file1Data + sizeof(data1));
auto pad1Data = reinterpret_cast<uint8_t *>(pad1) + sizeof(ArFileEntryHeader);
ArFileEntryHeader *file2 = reinterpret_cast<ArFileEntryHeader *>(pad1Data + 8);
auto file2Data = reinterpret_cast<uint8_t *>(file2) + sizeof(ArFileEntryHeader);
EXPECT_EQ(0U, ptrDiff(file0Data, arData.data()) % 8);
EXPECT_EQ(0U, ptrDiff(file1Data, arData.data()) % 8);
EXPECT_EQ(0U, ptrDiff(file2Data, arData.data()) % 8);
EXPECT_EQ(0, memcmp(file0Data, data0, sizeof(data0)));
EXPECT_EQ(0, memcmp(file1Data, data1, sizeof(data1)));
EXPECT_EQ(0, memcmp(file2Data, data2, sizeof(data2)));
}

View File

@@ -1,183 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/ar/ar.h"
#include "shared/source/device_binary_format/ar/ar_decoder.h"
#include "shared/source/device_binary_format/ar/ar_encoder.h"
#include "shared/source/device_binary_format/device_binary_formats.h"
#include "shared/source/helpers/hw_info.h"
#include "device_binary_format/patchtokens_tests.h"
#include "test.h"
TEST(IsDeviceBinaryFormatAr, GivenValidBinaryReturnTrue) {
auto emptyArchive = ArrayRef<const uint8_t>::fromAny(NEO::Ar::arMagic.begin(), NEO::Ar::arMagic.size());
EXPECT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Archive>(emptyArchive));
}
TEST(IsDeviceBinaryFormatAr, GivenInvalidBinaryReturnTrue) {
const uint8_t binary[] = "not_ar";
EXPECT_FALSE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Archive>(binary));
}
TEST(UnpackSingleDeviceBinaryAr, WhenFailedToDecodeArThenUnpackingFails) {
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Archive>({}, "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty()) << unpackWarnings;
EXPECT_STREQ("Not an AR archive - mismatched file signature", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryAr, WhenFailedToFindMatchingBinariesThenUnpackingFails) {
auto emptyArchive = ArrayRef<const uint8_t>::fromAny(NEO::Ar::arMagic.begin(), NEO::Ar::arMagic.size());
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Archive>(emptyArchive, "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty()) << unpackWarnings;
EXPECT_STREQ("Couldn't find matching binary in AR archive", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryAr, WhenMultipleBinariesMatchedThenChooseBestMatch) {
PatchTokensTestData::ValidEmptyProgram programTokens;
NEO::Ar::ArEncoder encoder;
std::string requiredProduct = NEO::hardwarePrefix[productFamily];
std::string requiredStepping = std::to_string(programTokens.header->SteppingId);
std::string requiredPointerSize = (programTokens.header->GPUPointerSizeInBytes == 4) ? "32" : "64";
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "." + requiredProduct, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "." + requiredProduct + "." + requiredStepping, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "unk." + requiredStepping, programTokens.storage));
NEO::TargetDevice target;
target.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
target.stepping = programTokens.header->SteppingId;
target.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
auto arData = encoder.encode();
std::string unpackErrors;
std::string unpackWarnings;
auto unpacked = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Archive>(arData, requiredProduct, target, unpackErrors, unpackWarnings);
EXPECT_TRUE(unpackErrors.empty()) << unpackErrors;
EXPECT_TRUE(unpackWarnings.empty()) << unpackWarnings;
unpackErrors.clear();
unpackWarnings.clear();
auto decodedAr = NEO::Ar::decodeAr(arData, unpackErrors, unpackWarnings);
EXPECT_NE(nullptr, decodedAr.magic);
ASSERT_EQ(4U, decodedAr.files.size());
EXPECT_EQ(unpacked.deviceBinary.begin(), decodedAr.files[2].fileData.begin());
EXPECT_EQ(unpacked.deviceBinary.size(), decodedAr.files[2].fileData.size());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpacked.format);
}
TEST(UnpackSingleDeviceBinaryAr, WhenBestMatchIsntFullMatchThenChooseBestMatchButEmitWarnings) {
PatchTokensTestData::ValidEmptyProgram programTokens;
NEO::Ar::ArEncoder encoder;
std::string requiredProduct = NEO::hardwarePrefix[productFamily];
std::string requiredStepping = std::to_string(programTokens.header->SteppingId);
std::string requiredPointerSize = (programTokens.header->GPUPointerSizeInBytes == 4) ? "32" : "64";
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "." + requiredProduct, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "unk." + requiredStepping, programTokens.storage));
NEO::TargetDevice target;
target.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
target.stepping = programTokens.header->SteppingId;
target.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
auto arData = encoder.encode();
std::string unpackErrors;
std::string unpackWarnings;
auto unpacked = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Archive>(arData, requiredProduct, target, unpackErrors, unpackWarnings);
EXPECT_TRUE(unpackErrors.empty()) << unpackErrors;
EXPECT_FALSE(unpackWarnings.empty());
EXPECT_STREQ("Couldn't find perfectly matched binary (right stepping) in AR, using best usable", unpackWarnings.c_str());
unpackErrors.clear();
unpackWarnings.clear();
auto decodedAr = NEO::Ar::decodeAr(arData, unpackErrors, unpackWarnings);
EXPECT_NE(nullptr, decodedAr.magic);
ASSERT_EQ(3U, decodedAr.files.size());
EXPECT_EQ(unpacked.deviceBinary.begin(), decodedAr.files[1].fileData.begin());
EXPECT_EQ(unpacked.deviceBinary.size(), decodedAr.files[1].fileData.size());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpacked.format);
}
TEST(UnpackSingleDeviceBinaryAr, WhenFailedToUnpackBestMatchThenTryUnpackingAnyUsable) {
PatchTokensTestData::ValidEmptyProgram programTokens;
PatchTokensTestData::ValidEmptyProgram programTokensWrongTokenVersion;
programTokensWrongTokenVersion.headerMutable->Version -= 1;
NEO::Ar::ArEncoder encoder;
std::string requiredProduct = NEO::hardwarePrefix[productFamily];
std::string requiredStepping = std::to_string(programTokens.header->SteppingId);
std::string requiredPointerSize = (programTokens.header->GPUPointerSizeInBytes == 4) ? "32" : "64";
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "." + requiredProduct, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "." + requiredProduct + "." + requiredStepping, programTokensWrongTokenVersion.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "unk." + requiredStepping, programTokens.storage));
NEO::TargetDevice target;
target.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
target.stepping = programTokens.header->SteppingId;
target.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
auto arData = encoder.encode();
std::string unpackErrors;
std::string unpackWarnings;
auto unpacked = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Archive>(arData, requiredProduct, target, unpackErrors, unpackWarnings);
EXPECT_TRUE(unpackErrors.empty()) << unpackErrors;
EXPECT_FALSE(unpackWarnings.empty());
EXPECT_STREQ("Couldn't find perfectly matched binary (right stepping) in AR, using best usable", unpackWarnings.c_str());
unpackErrors.clear();
unpackWarnings.clear();
auto decodedAr = NEO::Ar::decodeAr(arData, unpackErrors, unpackWarnings);
EXPECT_NE(nullptr, decodedAr.magic);
ASSERT_EQ(4U, decodedAr.files.size());
EXPECT_EQ(unpacked.deviceBinary.begin(), decodedAr.files[1].fileData.begin());
EXPECT_EQ(unpacked.deviceBinary.size(), decodedAr.files[1].fileData.size());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpacked.format);
}
TEST(UnpackSingleDeviceBinaryAr, WhenCouldFindBinaryWithRightPointerSizeThenUnpackingFails) {
PatchTokensTestData::ValidEmptyProgram programTokens;
NEO::Ar::ArEncoder encoder;
std::string requiredProduct = NEO::hardwarePrefix[productFamily];
std::string requiredStepping = std::to_string(programTokens.header->SteppingId);
std::string requiredPointerSize = (programTokens.header->GPUPointerSizeInBytes == 4) ? "32" : "64";
std::string wrongPointerSize = (programTokens.header->GPUPointerSizeInBytes == 8) ? "32" : "64";
ASSERT_TRUE(encoder.appendFileEntry(wrongPointerSize, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(wrongPointerSize + "." + requiredProduct, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(wrongPointerSize + "." + requiredProduct + "." + requiredStepping, programTokens.storage));
ASSERT_TRUE(encoder.appendFileEntry(requiredPointerSize + "unk." + requiredStepping, programTokens.storage));
NEO::TargetDevice target;
target.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
target.stepping = programTokens.header->SteppingId;
target.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
auto arData = encoder.encode();
std::string unpackErrors;
std::string unpackWarnings;
auto unpacked = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Archive>(arData, requiredProduct, target, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpacked.format);
EXPECT_TRUE(unpacked.deviceBinary.empty());
EXPECT_TRUE(unpacked.debugData.empty());
EXPECT_TRUE(unpacked.intermediateRepresentation.empty());
EXPECT_TRUE(unpacked.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty()) << unpackWarnings;
EXPECT_STREQ("Couldn't find matching binary in AR archive", unpackErrors.c_str());
}

View File

@@ -1,397 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/compiler_interface/intermediate_representations.h"
#include "shared/source/device_binary_format/device_binary_formats.h"
#include "shared/source/device_binary_format/elf/elf_decoder.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/source/device_binary_format/elf/ocl_elf.h"
#include "shared/source/program/program_info.h"
#include "device_binary_format/patchtokens_tests.h"
#include "test.h"
#include <algorithm>
#include <tuple>
TEST(IsDeviceBinaryFormatOclElf, GivenElfThenReturnsTrueIfProperElfFileTypeDetected) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc64;
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
EXPECT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode()));
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_OBJECTS;
EXPECT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode()));
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_LIBRARY;
EXPECT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode()));
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_DEBUG;
EXPECT_FALSE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode()));
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_SOURCE;
EXPECT_FALSE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode()));
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_NONE;
EXPECT_FALSE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode()));
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_EXEC;
EXPECT_FALSE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode()));
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_32> elfEnc32;
elfEnc32.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
EXPECT_FALSE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(elfEnc32.encode()));
}
TEST(UnpackSingleDeviceBinaryOclElf, WhenFailedToDecodeElfThenUnpackingFails) {
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>({}, "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_STREQ("Invalid or missing ELF header", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryOclElf, GivenNotOclElfThenUnpackingFails) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc64;
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode(), "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_STREQ("Not OCL ELF file type", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryOclElf, GivenOclElfThenSetsProperOutputFormat) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc64;
std::string unpackErrors;
std::string unpackWarnings;
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode(), "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_TRUE(unpackErrors.empty());
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_LIBRARY;
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_SPIRV, NEO::Elf::SectionNamesOpenCl::spirvObject, ArrayRef<const uint8_t>::fromAny(NEO::spirvMagic.begin(), NEO::spirvMagic.size()));
auto elfData = elfEnc64.encode();
unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfData, "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::OclLibrary, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_TRUE(unpackErrors.empty());
EXPECT_FALSE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(NEO::isSpirVBitcode(unpackResult.intermediateRepresentation));
EXPECT_EQ(NEO::spirvMagic.size(), unpackResult.intermediateRepresentation.size());
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_OBJECTS;
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_LLVM_BINARY, NEO::Elf::SectionNamesOpenCl::llvmObject, ArrayRef<const uint8_t>::fromAny(NEO::llvmBcMagic.begin(), NEO::llvmBcMagic.size()));
elfData = elfEnc64.encode();
unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfData, "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::OclCompiledObject, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_TRUE(unpackErrors.empty());
EXPECT_FALSE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(NEO::isLlvmBitcode(unpackResult.intermediateRepresentation));
EXPECT_EQ(NEO::llvmBcMagic.size(), unpackResult.intermediateRepresentation.size());
}
TEST(UnpackSingleDeviceBinaryOclElf, GivenValidOclElfExecutableThenReadsAllSectionProperly) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
NEO::TargetDevice targetDevice;
targetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(patchtokensProgram.header->Device);
targetDevice.stepping = patchtokensProgram.header->SteppingId;
targetDevice.maxPointerSizeInBytes = patchtokensProgram.header->GPUPointerSizeInBytes;
const uint8_t intermediateRepresentation[] = "235711";
const uint8_t debugData[] = "313739";
std::string buildOptions = "buildOpts";
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc64;
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
std::string unpackErrors;
std::string unpackWarnings;
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, NEO::Elf::SectionNamesOpenCl::deviceBinary, patchtokensProgram.storage);
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_OPTIONS, NEO::Elf::SectionNamesOpenCl::buildOptions, buildOptions);
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_DEV_DEBUG, NEO::Elf::SectionNamesOpenCl::buildOptions, debugData);
{
auto encWithLlvm = elfEnc64;
encWithLlvm.appendSection(NEO::Elf::SHT_OPENCL_LLVM_BINARY, NEO::Elf::SectionNamesOpenCl::llvmObject, intermediateRepresentation);
auto elfData = encWithLlvm.encode();
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfData, "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_TRUE(unpackErrors.empty());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpackResult.format);
ASSERT_EQ(patchtokensProgram.storage.size(), unpackResult.deviceBinary.size());
ASSERT_EQ(sizeof(debugData), unpackResult.debugData.size());
ASSERT_EQ(buildOptions.size() + 1, unpackResult.buildOptions.size());
ASSERT_EQ(sizeof(intermediateRepresentation), unpackResult.intermediateRepresentation.size());
EXPECT_EQ(0, memcmp(patchtokensProgram.storage.data(), unpackResult.deviceBinary.begin(), unpackResult.deviceBinary.size()));
EXPECT_STREQ(buildOptions.c_str(), unpackResult.buildOptions.begin());
EXPECT_EQ(0, memcmp(debugData, unpackResult.debugData.begin(), unpackResult.debugData.size()));
EXPECT_EQ(0, memcmp(intermediateRepresentation, unpackResult.intermediateRepresentation.begin(), unpackResult.intermediateRepresentation.size()));
}
{
auto encWithSpirV = elfEnc64;
encWithSpirV.appendSection(NEO::Elf::SHT_OPENCL_SPIRV, NEO::Elf::SectionNamesOpenCl::spirvObject, intermediateRepresentation);
auto elfData = encWithSpirV.encode();
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfData, "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_TRUE(unpackErrors.empty());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpackResult.format);
ASSERT_EQ(patchtokensProgram.storage.size(), unpackResult.deviceBinary.size());
ASSERT_EQ(sizeof(debugData), unpackResult.debugData.size());
ASSERT_EQ(buildOptions.size() + 1, unpackResult.buildOptions.size());
ASSERT_EQ(sizeof(intermediateRepresentation), unpackResult.intermediateRepresentation.size());
EXPECT_EQ(0, memcmp(patchtokensProgram.storage.data(), unpackResult.deviceBinary.begin(), unpackResult.deviceBinary.size()));
EXPECT_STREQ(buildOptions.c_str(), unpackResult.buildOptions.begin());
EXPECT_EQ(0, memcmp(debugData, unpackResult.debugData.begin(), unpackResult.debugData.size()));
EXPECT_EQ(0, memcmp(intermediateRepresentation, unpackResult.intermediateRepresentation.begin(), unpackResult.intermediateRepresentation.size()));
}
}
TEST(UnpackSingleDeviceBinaryOclElf, GivenOclElfExecutableWithUnhandledSectionThenUnpackingFails) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc64;
std::string unpackErrors;
std::string unpackWarnings;
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
elfEnc64.appendSection(NEO::Elf::SHT_NOBITS, "my_data", {});
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode(), "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_STREQ("Unhandled ELF section", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryOclElf, GivenOclElfExecutableWhenPatchtokensBinaryIsBrokenThenReadsAllSectionProperly) {
const uint8_t intermediateRepresentation[] = "235711";
const uint8_t debugData[] = "313739";
const uint8_t deviceBinary[] = "not_patchtokens";
std::string buildOptions = "buildOpts";
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc64;
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
std::string unpackErrors;
std::string unpackWarnings;
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, NEO::Elf::SectionNamesOpenCl::deviceBinary, deviceBinary);
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_OPTIONS, NEO::Elf::SectionNamesOpenCl::buildOptions, buildOptions);
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_DEV_DEBUG, NEO::Elf::SectionNamesOpenCl::buildOptions, debugData);
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_SPIRV, NEO::Elf::SectionNamesOpenCl::spirvObject, intermediateRepresentation);
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(elfEnc64.encode(), "", {}, unpackErrors, unpackWarnings);
EXPECT_FALSE(unpackErrors.empty());
EXPECT_STREQ("Invalid program header", unpackErrors.c_str());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_FALSE(unpackResult.intermediateRepresentation.empty());
EXPECT_FALSE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
}
TEST(DecodeSingleDeviceBinaryOclElf, WhenUsedAsSingleDeviceBinaryThenDecodingFails) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
;
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc64;
elfEnc64.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
elfEnc64.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, NEO::Elf::SectionNamesOpenCl::deviceBinary, patchtokensProgram.storage);
auto elfData = elfEnc64.encode();
NEO::TargetDevice targetDevice;
targetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(patchtokensProgram.header->Device);
targetDevice.stepping = patchtokensProgram.header->SteppingId;
targetDevice.maxPointerSizeInBytes = patchtokensProgram.header->GPUPointerSizeInBytes;
NEO::SingleDeviceBinary deviceBinary;
deviceBinary.targetDevice = targetDevice;
deviceBinary.deviceBinary = elfData;
std::string unpackErrors;
std::string unpackWarnings;
NEO::ProgramInfo programInfo;
NEO::DecodeError error = NEO::decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(programInfo, deviceBinary, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, error);
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_FALSE(unpackErrors.empty());
EXPECT_STREQ("Device binary format is packed", unpackErrors.c_str());
}
TEST(PackDeviceBinaryOclElf, WhenPackingEmptyDataThenEmptyOclElfIsEmitted) {
NEO::SingleDeviceBinary singleBinary;
std::string packErrors;
std::string packWarnings;
auto packedData = NEO::packDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(singleBinary, packErrors, packWarnings);
EXPECT_TRUE(packWarnings.empty());
EXPECT_TRUE(packErrors.empty());
ASSERT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(packedData));
std::string decodeElfErrors;
std::string decodeElfWarnings;
auto elf = NEO::Elf::decodeElf(packedData, decodeElfErrors, decodeElfWarnings);
EXPECT_TRUE(decodeElfErrors.empty());
EXPECT_TRUE(decodeElfWarnings.empty());
ASSERT_NE(nullptr, elf.elfFileHeader);
EXPECT_EQ(NEO::Elf::ET_OPENCL_EXECUTABLE, elf.elfFileHeader->type);
EXPECT_EQ(0U, elf.elfFileHeader->shNum);
}
TEST(PackDeviceBinaryOclElf, WhenPackingBinaryWithUnknownIntermediateRepresentationThenFail) {
const uint8_t intermediateRepresentation[] = "not_llvm_and_not_spirv";
NEO::SingleDeviceBinary singleBinary;
singleBinary.intermediateRepresentation = intermediateRepresentation;
std::string packErrors;
std::string packWarnings;
auto packedData = NEO::packDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(singleBinary, packErrors, packWarnings);
EXPECT_TRUE(packedData.empty());
EXPECT_TRUE(packWarnings.empty());
EXPECT_FALSE(packErrors.empty());
EXPECT_STREQ("Unknown intermediate representation format", packErrors.c_str());
}
TEST(PackDeviceBinaryOclElf, WhenPackingBinaryWitIntermediateRepresentationThenChoosesProperSectionBasedOnMagic) {
using namespace NEO::Elf;
auto spirV = NEO::spirvMagic;
auto llvmBc = NEO::llvmBcMagic;
NEO::SingleDeviceBinary singleBinary;
{
singleBinary.intermediateRepresentation = ArrayRef<const uint8_t>::fromAny(spirV.begin(), spirV.size());
std::string packErrors;
std::string packWarnings;
auto packedData = NEO::packDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(singleBinary, packErrors, packWarnings);
EXPECT_FALSE(packedData.empty());
EXPECT_TRUE(packWarnings.empty());
EXPECT_TRUE(packErrors.empty());
ASSERT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(packedData));
std::string decodeElfErrors;
std::string decodeElfWarnings;
auto elf = NEO::Elf::decodeElf(packedData, decodeElfErrors, decodeElfWarnings);
EXPECT_TRUE(decodeElfErrors.empty());
EXPECT_TRUE(decodeElfWarnings.empty());
ASSERT_NE(nullptr, elf.elfFileHeader);
EXPECT_EQ(NEO::Elf::ET_OPENCL_EXECUTABLE, elf.elfFileHeader->type);
EXPECT_EQ(3U, elf.elfFileHeader->shNum);
auto spirVSection = std::find_if(elf.sectionHeaders.begin(), elf.sectionHeaders.end(),
[](const Elf<>::SectionHeaderAndData &section) { return section.header->type == NEO::Elf::SHT_OPENCL_SPIRV; });
ASSERT_NE(nullptr, spirVSection);
ASSERT_EQ(spirV.size(), spirVSection->data.size());
EXPECT_EQ(0, memcmp(spirV.begin(), spirVSection->data.begin(), spirV.size()));
}
{
singleBinary.intermediateRepresentation = ArrayRef<const uint8_t>::fromAny(llvmBc.begin(), llvmBc.size());
std::string packErrors;
std::string packWarnings;
auto packedData = NEO::packDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(singleBinary, packErrors, packWarnings);
EXPECT_FALSE(packedData.empty());
EXPECT_TRUE(packWarnings.empty());
EXPECT_TRUE(packErrors.empty());
ASSERT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(packedData));
std::string decodeElfErrors;
std::string decodeElfWarnings;
auto elf = NEO::Elf::decodeElf(packedData, decodeElfErrors, decodeElfWarnings);
EXPECT_TRUE(decodeElfErrors.empty());
EXPECT_TRUE(decodeElfWarnings.empty());
ASSERT_NE(nullptr, elf.elfFileHeader);
EXPECT_EQ(NEO::Elf::ET_OPENCL_EXECUTABLE, elf.elfFileHeader->type);
EXPECT_EQ(3U, elf.elfFileHeader->shNum);
auto llvmSection = std::find_if(elf.sectionHeaders.begin(), elf.sectionHeaders.end(),
[](const Elf<>::SectionHeaderAndData &section) { return section.header->type == NEO::Elf::SHT_OPENCL_LLVM_BINARY; });
ASSERT_NE(nullptr, llvmSection);
ASSERT_EQ(llvmBc.size(), llvmSection->data.size());
EXPECT_EQ(0, memcmp(llvmBc.begin(), llvmSection->data.begin(), llvmBc.size()));
}
}
TEST(PackDeviceBinaryOclElf, WhenPackingBinaryThenSectionsAreProperlyPopulated) {
using namespace NEO::Elf;
NEO::SingleDeviceBinary singleBinary;
auto spirV = NEO::spirvMagic;
const uint8_t debugData[] = "313739";
const uint8_t deviceBinary[] = "23571113";
std::string buildOptions = "buildOpts";
singleBinary.intermediateRepresentation = ArrayRef<const uint8_t>::fromAny(spirV.begin(), spirV.size());
singleBinary.debugData = debugData;
singleBinary.deviceBinary = deviceBinary;
singleBinary.buildOptions = buildOptions;
std::string packErrors;
std::string packWarnings;
auto packedData = NEO::packDeviceBinary<NEO::DeviceBinaryFormat::OclElf>(singleBinary, packErrors, packWarnings);
EXPECT_TRUE(packErrors.empty());
EXPECT_TRUE(packWarnings.empty());
std::string decodeElfErrors;
std::string decodeElfWarnings;
auto elf = NEO::Elf::decodeElf(packedData, decodeElfErrors, decodeElfWarnings);
EXPECT_TRUE(decodeElfErrors.empty());
EXPECT_TRUE(decodeElfWarnings.empty());
ASSERT_NE(nullptr, elf.elfFileHeader);
auto spirvSection = std::find_if(elf.sectionHeaders.begin(), elf.sectionHeaders.end(),
[](const Elf<>::SectionHeaderAndData &section) { return section.header->type == NEO::Elf::SHT_OPENCL_SPIRV; });
auto deviceBinarySection = std::find_if(elf.sectionHeaders.begin(), elf.sectionHeaders.end(),
[](const Elf<>::SectionHeaderAndData &section) { return section.header->type == NEO::Elf::SHT_OPENCL_DEV_BINARY; });
auto deviceDebugSection = std::find_if(elf.sectionHeaders.begin(), elf.sectionHeaders.end(),
[](const Elf<>::SectionHeaderAndData &section) { return section.header->type == NEO::Elf::SHT_OPENCL_DEV_DEBUG; });
auto buildOptionsSection = std::find_if(elf.sectionHeaders.begin(), elf.sectionHeaders.end(),
[](const Elf<>::SectionHeaderAndData &section) { return section.header->type == NEO::Elf::SHT_OPENCL_OPTIONS; });
ASSERT_NE(nullptr, spirvSection);
ASSERT_EQ(spirV.size(), spirvSection->data.size());
EXPECT_EQ(0, memcmp(spirV.begin(), spirvSection->data.begin(), spirV.size()));
ASSERT_NE(nullptr, deviceBinarySection);
ASSERT_EQ(sizeof(deviceBinary), deviceBinarySection->data.size());
EXPECT_EQ(0, memcmp(deviceBinary, deviceBinarySection->data.begin(), sizeof(deviceBinary)));
ASSERT_NE(nullptr, deviceDebugSection);
ASSERT_EQ(sizeof(debugData), deviceDebugSection->data.size());
EXPECT_EQ(0, memcmp(debugData, deviceDebugSection->data.begin(), sizeof(debugData)));
ASSERT_NE(nullptr, buildOptionsSection);
ASSERT_EQ(buildOptions.size(), buildOptionsSection->data.size());
EXPECT_EQ(0, memcmp(buildOptions.c_str(), buildOptionsSection->data.begin(), buildOptions.size()));
}

View File

@@ -1,155 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/device_binary_formats.h"
#include "shared/source/program/program_info.h"
#include "device_binary_format/patchtokens_tests.h"
#include "test.h"
TEST(IsDeviceBinaryFormatPatchtokens, GivenValidBinaryReturnTrue) {
PatchTokensTestData::ValidProgramWithKernel programTokens;
EXPECT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Patchtokens>(programTokens.storage));
}
TEST(IsDeviceBinaryFormatPatchtokens, GivenInvalidBinaryReturnTrue) {
const uint8_t binary[] = "not_patchtokens";
EXPECT_FALSE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Patchtokens>(binary));
}
TEST(UnpackSingleDeviceBinaryPatchtokens, WhenFailedToDecodeHeaderThenUnpackingFails) {
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Patchtokens>({}, "", {}, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_STREQ("Invalid program header", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryPatchtokens, WhenValidBinaryAndMatchedWithRequestedTargetDeviceThenReturnSelf) {
PatchTokensTestData::ValidProgramWithKernel programTokens;
NEO::TargetDevice targetDevice;
targetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
targetDevice.stepping = programTokens.header->SteppingId;
targetDevice.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Patchtokens>(programTokens.storage, "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpackResult.format);
EXPECT_EQ(targetDevice.coreFamily, unpackResult.targetDevice.coreFamily);
EXPECT_EQ(targetDevice.stepping, unpackResult.targetDevice.stepping);
EXPECT_EQ(targetDevice.maxPointerSizeInBytes, unpackResult.targetDevice.maxPointerSizeInBytes);
EXPECT_FALSE(unpackResult.deviceBinary.empty());
EXPECT_EQ(programTokens.storage.data(), unpackResult.deviceBinary.begin());
EXPECT_EQ(programTokens.storage.size(), unpackResult.deviceBinary.size());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_TRUE(unpackErrors.empty());
}
TEST(UnpackSingleDeviceBinaryPatchtokens, WhenValidBinaryForDifferentCoreFamilyDeviceThenUnpackingFails) {
PatchTokensTestData::ValidProgramWithKernel programTokens;
NEO::TargetDevice targetDevice;
targetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device + 1);
targetDevice.stepping = programTokens.header->SteppingId;
targetDevice.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Patchtokens>(programTokens.storage, "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_EQ(IGFX_UNKNOWN_CORE, unpackResult.targetDevice.coreFamily);
EXPECT_EQ(0U, unpackResult.targetDevice.stepping);
EXPECT_EQ(4U, unpackResult.targetDevice.maxPointerSizeInBytes);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_FALSE(unpackErrors.empty());
EXPECT_STREQ("Unhandled target device", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryPatchtokens, WhenValidBinaryWithUnsupportedPatchTokensVerionThenUnpackingFails) {
PatchTokensTestData::ValidProgramWithKernel programTokens;
programTokens.headerMutable->Version += 1;
NEO::TargetDevice targetDevice;
targetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
targetDevice.stepping = programTokens.header->SteppingId;
targetDevice.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Patchtokens>(programTokens.storage, "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_EQ(IGFX_UNKNOWN_CORE, unpackResult.targetDevice.coreFamily);
EXPECT_EQ(0U, unpackResult.targetDevice.stepping);
EXPECT_EQ(4U, unpackResult.targetDevice.maxPointerSizeInBytes);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_FALSE(unpackErrors.empty());
EXPECT_STREQ("Unhandled target device", unpackErrors.c_str());
}
TEST(UnpackSingleDeviceBinaryPatchtokens, WhenValidBinaryWithUnsupportedPointerSizeThenUnpackingFails) {
PatchTokensTestData::ValidProgramWithKernel programTokens;
programTokens.headerMutable->GPUPointerSizeInBytes = 8U;
NEO::TargetDevice targetDevice;
targetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
targetDevice.stepping = programTokens.header->SteppingId;
targetDevice.maxPointerSizeInBytes = 4U;
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Patchtokens>(programTokens.storage, "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpackResult.format);
EXPECT_EQ(IGFX_UNKNOWN_CORE, unpackResult.targetDevice.coreFamily);
EXPECT_EQ(0U, unpackResult.targetDevice.stepping);
EXPECT_EQ(4U, unpackResult.targetDevice.maxPointerSizeInBytes);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_TRUE(unpackResult.debugData.empty());
EXPECT_TRUE(unpackResult.intermediateRepresentation.empty());
EXPECT_TRUE(unpackResult.buildOptions.empty());
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_FALSE(unpackErrors.empty());
EXPECT_STREQ("Unhandled target device", unpackErrors.c_str());
}
TEST(DecodeSingleDeviceBinaryPatchtokens, GivenInvalidBinaryThenReturnError) {
NEO::ProgramInfo programInfo;
NEO::SingleDeviceBinary singleBinary;
std::string decodeErrors;
std::string decodeWarnings;
auto error = NEO::decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Patchtokens>(programInfo, singleBinary, decodeErrors, decodeWarnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, error);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("ProgramFromPatchtokens wasn't successfully decoded", decodeErrors.c_str());
}
TEST(DecodeSingleDeviceBinaryPatchtokens, GivenValidBinaryThenOutputIsProperlyPopulated) {
PatchTokensTestData::ValidProgramWithKernel programTokens;
NEO::ProgramInfo programInfo;
NEO::SingleDeviceBinary singleBinary;
singleBinary.deviceBinary = programTokens.storage;
std::string decodeErrors;
std::string decodeWarnings;
auto error = NEO::decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Patchtokens>(programInfo, singleBinary, decodeErrors, decodeWarnings);
EXPECT_EQ(NEO::DecodeError::Success, error);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_TRUE(decodeErrors.empty());
ASSERT_EQ(1U, programInfo.kernelInfos.size());
}

View File

@@ -1,275 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/ar/ar_encoder.h"
#include "shared/source/device_binary_format/device_binary_formats.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/source/device_binary_format/elf/ocl_elf.h"
#include "shared/source/program/program_info.h"
#include "device_binary_format/patchtokens_tests.h"
#include "test.h"
TEST(DecodeError, WhenStringRepresentationIsNeededThenAsStringEncodesProperly) {
EXPECT_STREQ("decoded successfully", NEO::asString(NEO::DecodeError::Success));
EXPECT_STREQ("in undefined status", NEO::asString(NEO::DecodeError::Undefined));
EXPECT_STREQ("with invalid binary", NEO::asString(NEO::DecodeError::InvalidBinary));
EXPECT_STREQ("with unhandled binary", NEO::asString(NEO::DecodeError::UnhandledBinary));
}
TEST(IsAnyDeviceBinaryFormat, GivenNoneOfKnownFormatsThenReturnsFalse) {
const uint8_t data[] = "none of known formats";
EXPECT_FALSE(NEO::isAnyDeviceBinaryFormat(data));
}
TEST(IsAnyDeviceBinaryFormat, GivenPatchTokensFormatThenReturnsTrue) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
EXPECT_TRUE(NEO::isAnyDeviceBinaryFormat(patchtokensProgram.storage));
}
TEST(IsAnyDeviceBinaryFormat, GivenOclElfFormatThenReturnsTrue) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc;
elfEnc.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
EXPECT_TRUE(NEO::isAnyDeviceBinaryFormat(elfEnc.encode()));
}
TEST(IsAnyDeviceBinaryFormat, GivenArFormatThenReturnsTrue) {
EXPECT_TRUE(NEO::isAnyDeviceBinaryFormat(ArrayRef<const uint8_t>::fromAny(NEO::Ar::arMagic.begin(), NEO::Ar::arMagic.size())));
}
TEST(UnpackSingleDeviceBinary, GivenUnknownBinaryThenReturnError) {
const uint8_t data[] = "none of known formats";
ConstStringRef requestedProductAbbreviation = "unk";
NEO::TargetDevice requestedTargetDevice;
std::string outErrors;
std::string outWarnings;
auto unpacked = NEO::unpackSingleDeviceBinary(data, requestedProductAbbreviation, requestedTargetDevice, outErrors, outWarnings);
EXPECT_TRUE(unpacked.buildOptions.empty());
EXPECT_TRUE(unpacked.debugData.empty());
EXPECT_TRUE(unpacked.deviceBinary.empty());
EXPECT_TRUE(unpacked.intermediateRepresentation.empty());
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, unpacked.format);
EXPECT_EQ(0U, unpacked.targetDevice.coreFamily);
EXPECT_EQ(0U, unpacked.targetDevice.stepping);
EXPECT_EQ(4U, unpacked.targetDevice.maxPointerSizeInBytes);
EXPECT_TRUE(outWarnings.empty());
EXPECT_STREQ("Unknown format", outErrors.c_str());
}
TEST(UnpackSingleDeviceBinary, GivenPatchtoknsBinaryThenReturnSelf) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
ConstStringRef requestedProductAbbreviation = "unk";
NEO::TargetDevice requestedTargetDevice;
requestedTargetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(patchtokensProgram.header->Device);
requestedTargetDevice.stepping = patchtokensProgram.header->SteppingId;
requestedTargetDevice.maxPointerSizeInBytes = patchtokensProgram.header->GPUPointerSizeInBytes;
std::string outErrors;
std::string outWarnings;
auto unpacked = NEO::unpackSingleDeviceBinary(patchtokensProgram.storage, requestedProductAbbreviation, requestedTargetDevice, outErrors, outWarnings);
EXPECT_TRUE(unpacked.buildOptions.empty());
EXPECT_TRUE(unpacked.debugData.empty());
EXPECT_FALSE(unpacked.deviceBinary.empty());
EXPECT_EQ(patchtokensProgram.storage.data(), unpacked.deviceBinary.begin());
EXPECT_EQ(patchtokensProgram.storage.size(), unpacked.deviceBinary.size());
EXPECT_TRUE(unpacked.intermediateRepresentation.empty());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpacked.format);
EXPECT_EQ(requestedTargetDevice.coreFamily, unpacked.targetDevice.coreFamily);
EXPECT_EQ(requestedTargetDevice.stepping, unpacked.targetDevice.stepping);
EXPECT_EQ(patchtokensProgram.header->GPUPointerSizeInBytes, unpacked.targetDevice.maxPointerSizeInBytes);
EXPECT_TRUE(outWarnings.empty());
EXPECT_TRUE(outErrors.empty());
}
TEST(UnpackSingleDeviceBinary, GivenOclElfBinaryThenReturnPatchtokensBinary) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc;
elfEnc.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
elfEnc.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, NEO::Elf::SectionNamesOpenCl::deviceBinary, patchtokensProgram.storage);
ConstStringRef requestedProductAbbreviation = "unk";
NEO::TargetDevice requestedTargetDevice;
requestedTargetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(patchtokensProgram.header->Device);
requestedTargetDevice.stepping = patchtokensProgram.header->SteppingId;
requestedTargetDevice.maxPointerSizeInBytes = patchtokensProgram.header->GPUPointerSizeInBytes;
std::string outErrors;
std::string outWarnings;
auto elfData = elfEnc.encode();
auto unpacked = NEO::unpackSingleDeviceBinary(elfData, requestedProductAbbreviation, requestedTargetDevice, outErrors, outWarnings);
EXPECT_TRUE(unpacked.buildOptions.empty());
EXPECT_TRUE(unpacked.debugData.empty());
EXPECT_TRUE(unpacked.intermediateRepresentation.empty());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpacked.format);
EXPECT_EQ(requestedTargetDevice.coreFamily, unpacked.targetDevice.coreFamily);
EXPECT_EQ(requestedTargetDevice.stepping, unpacked.targetDevice.stepping);
EXPECT_EQ(patchtokensProgram.header->GPUPointerSizeInBytes, unpacked.targetDevice.maxPointerSizeInBytes);
EXPECT_TRUE(outWarnings.empty());
EXPECT_TRUE(outErrors.empty());
EXPECT_FALSE(unpacked.deviceBinary.empty());
ASSERT_EQ(patchtokensProgram.storage.size(), unpacked.deviceBinary.size());
EXPECT_EQ(0, memcmp(patchtokensProgram.storage.data(), unpacked.deviceBinary.begin(), unpacked.deviceBinary.size()));
}
TEST(UnpackSingleDeviceBinary, GivenArBinaryWithOclElfThenReturnPatchtokensBinary) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc;
elfEnc.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
elfEnc.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, NEO::Elf::SectionNamesOpenCl::deviceBinary, patchtokensProgram.storage);
NEO::TargetDevice requestedTargetDevice;
requestedTargetDevice.coreFamily = static_cast<GFXCORE_FAMILY>(patchtokensProgram.header->Device);
requestedTargetDevice.stepping = patchtokensProgram.header->SteppingId;
requestedTargetDevice.maxPointerSizeInBytes = patchtokensProgram.header->GPUPointerSizeInBytes;
std::string outErrors;
std::string outWarnings;
auto elfData = elfEnc.encode();
std::string requiredProduct = NEO::hardwarePrefix[productFamily];
std::string requiredStepping = std::to_string(patchtokensProgram.header->SteppingId);
std::string requiredPointerSize = (patchtokensProgram.header->GPUPointerSizeInBytes == 4) ? "32" : "64";
NEO::Ar::ArEncoder arEnc(true);
ASSERT_TRUE(arEnc.appendFileEntry(requiredPointerSize + "." + requiredProduct + "." + requiredStepping, elfData));
auto arData = arEnc.encode();
auto unpacked = NEO::unpackSingleDeviceBinary(arData, requiredProduct, requestedTargetDevice, outErrors, outWarnings);
EXPECT_TRUE(unpacked.buildOptions.empty());
EXPECT_TRUE(unpacked.debugData.empty());
EXPECT_TRUE(unpacked.intermediateRepresentation.empty());
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, unpacked.format);
EXPECT_EQ(requestedTargetDevice.coreFamily, unpacked.targetDevice.coreFamily);
EXPECT_EQ(requestedTargetDevice.stepping, unpacked.targetDevice.stepping);
EXPECT_EQ(patchtokensProgram.header->GPUPointerSizeInBytes, unpacked.targetDevice.maxPointerSizeInBytes);
EXPECT_TRUE(outWarnings.empty()) << outWarnings;
EXPECT_TRUE(outErrors.empty()) << outErrors;
EXPECT_FALSE(unpacked.deviceBinary.empty());
ASSERT_EQ(patchtokensProgram.storage.size(), unpacked.deviceBinary.size());
EXPECT_EQ(0, memcmp(patchtokensProgram.storage.data(), unpacked.deviceBinary.begin(), unpacked.deviceBinary.size()));
}
TEST(IsAnyPackedDeviceBinaryFormat, GivenUnknownFormatThenReturnFalse) {
const uint8_t data[] = "none of known formats";
EXPECT_FALSE(NEO::isAnyPackedDeviceBinaryFormat(data));
}
TEST(IsAnyPackedDeviceBinaryFormat, GivenPatchTokensFormatThenReturnsFalse) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
EXPECT_FALSE(NEO::isAnyPackedDeviceBinaryFormat(patchtokensProgram.storage));
}
TEST(IsAnyPackedDeviceBinaryFormat, GivenOclElfFormatThenReturnsTrue) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc;
elfEnc.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
EXPECT_TRUE(NEO::isAnyPackedDeviceBinaryFormat(elfEnc.encode()));
}
TEST(IsAnyPackedDeviceBinaryFormat, GivenArFormatThenReturnsTrue) {
EXPECT_TRUE(NEO::isAnyPackedDeviceBinaryFormat(ArrayRef<const uint8_t>::fromAny(NEO::Ar::arMagic.begin(), NEO::Ar::arMagic.size())));
}
TEST(IsAnySingleDeviceBinaryFormat, GivenUnknownFormatThenReturnFalse) {
const uint8_t data[] = "none of known formats";
EXPECT_FALSE(NEO::isAnySingleDeviceBinaryFormat(data));
}
TEST(IsAnySingleDeviceBinaryFormat, GivenPatchTokensFormatThenReturnsTrue) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
EXPECT_TRUE(NEO::isAnySingleDeviceBinaryFormat(patchtokensProgram.storage));
}
TEST(IsAnySingleDeviceBinaryFormat, GivenOclElfFormatThenReturnsFalse) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc;
elfEnc.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
EXPECT_FALSE(NEO::isAnySingleDeviceBinaryFormat(elfEnc.encode()));
}
TEST(IsAnySingleDeviceBinaryFormat, GivenArFormatThenReturnsFalse) {
EXPECT_FALSE(NEO::isAnySingleDeviceBinaryFormat(ArrayRef<const uint8_t>::fromAny(NEO::Ar::arMagic.begin(), NEO::Ar::arMagic.size())));
}
TEST(DecodeSingleDeviceBinary, GivenUnknownFormatThenReturnFalse) {
const uint8_t data[] = "none of known formats";
NEO::ProgramInfo programInfo;
std::string decodeErrors;
std::string decodeWarnings;
NEO::SingleDeviceBinary bin;
bin.deviceBinary = data;
NEO::DecodeError status;
NEO::DeviceBinaryFormat format;
std::tie(status, format) = NEO::decodeSingleDeviceBinary(programInfo, bin, decodeErrors, decodeWarnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, status);
EXPECT_EQ(NEO::DeviceBinaryFormat::Unknown, format);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_STREQ("Unknown format", decodeErrors.c_str());
}
TEST(DecodeSingleDeviceBinary, GivenPatchTokensFormatThenDecodingSucceeds) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
NEO::ProgramInfo programInfo;
std::string decodeErrors;
std::string decodeWarnings;
NEO::SingleDeviceBinary bin;
bin.deviceBinary = patchtokensProgram.storage;
NEO::DecodeError status;
NEO::DeviceBinaryFormat format;
std::tie(status, format) = NEO::decodeSingleDeviceBinary(programInfo, bin, decodeErrors, decodeWarnings);
EXPECT_EQ(NEO::DecodeError::Success, status);
EXPECT_EQ(NEO::DeviceBinaryFormat::Patchtokens, format);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_TRUE(decodeErrors.empty());
}
TEST(DecodeSingleDeviceBinary, GivenOclElfFormatThenDecodingFails) {
PatchTokensTestData::ValidEmptyProgram patchtokensProgram;
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEnc;
elfEnc.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
elfEnc.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, NEO::Elf::SectionNamesOpenCl::deviceBinary, patchtokensProgram.storage);
auto elfData = elfEnc.encode();
NEO::ProgramInfo programInfo;
std::string decodeErrors;
std::string decodeWarnings;
NEO::SingleDeviceBinary bin;
bin.deviceBinary = elfData;
NEO::DecodeError status;
NEO::DeviceBinaryFormat format;
std::tie(status, format) = NEO::decodeSingleDeviceBinary(programInfo, bin, decodeErrors, decodeWarnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, status);
EXPECT_EQ(NEO::DeviceBinaryFormat::OclElf, format);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_STREQ("Device binary format is packed", decodeErrors.c_str());
}
TEST(DecodeSingleDeviceBinary, GivenArFormatThenDecodingFails) {
NEO::Ar::ArEncoder arEnc;
auto arData = arEnc.encode();
NEO::ProgramInfo programInfo;
std::string decodeErrors;
std::string decodeWarnings;
NEO::SingleDeviceBinary bin;
bin.deviceBinary = arData;
NEO::DecodeError status;
NEO::DeviceBinaryFormat format;
std::tie(status, format) = NEO::decodeSingleDeviceBinary(programInfo, bin, decodeErrors, decodeWarnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, status);
EXPECT_EQ(NEO::DeviceBinaryFormat::Archive, format);
EXPECT_TRUE(decodeWarnings.empty());
EXPECT_STREQ("Device binary format is packed", decodeErrors.c_str());
}
TEST(PackDeviceBinary, GivenRequestToPackThenUsesOclElfFormat) {
NEO::SingleDeviceBinary deviceBinary;
std::string packErrors;
std::string packWarnings;
auto packed = NEO::packDeviceBinary(deviceBinary, packErrors, packWarnings);
EXPECT_TRUE(packErrors.empty());
EXPECT_TRUE(packWarnings.empty());
EXPECT_TRUE(NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::OclElf>(packed));
}

View File

@@ -1,343 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/elf/elf_decoder.h"
#include "test.h"
using namespace NEO::Elf;
TEST(ElfDecoder, WhenEmptyDataThenElfHeaderDecodingFails) {
ArrayRef<const uint8_t> empty;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_32>(empty));
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_64>(empty));
}
TEST(ElfDecoder, WhenValidHaderThenElfHeaderDecodingSucceeds) {
ElfFileHeader<EI_CLASS_64> header64;
EXPECT_EQ(&header64, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header64, 1U)));
ElfFileHeader<EI_CLASS_32> header32;
EXPECT_EQ(&header32, decodeElfFileHeader<EI_CLASS_32>(ArrayRef<const uint8_t>::fromAny(&header32, 1U)));
}
TEST(ElfDecoder, WhenNotEngoughDataThenElfHeaderDecodingFails) {
ElfFileHeader<EI_CLASS_64> header64;
auto header64Data = ArrayRef<const uint8_t>::fromAny(&header64, 1U);
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>(header64Data.begin(), header64Data.begin() + header64Data.size() - 1)));
ElfFileHeader<EI_CLASS_32> header32;
auto header32Data = ArrayRef<const uint8_t>::fromAny(&header32, 1U);
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_32>(ArrayRef<const uint8_t>(header32Data.begin(), header32Data.begin() + header32Data.size() - 1)));
}
TEST(ElfDecoder, WhenInvalidElfMagicThenElfHeaderDecodingFails) {
ElfFileHeader<EI_CLASS_64> header;
header.identity.magic[0] = 5;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U)));
header = ElfFileHeader<EI_CLASS_64>{};
header.identity.magic[1] = 5;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U)));
header = ElfFileHeader<EI_CLASS_64>{};
header.identity.magic[2] = 5;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U)));
header = ElfFileHeader<EI_CLASS_64>{};
header.identity.magic[3] = 5;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U)));
header = ElfFileHeader<EI_CLASS_64>{};
EXPECT_EQ(&header, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U)));
}
TEST(ElfDecoder, WhenMismatchedClassThenElfHeaderDecodingFails) {
ElfFileHeader<EI_CLASS_64> header64;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_32>(ArrayRef<const uint8_t>::fromAny(&header64, 1U)));
ElfFileHeader<EI_CLASS_32> header32;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header32, 1U)));
}
TEST(ElfDecoder, WhenNotElfThenCheckNumBitsReturnsClassNone) {
ArrayRef<const uint8_t> empty;
EXPECT_EQ(EI_CLASS_NONE, getElfNumBits(empty));
}
TEST(ElfDecoder, WhenValidElfThenCheckNumBitsReturnsProperClass) {
ElfFileHeader<EI_CLASS_64> header64;
EXPECT_EQ(EI_CLASS_64, getElfNumBits(ArrayRef<const uint8_t>::fromAny(&header64, 1U)));
ElfFileHeader<EI_CLASS_32> header32;
EXPECT_EQ(EI_CLASS_32, getElfNumBits(ArrayRef<const uint8_t>::fromAny(&header32, 1U)));
}
TEST(ElfDecoder, WhenNotElfThenIsElfReturnsFalse) {
ArrayRef<const uint8_t> empty;
EXPECT_FALSE(isElf(empty));
}
TEST(ElfDecoder, WhenValidElfThenIsElfReturnsTrue) {
ElfFileHeader<EI_CLASS_64> header64;
EXPECT_TRUE(isElf(ArrayRef<const uint8_t>::fromAny(&header64, 1U)));
ElfFileHeader<EI_CLASS_32> header32;
EXPECT_TRUE(isElf(ArrayRef<const uint8_t>::fromAny(&header32, 1U)));
}
TEST(ElfDecoder, WhenValidEmptyElfThenHeaderIsProperlyDecodedAndNoWarningsOrErrorsEmitted) {
ElfFileHeader<EI_CLASS_64> header64;
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header64, 1U), decodeErrors, decodeWarnings);
EXPECT_EQ(&header64, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_TRUE(decodeWarnings.empty());
decodeWarnings.clear();
decodeErrors.clear();
ElfFileHeader<EI_CLASS_32> header32;
auto elf32 = decodeElf<EI_CLASS_32>(ArrayRef<const uint8_t>::fromAny(&header32, 1U), decodeErrors, decodeWarnings);
EXPECT_EQ(&header32, elf32.elfFileHeader);
EXPECT_TRUE(elf32.programHeaders.empty());
EXPECT_TRUE(elf32.sectionHeaders.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenInvalidElfHeaderThenDecodingFails) {
ElfFileHeader<EI_CLASS_64> header;
header.identity.magic[0] = 5;
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U), decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Invalid or missing ELF header", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenOutOfBoundsProgramHeaderTableOffsetThenDecodingFails) {
ElfFileHeader<EI_CLASS_64> header;
header.phOff = sizeof(header) + 1;
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U), decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
EXPECT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Out of bounds program headers table", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenOutOfBoundsSectionHeaderTableOffsetThenDecodingFails) {
ElfFileHeader<EI_CLASS_64> header;
header.shOff = sizeof(header) + 1;
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(ArrayRef<const uint8_t>::fromAny(&header, 1U), decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
ASSERT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Out of bounds section headers table", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenValidProgramHeaderTableEntriesThenDecodingSucceedsAndNoWarningsOrErrorsEmitted) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.phOff = header.ehSize;
header.phNum = 2;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfProgramHeader<EI_CLASS_64> programHeader0;
programHeader0.fileSz = sizeof(programHeader0) * 2;
programHeader0.offset = header.phOff;
ElfProgramHeader<EI_CLASS_64> programHeader1;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&programHeader0), reinterpret_cast<const uint8_t *>(&programHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&programHeader1), reinterpret_cast<const uint8_t *>(&programHeader1 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<decltype(header) *>(storage.data()), elf64.elfFileHeader);
EXPECT_TRUE(elf64.sectionHeaders.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_TRUE(decodeWarnings.empty());
ASSERT_EQ(2U, elf64.programHeaders.size());
EXPECT_EQ(reinterpret_cast<decltype(programHeader0) *>(storage.data() + header.phOff), elf64.programHeaders[0].header);
EXPECT_EQ(reinterpret_cast<decltype(programHeader1) *>(storage.data() + header.phOff + header.phEntSize), elf64.programHeaders[1].header);
EXPECT_TRUE(elf64.programHeaders[1].data.empty());
EXPECT_FALSE(elf64.programHeaders[0].data.empty());
EXPECT_EQ(storage.data() + programHeader0.offset, elf64.programHeaders[0].data.begin());
EXPECT_EQ(programHeader0.fileSz, elf64.programHeaders[0].data.size());
}
TEST(ElfDecoder, WhenOutOfBoundsProgramHeaderTableEntriesThenDecodingFails) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.phOff = header.ehSize;
header.phNum = 3;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfProgramHeader<EI_CLASS_64> programHeader0;
ElfProgramHeader<EI_CLASS_64> programHeader1;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&programHeader0), reinterpret_cast<const uint8_t *>(&programHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&programHeader1), reinterpret_cast<const uint8_t *>(&programHeader1 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
ASSERT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Out of bounds program headers table", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenOutOfBoundsProgramHeaderDataThenDecodingFails) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.phOff = header.ehSize;
header.phNum = 2;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfProgramHeader<EI_CLASS_64> programHeader0;
programHeader0.fileSz = sizeof(programHeader0) * 2;
programHeader0.offset = header.phOff;
ElfProgramHeader<EI_CLASS_64> programHeader1;
programHeader1.fileSz = sizeof(programHeader0) * 3;
programHeader1.offset = header.phOff;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&programHeader0), reinterpret_cast<const uint8_t *>(&programHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&programHeader1), reinterpret_cast<const uint8_t *>(&programHeader1 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
ASSERT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Out of bounds program header offset/filesz, program header idx : 1", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenValidSectionHeaderTableEntriesThenDecodingSucceedsAndNoWarningsOrErrorsEmitted) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 2;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfSectionHeader<EI_CLASS_64> sectionHeader0;
sectionHeader0.size = sizeof(sectionHeader0) * 2;
sectionHeader0.offset = header.shOff;
ElfSectionHeader<EI_CLASS_64> sectionHeader1;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader0), reinterpret_cast<const uint8_t *>(&sectionHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader1), reinterpret_cast<const uint8_t *>(&sectionHeader1 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<decltype(header) *>(storage.data()), elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_TRUE(decodeWarnings.empty());
ASSERT_EQ(2U, elf64.sectionHeaders.size());
EXPECT_EQ(reinterpret_cast<decltype(sectionHeader0) *>(storage.data() + header.shOff), elf64.sectionHeaders[0].header);
EXPECT_EQ(reinterpret_cast<decltype(sectionHeader1) *>(storage.data() + header.shOff + header.shEntSize), elf64.sectionHeaders[1].header);
EXPECT_TRUE(elf64.sectionHeaders[1].data.empty());
EXPECT_FALSE(elf64.sectionHeaders[0].data.empty());
EXPECT_EQ(storage.data() + sectionHeader0.offset, elf64.sectionHeaders[0].data.begin());
EXPECT_EQ(sectionHeader0.size, elf64.sectionHeaders[0].data.size());
}
TEST(ElfDecoder, WhenOutOfBoundsSectionHeaderTableEntriesThenDecodingFails) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 3;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfSectionHeader<EI_CLASS_64> sectionHeader0;
ElfSectionHeader<EI_CLASS_64> sectionHeader1;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader0), reinterpret_cast<const uint8_t *>(&sectionHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader1), reinterpret_cast<const uint8_t *>(&sectionHeader1 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
ASSERT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Out of bounds section headers table", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenOutOfBoundsSectionHeaderDataThenDecodingFails) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 2;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfSectionHeader<EI_CLASS_64> sectionHeader0;
sectionHeader0.size = sizeof(sectionHeader0) * 2;
sectionHeader0.offset = header.shOff;
ElfSectionHeader<EI_CLASS_64> sectionHeader1;
sectionHeader1.size = sizeof(sectionHeader0) * 3;
sectionHeader1.offset = header.shOff;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader0), reinterpret_cast<const uint8_t *>(&sectionHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader1), reinterpret_cast<const uint8_t *>(&sectionHeader1 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
ASSERT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Out of bounds section header offset/size, section header idx : 1", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenSectionDoesNotHaveDataInFileThenDataIsSetAsEmpty) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 2;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfSectionHeader<EI_CLASS_64> sectionHeader0;
sectionHeader0.size = sizeof(sectionHeader0) * 2;
sectionHeader0.offset = header.shOff;
ElfSectionHeader<EI_CLASS_64> sectionHeader1;
sectionHeader1.size = sizeof(sectionHeader0) * 3;
sectionHeader1.offset = header.shOff;
sectionHeader1.type = SHT_NOBITS;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader0), reinterpret_cast<const uint8_t *>(&sectionHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader1), reinterpret_cast<const uint8_t *>(&sectionHeader1 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(reinterpret_cast<decltype(header) *>(storage.data()), elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(decodeErrors.empty());
EXPECT_TRUE(decodeWarnings.empty());
ASSERT_EQ(2U, elf64.sectionHeaders.size());
EXPECT_EQ(reinterpret_cast<decltype(sectionHeader0) *>(storage.data() + header.shOff), elf64.sectionHeaders[0].header);
EXPECT_EQ(reinterpret_cast<decltype(sectionHeader1) *>(storage.data() + header.shOff + header.shEntSize), elf64.sectionHeaders[1].header);
EXPECT_TRUE(elf64.sectionHeaders[1].data.empty());
EXPECT_FALSE(elf64.sectionHeaders[0].data.empty());
EXPECT_EQ(storage.data() + sectionHeader0.offset, elf64.sectionHeaders[0].data.begin());
EXPECT_EQ(sectionHeader0.size, elf64.sectionHeaders[0].data.size());
}

View File

@@ -1,457 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/source/utilities/range.h"
#include "test.h"
using namespace NEO::Elf;
TEST(ElfEncoder, WhenEmptyDataThenEncodedElfContainsOnlyHeader) {
ElfEncoder<EI_CLASS_64> elfEncoder64(false, false);
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
auto &identity64 = header64.identity;
EXPECT_EQ(elfMagic[0], identity64.magic[0]);
EXPECT_EQ(elfMagic[1], identity64.magic[1]);
EXPECT_EQ(elfMagic[2], identity64.magic[2]);
EXPECT_EQ(elfMagic[3], identity64.magic[3]);
EXPECT_EQ(EI_CLASS_64, identity64.eClass);
EXPECT_EQ(EI_DATA_LITTLE_ENDIAN, identity64.data);
EXPECT_EQ(EV_CURRENT, identity64.version);
EXPECT_EQ(0U, identity64.osAbi);
EXPECT_EQ(0U, identity64.abiVersion);
EXPECT_EQ(ET_NONE, header64.type);
EXPECT_EQ(EM_NONE, header64.machine);
EXPECT_EQ(1U, header64.version);
EXPECT_EQ(0U, header64.entry);
EXPECT_EQ(0U, header64.phOff);
EXPECT_EQ(0U, header64.shOff);
EXPECT_EQ(0U, header64.flags);
EXPECT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>), header64.ehSize);
EXPECT_EQ(sizeof(ElfProgramHeader<EI_CLASS_64>), header64.phEntSize);
EXPECT_EQ(0U, header64.phNum);
EXPECT_EQ(sizeof(ElfSectionHeader<EI_CLASS_64>), header64.shEntSize);
EXPECT_EQ(0U, header64.shNum);
EXPECT_EQ(SHN_UNDEF, header64.shStrNdx);
ElfEncoder<EI_CLASS_32> elfEncoder32(false, false);
auto elfData32 = elfEncoder32.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_32>), elfData32.size());
auto &header32 = *reinterpret_cast<ElfFileHeader<EI_CLASS_32> *>(elfData32.data());
auto &identity32 = header32.identity;
EXPECT_EQ(elfMagic[0], identity32.magic[0]);
EXPECT_EQ(elfMagic[1], identity32.magic[1]);
EXPECT_EQ(elfMagic[2], identity32.magic[2]);
EXPECT_EQ(elfMagic[3], identity32.magic[3]);
EXPECT_EQ(EI_CLASS_32, identity32.eClass);
EXPECT_EQ(EI_DATA_LITTLE_ENDIAN, identity32.data);
EXPECT_EQ(EV_CURRENT, identity32.version);
EXPECT_EQ(0U, identity32.osAbi);
EXPECT_EQ(0U, identity32.abiVersion);
EXPECT_EQ(ET_NONE, header32.type);
EXPECT_EQ(EM_NONE, header32.machine);
EXPECT_EQ(1U, header32.version);
EXPECT_EQ(0U, header32.entry);
EXPECT_EQ(0U, header32.phOff);
EXPECT_EQ(0U, header32.shOff);
EXPECT_EQ(0U, header32.flags);
EXPECT_EQ(sizeof(ElfFileHeader<EI_CLASS_32>), header32.ehSize);
EXPECT_EQ(sizeof(ElfProgramHeader<EI_CLASS_32>), header32.phEntSize);
EXPECT_EQ(0U, header32.phNum);
EXPECT_EQ(sizeof(ElfSectionHeader<EI_CLASS_32>), header32.shEntSize);
EXPECT_EQ(0U, header32.shNum);
EXPECT_EQ(SHN_UNDEF, header32.shStrNdx);
}
TEST(ElfEncoder, GivenRequestForUndefAndSectionHeaderNamesSectionsWhenNotNeededThenNotEmitted) {
ElfEncoder<EI_CLASS_64> elfEncoder64(true, true);
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
EXPECT_EQ(0U, header64.shOff);
EXPECT_EQ(0U, header64.shNum);
EXPECT_EQ(SHN_UNDEF, header64.shStrNdx);
}
TEST(ElfEncoder, GivenRequestForUndefAndSectionHeaderNamesSectionsWhenNeededThenEmitted) {
ElfEncoder<EI_CLASS_64> elfEncoder64(true, true);
elfEncoder64.appendSection(SHT_NULL, ".my_name_is_important", {});
auto elfData64 = elfEncoder64.encode();
char expectedSectionNamesData[] = "\0.shstrtab\0.my_name_is_important";
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 3 * sizeof(ElfSectionHeader<EI_CLASS_64>) + alignUp(sizeof(expectedSectionNamesData), 8), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
EXPECT_EQ(0U, header64.phOff);
EXPECT_EQ(header64.ehSize, header64.shOff);
EXPECT_EQ(0U, header64.flags);
EXPECT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>), header64.ehSize);
EXPECT_EQ(sizeof(ElfProgramHeader<EI_CLASS_64>), header64.phEntSize);
EXPECT_EQ(0U, header64.phNum);
EXPECT_EQ(sizeof(ElfSectionHeader<EI_CLASS_64>), header64.shEntSize);
EXPECT_EQ(3U, header64.shNum);
EXPECT_EQ(2U, header64.shStrNdx);
auto &sectUndef64 = *reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>));
auto &sectSkipMe64 = *reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>) + sizeof(ElfSectionHeader<EI_CLASS_64>));
auto &sectSectionNames64 = *reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>) + 2 * sizeof(ElfSectionHeader<EI_CLASS_64>));
const char *sectionNames64Data = reinterpret_cast<char *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>) + 3 * sizeof(ElfSectionHeader<EI_CLASS_64>));
EXPECT_EQ(0U, sectUndef64.name);
EXPECT_EQ(SHT_NULL, sectUndef64.type);
EXPECT_EQ(SHF_NONE, sectUndef64.flags);
EXPECT_EQ(0U, sectUndef64.addr);
EXPECT_EQ(0U, sectUndef64.offset);
EXPECT_EQ(0U, sectUndef64.size);
EXPECT_EQ(SHN_UNDEF, sectUndef64.link);
EXPECT_EQ(0U, sectUndef64.info);
EXPECT_EQ(0U, sectUndef64.addralign);
EXPECT_EQ(0U, sectUndef64.entsize);
EXPECT_EQ(11U, sectSkipMe64.name);
EXPECT_EQ(SHT_NULL, sectSkipMe64.type);
EXPECT_EQ(SHF_NONE, sectSkipMe64.flags);
EXPECT_EQ(0U, sectSkipMe64.addr);
EXPECT_EQ(0U, sectSkipMe64.offset);
EXPECT_EQ(0U, sectSkipMe64.size);
EXPECT_EQ(SHN_UNDEF, sectSkipMe64.link);
EXPECT_EQ(0U, sectSkipMe64.info);
EXPECT_EQ(8U, sectSkipMe64.addralign);
EXPECT_EQ(0U, sectSkipMe64.entsize);
EXPECT_EQ(1U, sectSectionNames64.name);
EXPECT_EQ(SHT_STRTAB, sectSectionNames64.type);
EXPECT_EQ(SHF_NONE, sectSectionNames64.flags);
EXPECT_EQ(0U, sectSectionNames64.addr);
EXPECT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 3 * sizeof(ElfSectionHeader<EI_CLASS_64>), sectSectionNames64.offset);
EXPECT_EQ(sizeof(expectedSectionNamesData), sectSectionNames64.size);
EXPECT_EQ(SHN_UNDEF, sectSectionNames64.link);
EXPECT_EQ(0U, sectSectionNames64.info);
EXPECT_EQ(8U, sectSectionNames64.addralign);
EXPECT_EQ(0U, sectSectionNames64.entsize);
EXPECT_EQ(0, memcmp(expectedSectionNamesData, sectionNames64Data, sizeof(expectedSectionNamesData)));
ElfEncoder<EI_CLASS_32> elfEncoder32(true, true);
elfEncoder32.appendSection(SHT_NULL, ".my_name_is_important", {});
auto elfData32 = elfEncoder32.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_32>) + 3 * sizeof(ElfSectionHeader<EI_CLASS_32>) + alignUp(sizeof(expectedSectionNamesData), 8), elfData32.size());
auto &header32 = *reinterpret_cast<ElfFileHeader<EI_CLASS_32> *>(elfData32.data());
EXPECT_EQ(header32.ehSize, header32.shOff);
auto &sectSectionNames32 = *reinterpret_cast<ElfSectionHeader<EI_CLASS_32> *>(elfData32.data() + sizeof(ElfFileHeader<EI_CLASS_32>) + 2 * sizeof(ElfSectionHeader<EI_CLASS_32>));
const char *sectionNames32Data = reinterpret_cast<char *>(elfData32.data() + sizeof(ElfFileHeader<EI_CLASS_32>) + 3 * sizeof(ElfSectionHeader<EI_CLASS_32>));
EXPECT_EQ(sizeof(ElfFileHeader<EI_CLASS_32>) + 3 * sizeof(ElfSectionHeader<EI_CLASS_32>), sectSectionNames32.offset);
EXPECT_EQ(sizeof(expectedSectionNamesData), sectSectionNames32.size);
EXPECT_EQ(0, memcmp(expectedSectionNamesData, sectionNames32Data, sizeof(expectedSectionNamesData)));
}
TEST(ElfEncoder, WhenAppendingSectionWithDataThenOffsetsAreProperlyUpdated) {
ElfEncoder<EI_CLASS_64> elfEncoder64(false, false);
const uint8_t data[] = "235711131719";
elfEncoder64.appendSection(SHT_PROGBITS, ".my_name_is_not_important", data);
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 1 * sizeof(ElfSectionHeader<EI_CLASS_64>) + alignUp(sizeof(data), 8), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
EXPECT_EQ(0U, header64.phOff);
EXPECT_EQ(header64.ehSize, header64.shOff);
EXPECT_EQ(1U, header64.shNum);
EXPECT_EQ(SHN_UNDEF, header64.shStrNdx);
auto &sectProgBits = *reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>));
auto sectProgBitsData = elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>) + sizeof(ElfSectionHeader<EI_CLASS_64>);
EXPECT_EQ(0U, sectProgBits.name);
EXPECT_EQ(SHT_PROGBITS, sectProgBits.type);
EXPECT_EQ(SHF_NONE, sectProgBits.flags);
EXPECT_EQ(0U, sectProgBits.addr);
EXPECT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + sizeof(ElfSectionHeader<EI_CLASS_64>), sectProgBits.offset);
EXPECT_EQ(sizeof(data), sectProgBits.size);
EXPECT_EQ(SHN_UNDEF, sectProgBits.link);
EXPECT_EQ(0U, sectProgBits.info);
EXPECT_EQ(8U, sectProgBits.addralign);
EXPECT_EQ(0U, sectProgBits.entsize);
EXPECT_EQ(0, memcmp(data, sectProgBitsData, sizeof(data)));
}
TEST(ElfEncoder, WhenAppendingSectionWithoutDataThenOffsetsAreLeftIntact) {
ElfEncoder<EI_CLASS_64> elfEncoder64(false, false);
elfEncoder64.appendSection(SHT_PROGBITS, ".my_name_is_not_important", {});
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 1 * sizeof(ElfSectionHeader<EI_CLASS_64>), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
EXPECT_EQ(0U, header64.phOff);
EXPECT_EQ(header64.ehSize, header64.shOff);
EXPECT_EQ(1U, header64.shNum);
EXPECT_EQ(SHN_UNDEF, header64.shStrNdx);
auto &sectProgBits = *reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>));
EXPECT_EQ(0U, sectProgBits.name);
EXPECT_EQ(SHT_PROGBITS, sectProgBits.type);
EXPECT_EQ(SHF_NONE, sectProgBits.flags);
EXPECT_EQ(0U, sectProgBits.addr);
EXPECT_EQ(0U, sectProgBits.offset);
EXPECT_EQ(0U, sectProgBits.size);
EXPECT_EQ(SHN_UNDEF, sectProgBits.link);
EXPECT_EQ(0U, sectProgBits.info);
EXPECT_EQ(8U, sectProgBits.addralign);
EXPECT_EQ(0U, sectProgBits.entsize);
}
TEST(ElfEncoder, WhenAppendingSectionWithNoBitsTypeThenDataIsIgnored) {
{
ElfEncoder<EI_CLASS_64> elfEncoder64(false, false);
const uint8_t data[] = "235711131719";
elfEncoder64.appendSection(SHT_NOBITS, ".my_name_is_not_important", data);
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 1 * sizeof(ElfSectionHeader<EI_CLASS_64>), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
EXPECT_EQ(0U, header64.phOff);
EXPECT_EQ(header64.ehSize, header64.shOff);
EXPECT_EQ(1U, header64.shNum);
EXPECT_EQ(SHN_UNDEF, header64.shStrNdx);
auto &sectNoBits = *reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>));
EXPECT_EQ(0U, sectNoBits.name);
EXPECT_EQ(SHT_NOBITS, sectNoBits.type);
EXPECT_EQ(SHF_NONE, sectNoBits.flags);
EXPECT_EQ(0U, sectNoBits.addr);
EXPECT_EQ(0U, sectNoBits.offset);
EXPECT_EQ(0U, sectNoBits.size);
EXPECT_EQ(SHN_UNDEF, sectNoBits.link);
EXPECT_EQ(0U, sectNoBits.info);
EXPECT_EQ(8U, sectNoBits.addralign);
EXPECT_EQ(0U, sectNoBits.entsize);
}
{
ElfEncoder<EI_CLASS_64> elfEncoder64(false, false);
const uint8_t data[] = "235711131719";
elfEncoder64.appendSection(static_cast<uint32_t>(SHT_NOBITS), ".my_name_is_not_important", data).size = sizeof(data);
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 1 * sizeof(ElfSectionHeader<EI_CLASS_64>), elfData64.size());
auto &sectNoBits = *reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>));
EXPECT_EQ(0U, sectNoBits.offset);
EXPECT_EQ(sizeof(data), sectNoBits.size);
}
}
TEST(ElfEncoder, WhenAppendingSegmentWithDataThenOffsetsAreProperlyUpdated) {
ElfEncoder<EI_CLASS_64> elfEncoder64(false, false);
const uint8_t data[] = "235711131719";
elfEncoder64.appendSegment(PT_LOAD, data);
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 1 * sizeof(ElfProgramHeader<EI_CLASS_64>) + alignUp(sizeof(data), 8), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
EXPECT_EQ(0U, header64.shOff);
EXPECT_EQ(header64.ehSize, header64.phOff);
EXPECT_EQ(1U, header64.phNum);
EXPECT_EQ(SHN_UNDEF, header64.shStrNdx);
auto &segLoad = *reinterpret_cast<ElfProgramHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>));
auto segLoadBitsData = elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>) + sizeof(ElfProgramHeader<EI_CLASS_64>);
EXPECT_EQ(PT_LOAD, segLoad.type);
EXPECT_EQ(PF_NONE, segLoad.flags);
EXPECT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + sizeof(ElfProgramHeader<EI_CLASS_64>), segLoad.offset);
EXPECT_EQ(0U, segLoad.vAddr);
EXPECT_EQ(0U, segLoad.pAddr);
EXPECT_EQ(sizeof(data), segLoad.fileSz);
EXPECT_EQ(0U, segLoad.memSz);
EXPECT_EQ(8U, segLoad.align);
EXPECT_EQ(0, memcmp(data, segLoadBitsData, sizeof(data)));
}
TEST(ElfEncoder, WhenAppendingSegmentWithoutDataThenOffsetsAreLeftIntact) {
ElfEncoder<EI_CLASS_64> elfEncoder64(false, false);
elfEncoder64.appendSegment(PT_LOAD, {});
auto elfData64 = elfEncoder64.encode();
ASSERT_EQ(sizeof(ElfFileHeader<EI_CLASS_64>) + 1 * sizeof(ElfProgramHeader<EI_CLASS_64>), elfData64.size());
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
EXPECT_EQ(0U, header64.shOff);
EXPECT_EQ(header64.ehSize, header64.phOff);
EXPECT_EQ(1U, header64.phNum);
EXPECT_EQ(SHN_UNDEF, header64.shStrNdx);
auto &segLoad = *reinterpret_cast<ElfProgramHeader<EI_CLASS_64> *>(elfData64.data() + sizeof(ElfFileHeader<EI_CLASS_64>));
EXPECT_EQ(PT_LOAD, segLoad.type);
EXPECT_EQ(PF_NONE, segLoad.flags);
EXPECT_EQ(0U, segLoad.offset);
EXPECT_EQ(0U, segLoad.vAddr);
EXPECT_EQ(0U, segLoad.pAddr);
EXPECT_EQ(0U, segLoad.fileSz);
EXPECT_EQ(0U, segLoad.memSz);
EXPECT_EQ(8U, segLoad.align);
}
TEST(ElfEncoder, WhenAppendingBothSectionAndSegmentThenProperElfIsEmited) {
const uint8_t segmentData[] = "235711131719";
const uint8_t sectionData[] = "232931374143";
const uint8_t sectionNamesData[] = "\0.shstrtab\0.my_name_is_important";
ElfFileHeader<EI_CLASS_64> header;
header.type = ET_EXEC;
header.entry = 16U;
header.phOff = static_cast<decltype(header.phOff)>(sizeof(header));
header.shOff = static_cast<decltype(header.shOff)>(sizeof(header) + sizeof(ElfProgramHeader<EI_CLASS_64>));
header.flags = 4U;
header.phNum = 1U;
header.shNum = 3U;
header.shStrNdx = 2U;
ElfProgramHeader<EI_CLASS_64> segment;
segment.type = PT_LOAD;
segment.flags = PF_R | PF_X;
segment.offset = static_cast<decltype(segment.offset)>(header.shOff + sizeof(ElfSectionHeader<EI_CLASS_64>) * 3);
segment.vAddr = 4096U;
segment.pAddr = 4096U * 16;
segment.fileSz = static_cast<decltype(segment.fileSz)>(sizeof(segmentData));
segment.memSz = 8192U;
segment.align = 8U;
ElfSectionHeader<EI_CLASS_64> sectionUndef;
ElfSectionHeader<EI_CLASS_64> sectionProgBits;
sectionProgBits.name = 11U;
sectionProgBits.type = SHT_PROGBITS;
sectionProgBits.flags = SHF_ALLOC;
sectionProgBits.addr = 16U;
sectionProgBits.offset = static_cast<decltype(sectionProgBits.offset)>(segment.offset + alignUp(static_cast<size_t>(segment.fileSz), static_cast<size_t>(segment.align)));
sectionProgBits.size = static_cast<decltype(sectionProgBits.size)>(sizeof(sectionData));
sectionProgBits.link = SHN_UNDEF;
sectionProgBits.info = 0U;
sectionProgBits.addralign = 16U;
sectionProgBits.entsize = 0U;
ElfSectionHeader<EI_CLASS_64> sectionSectionNames;
sectionSectionNames.name = 1U;
sectionSectionNames.type = SHT_STRTAB;
sectionSectionNames.flags = SHF_NONE;
sectionSectionNames.addr = 0U;
sectionSectionNames.offset = static_cast<decltype(sectionSectionNames.offset)>(sectionProgBits.offset + alignUp(static_cast<size_t>(sectionProgBits.size), static_cast<size_t>(sectionProgBits.addralign)));
sectionSectionNames.size = static_cast<decltype(sectionSectionNames.size)>(sizeof(sectionNamesData));
sectionSectionNames.link = SHN_UNDEF;
sectionSectionNames.info = 0U;
sectionSectionNames.addralign = 8U;
sectionSectionNames.entsize = 0U;
std::vector<uint8_t> handMade;
handMade.insert(handMade.end(), reinterpret_cast<uint8_t *>(&header), reinterpret_cast<uint8_t *>(&header + 1));
handMade.insert(handMade.end(), reinterpret_cast<uint8_t *>(&segment), reinterpret_cast<uint8_t *>(&segment + 1));
handMade.insert(handMade.end(), reinterpret_cast<uint8_t *>(&sectionUndef), reinterpret_cast<uint8_t *>(&sectionUndef + 1));
handMade.insert(handMade.end(), reinterpret_cast<uint8_t *>(&sectionProgBits), reinterpret_cast<uint8_t *>(&sectionProgBits + 1));
handMade.insert(handMade.end(), reinterpret_cast<uint8_t *>(&sectionSectionNames), reinterpret_cast<uint8_t *>(&sectionSectionNames + 1));
handMade.insert(handMade.end(), segmentData, segmentData + sizeof(segmentData));
handMade.resize(static_cast<size_t>(sectionProgBits.offset), 0U);
handMade.insert(handMade.end(), sectionData, sectionData + sizeof(sectionData));
handMade.resize(static_cast<size_t>(sectionSectionNames.offset), 0U);
handMade.insert(handMade.end(), sectionNamesData, sectionNamesData + sizeof(sectionNamesData));
handMade.resize(static_cast<size_t>(sectionSectionNames.offset + alignUp(sizeof(sectionNamesData), 8U)), 0U);
ElfEncoder<EI_CLASS_64> elfEncoder64;
{
auto &encodedHeader = elfEncoder64.getElfFileHeader();
encodedHeader.type = ET_EXEC;
encodedHeader.entry = 16U;
encodedHeader.flags = 4U;
auto &encodedSegment = elfEncoder64.appendSegment(PT_LOAD, segmentData);
encodedSegment.type = PT_LOAD;
encodedSegment.flags = PF_R | PF_X;
encodedSegment.vAddr = 4096U;
encodedSegment.pAddr = 4096U * 16;
encodedSegment.memSz = 8192U;
encodedSegment.align = 8U;
ElfSectionHeader<EI_CLASS_64> encodedSectionProgBits;
encodedSectionProgBits.name = elfEncoder64.appendSectionName(".my_name_is_important");
encodedSectionProgBits.type = SHT_PROGBITS;
encodedSectionProgBits.flags = SHF_ALLOC;
encodedSectionProgBits.addr = 16U;
encodedSectionProgBits.link = SHN_UNDEF;
encodedSectionProgBits.info = 0U;
encodedSectionProgBits.addralign = 16U;
encodedSectionProgBits.entsize = 0U;
elfEncoder64.appendSection(encodedSectionProgBits, sectionData);
}
auto generated = elfEncoder64.encode();
EXPECT_EQ(handMade, generated);
}
TEST(ElfEncoder, WhenDefaultAlignmentIsRaisedThenSegmentDataAbideByIt) {
const uint8_t segmentData[] = "235711131719";
const uint8_t sectionData[] = "232931374143475";
static constexpr size_t alignment = 128U;
ElfEncoder<EI_CLASS_64> elfEncoder64(true, true, alignment);
elfEncoder64.appendSegment(PT_LOAD, segmentData);
elfEncoder64.appendSection(NEO::Elf::SHT_PROGBITS, "my_name_is_important", sectionData);
auto elfData64 = elfEncoder64.encode();
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
auto sectionHeaders = reinterpret_cast<NEO::Elf::ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + static_cast<size_t>(header64.shOff));
auto programHeaders = reinterpret_cast<NEO::Elf::ElfProgramHeader<EI_CLASS_64> *>(elfData64.data() + static_cast<size_t>(header64.phOff));
for (const auto &section : NEO::CreateRange(sectionHeaders, header64.shNum)) {
EXPECT_EQ(0U, section.offset % 8U);
}
for (const auto &segment : NEO::CreateRange(programHeaders, header64.phNum)) {
EXPECT_EQ(0U, segment.offset % alignment);
EXPECT_LE(alignment, segment.align);
}
}
TEST(ElfEncoder, WhenDefaultAlignmentIsLoweredThenSectionAndSegmentDataAbideByIt) {
const uint8_t segmentData[] = "235711131719";
const uint8_t sectionData[] = "232931374143475";
static constexpr size_t alignment = 1U;
ElfEncoder<EI_CLASS_64> elfEncoder64(true, true, alignment);
elfEncoder64.appendSegment(PT_LOAD, segmentData);
elfEncoder64.appendSection(NEO::Elf::SHT_PROGBITS, "my_name_is_important", sectionData);
auto elfData64 = elfEncoder64.encode();
auto &header64 = *reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData64.data());
auto sectionHeaders = reinterpret_cast<NEO::Elf::ElfSectionHeader<EI_CLASS_64> *>(elfData64.data() + static_cast<size_t>(header64.shOff));
NEO::Elf::ElfSectionHeader<EI_CLASS_64> *sectionNamesSection = sectionHeaders + header64.shStrNdx;
size_t unpaddedSize = sizeof(ElfFileHeader<EI_CLASS_64>) + 3 * sizeof(NEO::Elf::ElfSectionHeader<EI_CLASS_64>) + sizeof(NEO::Elf::ElfProgramHeader<EI_CLASS_64>);
unpaddedSize += sizeof(segmentData) + sizeof(sectionData) + static_cast<size_t>(sectionNamesSection->size);
EXPECT_EQ(unpaddedSize, elfData64.size());
}
TEST(ElfEncoder, WhenAppendingEmptySectionNameThenAlwaysReturn0AsOffset) {
ElfEncoder<EI_CLASS_64> elfEncoder64(false, true);
auto offset0 = elfEncoder64.appendSectionName({});
auto offset1 = elfEncoder64.appendSectionName({});
auto offset2 = elfEncoder64.appendSectionName({});
EXPECT_EQ(0U, offset0);
EXPECT_EQ(0U, offset1);
EXPECT_EQ(0U, offset2);
}
TEST(ElfEncoder, WhenAppendingSectionNameThenEmplacedStringIsAlwaysNullterminated) {
ElfEncoder<EI_CLASS_64> elfEncoder64(true, true);
auto strOffset = elfEncoder64.appendSectionName(ConstStringRef("abc", 2));
auto strOffset2 = elfEncoder64.appendSectionName(ConstStringRef("de", 3));
auto strOffset3 = elfEncoder64.appendSectionName(ConstStringRef("g"));
elfEncoder64.appendSection(SHT_NOBITS, "my_name_is_important", {});
EXPECT_EQ(strOffset + 3, strOffset2);
EXPECT_EQ(strOffset2 + 3, strOffset3);
auto elfData = elfEncoder64.encode();
auto header = reinterpret_cast<ElfFileHeader<EI_CLASS_64> *>(elfData.data());
auto sectionNamesSection = reinterpret_cast<ElfSectionHeader<EI_CLASS_64> *>(elfData.data() + static_cast<size_t>(header->shOff + header->shStrNdx * header->shEntSize));
EXPECT_STREQ("ab", reinterpret_cast<const char *>(elfData.data() + sectionNamesSection->offset + strOffset));
EXPECT_STREQ("de", reinterpret_cast<const char *>(elfData.data() + sectionNamesSection->offset + strOffset2));
EXPECT_STREQ("g", reinterpret_cast<const char *>(elfData.data() + sectionNamesSection->offset + strOffset3));
}

View File

@@ -1,333 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/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::DecodeError::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::DecodeError::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::DecodeError::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

@@ -1,524 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/patchtokens_decoder.h"
#include "shared/source/device_binary_format/patchtokens_validator.h"
#include "device_binary_format/patchtokens_tests.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
TEST(PatchtokensValidator, GivenValidProgramThenValidationSucceeds) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithInvalidOrUnknownStatusThenValidationFails) {
PatchTokensTestData::ValidEmptyProgram prog;
std::string error, warning;
prog.decodeStatus = NEO::DecodeError::Undefined;
EXPECT_EQ(NEO::DecodeError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ("ProgramFromPatchtokens wasn't successfully decoded", error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
warning.clear();
prog.decodeStatus = NEO::DecodeError::InvalidBinary;
EXPECT_EQ(NEO::DecodeError::InvalidBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ("Invalid pointer size", error.c_str());
EXPECT_TRUE(warning.empty());
prog.headerMutable->GPUPointerSizeInBytes = 1U;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 2U;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 3U;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 4U;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 5U;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 6U;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 7U;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 8U;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
prog.headerMutable->GPUPointerSizeInBytes = 9U;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
}
TEST(PatchtokensValidator, GivenProgramWithInvalidConstantPointerConstantBufferIndexThenValidationFails) {
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer prog;
std::string error, warning;
prog.constantPointerMutable->ConstantBufferIndex = 1;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenValidProgramWithMixedGlobalVarAndConstSurfacesAndPointersThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithMixedGlobalVarAndConstSurfacesAndPointers prog;
std::string error, warning;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(progGlobalVar, error, warning));
EXPECT_FALSE(error.empty());
EXPECT_TRUE(warning.empty());
PatchTokensTestData::ValidProgramWithConstantSurfaceAndPointer progConstVar;
progConstVar.constantPointerMutable->BufferType = iOpenCL::PROGRAM_SCOPE_GLOBAL_BUFFER;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(progConstVar, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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);
auto prevValue = NEO::PatchTokenBinary::allowUnhandledTokens;
NEO::PatchTokenBinary::allowUnhandledTokens = false;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
NEO::PatchTokenBinary::allowUnhandledTokens = prevValue;
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);
auto prevValue = NEO::PatchTokenBinary::allowUnhandledTokens;
NEO::PatchTokenBinary::allowUnhandledTokens = true;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
NEO::PatchTokenBinary::allowUnhandledTokens = prevValue;
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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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, GivenValidProgramWithKernelThenValidationSucceeds) {
PatchTokensTestData::ValidProgramWithKernel prog;
std::string error, warning;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::Undefined;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::InvalidBinary;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
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);
auto prevValue = NEO::PatchTokenBinary::allowUnhandledTokens;
NEO::PatchTokenBinary::allowUnhandledTokens = false;
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
NEO::PatchTokenBinary::allowUnhandledTokens = prevValue;
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);
auto prevValue = NEO::PatchTokenBinary::allowUnhandledTokens;
NEO::PatchTokenBinary::allowUnhandledTokens = true;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
NEO::PatchTokenBinary::allowUnhandledTokens = prevValue;
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::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelAndArgThenKernelArgInfoIsOptional) {
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
std::string error, warning;
prog.kernels[0].tokens.kernelArgs[0].argInfo = nullptr;
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenProgramWithKernelWhenKernelsArgHasUnknownAddressSpaceThenValidationFails) {
PatchTokensTestData::ValidProgramWithKernelAndArg prog;
std::string error, warning;
prog.arg0InfoAddressQualifierMutable[2] = '\0';
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, 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::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 2U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 3U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 4U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 5U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 6U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 7U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 8U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 9U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::UnhandledBinary, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_STREQ(expectedError, error.c_str());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 16U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
error.clear();
prog.kernelExecEnvMutable->LargestCompiledSIMDSize = 32U;
prog.recalcTokPtr();
EXPECT_EQ(NEO::DecodeError::Success, NEO::PatchTokenBinary::validate(prog, error, warning));
EXPECT_TRUE(error.empty());
EXPECT_TRUE(warning.empty());
}
TEST(PatchtokensValidator, GivenDefaultStateThenUnhandledPatchtokensAreAllowed) {
EXPECT_TRUE(NEO::PatchTokenBinary::allowUnhandledTokens);
}

View File

@@ -1,14 +0,0 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_DIRECT_SUBMISSION_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/direct_submission_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_DIRECT_SUBMISSION_TESTS ${NEO_CORE_DIRECT_SUBMISSION_TESTS})
add_subdirectories()

View File

@@ -1,620 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/submissions_aggregator.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/direct_submission/dispatchers/render_dispatcher.h"
#include "shared/source/helpers/flush_stamp.h"
#include "shared/source/os_interface/os_context.h"
#include "helpers/debug_manager_state_restore.h"
#include "helpers/ult_hw_config.h"
#include "mocks/mock_direct_submission_hw.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/helpers/dispatch_flags_helper.h"
#include "opencl/test/unit_test/helpers/variable_backup.h"
#include "opencl/test/unit_test/mocks/mock_csr.h"
#include "test.h"
#include <atomic>
#include <memory>
using namespace NEO;
extern std::atomic<uintptr_t> lastClFlushedPtr;
struct DirectSubmissionFixture : public DeviceFixture {
void SetUp() {
DeviceFixture::SetUp();
osContext.reset(OsContext::create(nullptr, 0u, 0u, aub_stream::ENGINE_RCS, PreemptionMode::ThreadGroup, false));
}
std::unique_ptr<OsContext> osContext;
};
using DirectSubmissionTest = Test<DirectSubmissionFixture>;
HWTEST_F(DirectSubmissionTest, whenDebugCacheFlushDisabledSetThenExpectNoCpuCacheFlush) {
DebugManagerStateRestore restore;
DebugManager.flags.DirectSubmissionDisableCpuCacheFlush.set(1);
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
EXPECT_TRUE(directSubmission.disableCpuCacheFlush);
uintptr_t expectedPtrVal = 0;
lastClFlushedPtr = 0;
void *ptr = reinterpret_cast<void *>(0xABCD00u);
size_t size = 64;
directSubmission.cpuCachelineFlush(ptr, size);
EXPECT_EQ(expectedPtrVal, lastClFlushedPtr);
}
HWTEST_F(DirectSubmissionTest, whenDebugCacheFlushDisabledNotSetThenExpectCpuCacheFlush) {
DebugManagerStateRestore restore;
DebugManager.flags.DirectSubmissionDisableCpuCacheFlush.set(0);
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
EXPECT_FALSE(directSubmission.disableCpuCacheFlush);
uintptr_t expectedPtrVal = 0xABCD00u;
lastClFlushedPtr = 0;
void *ptr = reinterpret_cast<void *>(expectedPtrVal);
size_t size = 64;
directSubmission.cpuCachelineFlush(ptr, size);
EXPECT_EQ(expectedPtrVal, lastClFlushedPtr);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionInitializedWhenRingIsStartedThenExpectAllocationsCreatedAndCommandsDispatched) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
EXPECT_FALSE(directSubmission.disableCpuCacheFlush);
bool ret = directSubmission.initialize(true);
EXPECT_TRUE(ret);
EXPECT_TRUE(directSubmission.ringStart);
EXPECT_NE(nullptr, directSubmission.ringBuffer);
EXPECT_NE(nullptr, directSubmission.ringBuffer2);
EXPECT_NE(nullptr, directSubmission.semaphores);
EXPECT_NE(0u, directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionInitializedWhenRingIsNotStartedThenExpectAllocationsCreatedAndCommandsNotDispatched) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
EXPECT_FALSE(directSubmission.ringStart);
EXPECT_NE(nullptr, directSubmission.ringBuffer);
EXPECT_NE(nullptr, directSubmission.ringBuffer2);
EXPECT_NE(nullptr, directSubmission.semaphores);
EXPECT_EQ(0u, directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionSwitchBuffersWhenCurrentIsPrimaryThenExpectNextSecondary) {
using RingBufferUse = typename MockDirectSubmissionHw<FamilyType>::RingBufferUse;
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
EXPECT_EQ(RingBufferUse::FirstBuffer, directSubmission.currentRingBuffer);
GraphicsAllocation *nextRing = directSubmission.switchRingBuffersAllocations();
EXPECT_EQ(directSubmission.ringBuffer2, nextRing);
EXPECT_EQ(RingBufferUse::SecondBuffer, directSubmission.currentRingBuffer);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionSwitchBuffersWhenCurrentIsSecondaryThenExpectNextPrimary) {
using RingBufferUse = typename MockDirectSubmissionHw<FamilyType>::RingBufferUse;
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
EXPECT_EQ(RingBufferUse::FirstBuffer, directSubmission.currentRingBuffer);
GraphicsAllocation *nextRing = directSubmission.switchRingBuffersAllocations();
EXPECT_EQ(directSubmission.ringBuffer2, nextRing);
EXPECT_EQ(RingBufferUse::SecondBuffer, directSubmission.currentRingBuffer);
nextRing = directSubmission.switchRingBuffersAllocations();
EXPECT_EQ(directSubmission.ringBuffer, nextRing);
EXPECT_EQ(RingBufferUse::FirstBuffer, directSubmission.currentRingBuffer);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionAllocateFailWhenRingIsStartedThenExpectRingNotStarted) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
EXPECT_FALSE(directSubmission.disableCpuCacheFlush);
directSubmission.allocateOsResourcesReturn = false;
bool ret = directSubmission.initialize(true);
EXPECT_FALSE(ret);
EXPECT_FALSE(directSubmission.ringStart);
EXPECT_EQ(0u, directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionSubmitFailWhenRingIsStartedThenExpectRingNotStartedCommandsDispatched) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
directSubmission.submitReturn = false;
bool ret = directSubmission.initialize(true);
EXPECT_FALSE(ret);
EXPECT_FALSE(directSubmission.ringStart);
EXPECT_NE(0u, directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionStartWhenRingIsStartedThenExpectNoStartCommandsDispatched) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(true);
EXPECT_TRUE(ret);
size_t usedSize = directSubmission.ringCommandStream.getUsed();
ret = directSubmission.startRingBuffer();
EXPECT_TRUE(ret);
EXPECT_EQ(usedSize, directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionStartWhenRingIsNotStartedThenExpectStartCommandsDispatched) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
size_t usedSize = directSubmission.ringCommandStream.getUsed();
ret = directSubmission.startRingBuffer();
EXPECT_TRUE(ret);
EXPECT_TRUE(directSubmission.ringStart);
EXPECT_NE(usedSize, directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionStartWhenRingIsNotStartedSubmitFailThenExpectStartCommandsDispatchedRingNotStarted) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
size_t usedSize = directSubmission.ringCommandStream.getUsed();
directSubmission.submitReturn = false;
ret = directSubmission.startRingBuffer();
EXPECT_FALSE(ret);
EXPECT_FALSE(directSubmission.ringStart);
EXPECT_NE(usedSize, directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionStartWhenRingIsNotStartedAndSwitchBufferIsNeededThenExpectRingAllocationChangedStartCommandsDispatched) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
auto expectedRingBuffer = directSubmission.currentRingBuffer;
GraphicsAllocation *oldRingBuffer = directSubmission.ringCommandStream.getGraphicsAllocation();
directSubmission.ringCommandStream.getSpace(directSubmission.ringCommandStream.getAvailableSpace() - directSubmission.getSizeSemaphoreSection());
ret = directSubmission.startRingBuffer();
auto actualRingBuffer = directSubmission.currentRingBuffer;
EXPECT_TRUE(ret);
EXPECT_TRUE(directSubmission.ringStart);
EXPECT_NE(oldRingBuffer, directSubmission.ringCommandStream.getGraphicsAllocation());
EXPECT_EQ(directSubmission.getSizeSemaphoreSection(), directSubmission.ringCommandStream.getUsed());
EXPECT_NE(expectedRingBuffer, actualRingBuffer);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionStopWhenStopRingIsCalledThenExpectStopCommandDispatched) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(true);
EXPECT_TRUE(ret);
size_t alreadyDispatchedSize = directSubmission.ringCommandStream.getUsed();
uint32_t oldQueueCount = directSubmission.semaphoreData->QueueWorkCount;
directSubmission.stopRingBuffer();
size_t expectedDispatchSize = alreadyDispatchedSize + directSubmission.getSizeEnd();
EXPECT_EQ(expectedDispatchSize, directSubmission.ringCommandStream.getUsed());
EXPECT_EQ(oldQueueCount + 1, directSubmission.semaphoreData->QueueWorkCount);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenDispatchSemaphoreThenExpectCorrectSizeUsed) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
directSubmission.dispatchSemaphoreSection(1u);
EXPECT_EQ(directSubmission.getSizeSemaphoreSection(), directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenDispatchStartSectionThenExpectCorrectSizeUsed) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
directSubmission.dispatchStartSection(1ull);
EXPECT_EQ(directSubmission.getSizeStartSection(), directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenDispatchSwitchRingBufferSectionThenExpectCorrectSizeUsed) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
directSubmission.dispatchSwitchRingBufferSection(1ull);
EXPECT_EQ(directSubmission.getSizeSwitchRingBufferSection(), directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenDispatchFlushSectionThenExpectCorrectSizeUsed) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
directSubmission.dispatchFlushSection();
EXPECT_EQ(directSubmission.getSizeFlushSection(), directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenDispatchTagUpdateSectionThenExpectCorrectSizeUsed) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
directSubmission.dispatchTagUpdateSection(0ull, 0ull);
EXPECT_EQ(directSubmission.getSizeTagUpdateSection(), directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenDispatchEndingSectionThenExpectCorrectSizeUsed) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
directSubmission.dispatchEndingSection();
EXPECT_EQ(directSubmission.getSizeEndingSection(), directSubmission.ringCommandStream.getUsed());
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenGetDispatchSizeThenExpectCorrectSizeReturned) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
size_t expectedSize = directSubmission.getSizeStartSection() +
directSubmission.getSizeFlushSection() +
directSubmission.getSizeTagUpdateSection() +
directSubmission.getSizeSemaphoreSection();
size_t actualSize = directSubmission.getSizeDispatch();
EXPECT_EQ(expectedSize, actualSize);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenGetEndSizeThenExpectCorrectSizeReturned) {
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
size_t expectedSize = directSubmission.getSizeEndingSection() +
directSubmission.getSizeFlushSection();
size_t actualSize = directSubmission.getSizeEnd();
EXPECT_EQ(expectedSize, actualSize);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionWhenSettingAddressInReturnCommandThenVerifyCorrectlySet) {
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
uint64_t returnAddress = 0x1A2BF000;
void *space = directSubmission.ringCommandStream.getSpace(sizeof(MI_BATCH_BUFFER_START));
directSubmission.setReturnAddress(space, returnAddress);
MI_BATCH_BUFFER_START *bbStart = reinterpret_cast<MI_BATCH_BUFFER_START *>(space);
EXPECT_EQ(returnAddress, bbStart->getBatchBufferStartAddressGraphicsaddress472());
}
HWTEST_F(DirectSubmissionTest, whenDirectSubmissionInitializedThenExpectCreatedAllocationsFreed) {
MemoryManager *memoryManager = pDevice->getExecutionEnvironment()->memoryManager.get();
std::unique_ptr<MockDirectSubmissionHw<FamilyType>> directSubmission =
std::make_unique<MockDirectSubmissionHw<FamilyType>>(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
directSubmission->initialize(false);
GraphicsAllocation *nulledAllocation = directSubmission->ringBuffer;
directSubmission->ringBuffer = nullptr;
directSubmission.reset(nullptr);
memoryManager->freeGraphicsMemory(nulledAllocation);
directSubmission =
std::make_unique<MockDirectSubmissionHw<FamilyType>>(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
directSubmission->initialize(false);
nulledAllocation = directSubmission->ringBuffer2;
directSubmission->ringBuffer2 = nullptr;
directSubmission.reset(nullptr);
memoryManager->freeGraphicsMemory(nulledAllocation);
directSubmission =
std::make_unique<MockDirectSubmissionHw<FamilyType>>(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
directSubmission->initialize(false);
nulledAllocation = directSubmission->semaphores;
directSubmission->semaphores = nullptr;
directSubmission.reset(nullptr);
memoryManager->freeGraphicsMemory(nulledAllocation);
}
struct DirectSubmissionDispatchBufferFixture : public DirectSubmissionFixture {
void SetUp() {
DirectSubmissionFixture::SetUp();
MemoryManager *memoryManager = pDevice->getExecutionEnvironment()->memoryManager.get();
const AllocationProperties commandBufferProperties{pDevice->getRootDeviceIndex(),
true, 0x1000,
GraphicsAllocation::AllocationType::COMMAND_BUFFER,
false};
commandBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandBufferProperties);
batchBuffer.endCmdPtr = &bbStart[0];
batchBuffer.commandBufferAllocation = commandBuffer;
batchBuffer.usedSize = 0x40;
}
void TearDown() {
MemoryManager *memoryManager = pDevice->getExecutionEnvironment()->memoryManager.get();
memoryManager->freeGraphicsMemory(commandBuffer);
DirectSubmissionFixture::TearDown();
}
BatchBuffer batchBuffer;
uint8_t bbStart[64];
GraphicsAllocation *commandBuffer;
};
using DirectSubmissionDispatchBufferTest = Test<DirectSubmissionDispatchBufferFixture>;
HWTEST_F(DirectSubmissionDispatchBufferTest,
givenDirectSubmissionRingStartAndSwitchBuffersWhenDispatchingCommandBufferThenExpectDispatchInCommandBufferAndQueueCountIncrease) {
FlushStampTracker flushStamp(true);
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(true);
EXPECT_TRUE(ret);
GraphicsAllocation *oldRingAllocation = directSubmission.ringCommandStream.getGraphicsAllocation();
EXPECT_EQ(0u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(1u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(1u, directSubmission.submitCount);
size_t submitSize = directSubmission.cmdDispatcher->getSizePreemption() +
directSubmission.getSizeSemaphoreSection();
EXPECT_EQ(submitSize, directSubmission.submitSize);
EXPECT_EQ(oldRingAllocation->getGpuAddress(), directSubmission.submitGpuAddress);
EXPECT_EQ(1u, directSubmission.handleResidencyCount);
size_t sizeUsed = directSubmission.ringCommandStream.getUsed();
ret = directSubmission.dispatchCommandBuffer(batchBuffer, flushStamp);
EXPECT_TRUE(ret);
EXPECT_EQ(oldRingAllocation, directSubmission.ringCommandStream.getGraphicsAllocation());
EXPECT_EQ(1u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(2u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(1u, directSubmission.submitCount);
EXPECT_EQ(2u, directSubmission.handleResidencyCount);
EXPECT_EQ(sizeUsed + directSubmission.getSizeDispatch(), directSubmission.ringCommandStream.getUsed());
EXPECT_TRUE(directSubmission.ringStart);
}
HWTEST_F(DirectSubmissionDispatchBufferTest,
givenDirectSubmissionRingNotStartAndSwitchBuffersWhenDispatchingCommandBufferThenExpectDispatchInCommandBufferQueueCountIncreaseAndSubmitToGpu) {
FlushStampTracker flushStamp(true);
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
GraphicsAllocation *oldRingAllocation = directSubmission.ringCommandStream.getGraphicsAllocation();
EXPECT_EQ(0u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(1u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(0u, directSubmission.submitCount);
EXPECT_EQ(1u, directSubmission.handleResidencyCount);
ret = directSubmission.dispatchCommandBuffer(batchBuffer, flushStamp);
EXPECT_TRUE(ret);
EXPECT_EQ(oldRingAllocation, directSubmission.ringCommandStream.getGraphicsAllocation());
EXPECT_EQ(1u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(2u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(1u, directSubmission.submitCount);
size_t submitSize = directSubmission.getSizeDispatch();
EXPECT_EQ(submitSize, directSubmission.submitSize);
EXPECT_EQ(oldRingAllocation->getGpuAddress(), directSubmission.submitGpuAddress);
EXPECT_EQ(1u, directSubmission.handleResidencyCount);
EXPECT_EQ(directSubmission.getSizeDispatch(), directSubmission.ringCommandStream.getUsed());
EXPECT_TRUE(directSubmission.ringStart);
}
HWTEST_F(DirectSubmissionDispatchBufferTest,
givenDirectSubmissionRingStartWhenDispatchingCommandBufferThenExpectDispatchInCommandBufferAndQueueCountIncrease) {
FlushStampTracker flushStamp(true);
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(true);
EXPECT_TRUE(ret);
GraphicsAllocation *oldRingAllocation = directSubmission.ringCommandStream.getGraphicsAllocation();
EXPECT_EQ(0u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(1u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(1u, directSubmission.submitCount);
size_t submitSize = directSubmission.cmdDispatcher->getSizePreemption() +
directSubmission.getSizeSemaphoreSection();
EXPECT_EQ(submitSize, directSubmission.submitSize);
EXPECT_EQ(oldRingAllocation->getGpuAddress(), directSubmission.submitGpuAddress);
EXPECT_EQ(1u, directSubmission.handleResidencyCount);
directSubmission.ringCommandStream.getSpace(directSubmission.ringCommandStream.getAvailableSpace() -
directSubmission.getSizeSwitchRingBufferSection());
ret = directSubmission.dispatchCommandBuffer(batchBuffer, flushStamp);
EXPECT_TRUE(ret);
EXPECT_NE(oldRingAllocation, directSubmission.ringCommandStream.getGraphicsAllocation());
EXPECT_EQ(1u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(2u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(1u, directSubmission.submitCount);
EXPECT_EQ(2u, directSubmission.handleResidencyCount);
EXPECT_EQ(directSubmission.getSizeDispatch(), directSubmission.ringCommandStream.getUsed());
EXPECT_TRUE(directSubmission.ringStart);
}
HWTEST_F(DirectSubmissionDispatchBufferTest,
givenDirectSubmissionRingNotStartWhenDispatchingCommandBufferThenExpectDispatchInCommandBufferQueueCountIncreaseAndSubmitToGpu) {
FlushStampTracker flushStamp(true);
MockDirectSubmissionHw<FamilyType> directSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = directSubmission.initialize(false);
EXPECT_TRUE(ret);
EXPECT_EQ(0u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(1u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(0u, directSubmission.submitCount);
EXPECT_EQ(1u, directSubmission.handleResidencyCount);
GraphicsAllocation *oldRingAllocation = directSubmission.ringCommandStream.getGraphicsAllocation();
directSubmission.ringCommandStream.getSpace(directSubmission.ringCommandStream.getAvailableSpace() -
directSubmission.getSizeSwitchRingBufferSection());
uint64_t submitGpuVa = oldRingAllocation->getGpuAddress() + directSubmission.ringCommandStream.getUsed();
ret = directSubmission.dispatchCommandBuffer(batchBuffer, flushStamp);
EXPECT_TRUE(ret);
EXPECT_NE(oldRingAllocation, directSubmission.ringCommandStream.getGraphicsAllocation());
EXPECT_EQ(1u, directSubmission.semaphoreData->QueueWorkCount);
EXPECT_EQ(2u, directSubmission.currentQueueWorkCount);
EXPECT_EQ(1u, directSubmission.submitCount);
size_t submitSize = directSubmission.getSizeSwitchRingBufferSection();
EXPECT_EQ(submitSize, directSubmission.submitSize);
EXPECT_EQ(submitGpuVa, directSubmission.submitGpuAddress);
EXPECT_EQ(1u, directSubmission.handleResidencyCount);
EXPECT_EQ(directSubmission.getSizeDispatch(), directSubmission.ringCommandStream.getUsed());
EXPECT_TRUE(directSubmission.ringStart);
}
HWTEST_F(DirectSubmissionTest, givenSuperBaseCsrWhenCheckingDirectSubmissionAvailableThenReturnFalse) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.csrSuperBaseCallDirectSubmissionAvailable = true;
int32_t executionStamp = 0;
std::unique_ptr<MockCsr<FamilyType>> mockCsr =
std::make_unique<MockCsr<FamilyType>>(executionStamp, *pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
bool ret = mockCsr->isDirectSubmissionEnabled();
EXPECT_FALSE(ret);
}
HWTEST_F(DirectSubmissionTest, givenBaseCsrWhenCheckingDirectSubmissionAvailableThenReturnFalse) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.csrBaseCallDirectSubmissionAvailable = true;
int32_t executionStamp = 0;
std::unique_ptr<MockCsr<FamilyType>> mockCsr =
std::make_unique<MockCsr<FamilyType>>(executionStamp, *pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
bool ret = mockCsr->isDirectSubmissionEnabled();
EXPECT_FALSE(ret);
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionAvailableWhenProgrammingEndingCommandThenUseBatchBufferStart) {
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
int32_t executionStamp = 0;
std::unique_ptr<MockCsr<FamilyType>> mockCsr =
std::make_unique<MockCsr<FamilyType>>(executionStamp, *pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
mockCsr->directSubmissionAvailable = true;
bool ret = mockCsr->isDirectSubmissionEnabled();
EXPECT_TRUE(ret);
void *location = nullptr;
uint8_t buffer[128];
mockCsr->commandStream.replaceBuffer(&buffer[0], 128u);
mockCsr->programEndingCmd(mockCsr->commandStream, &location, ret);
EXPECT_EQ(sizeof(MI_BATCH_BUFFER_START), mockCsr->commandStream.getUsed());
DispatchFlags dispatchFlags = DispatchFlagsHelper::createDefaultDispatchFlags();
dispatchFlags.epilogueRequired = true;
size_t expectedSize = sizeof(MI_BATCH_BUFFER_START) +
mockCsr->getCmdSizeForEpilogueCommands(dispatchFlags);
expectedSize = alignUp(expectedSize, MemoryConstants::cacheLineSize);
EXPECT_EQ(expectedSize, mockCsr->getCmdSizeForEpilogue(dispatchFlags));
}
HWTEST_F(DirectSubmissionTest, whenInitDirectSubmissionFailThenEngineIsNotCreated) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.csrFailInitDirectSubmission = true;
bool ret = pDevice->createEngine(0u, aub_stream::ENGINE_RCS);
EXPECT_FALSE(ret);
}

View File

@@ -1,16 +0,0 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_DIRECT_SUBMISSION_DISPATCHERS_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/blitter_dispatcher_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/dispatcher_fixture.cpp
${CMAKE_CURRENT_SOURCE_DIR}/dispatcher_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/render_dispatcher_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_DIRECT_SUBMISSION_DISPATCHERS_TESTS ${NEO_CORE_DIRECT_SUBMISSION_DISPATCHERS_TESTS})
add_subdirectories()

View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/direct_submission/dispatchers/blitter_dispatcher.h"
#include "direct_submission/dispatchers/dispatcher_fixture.h"
#include "test.h"
using BlitterDispatcheTest = Test<DispatcherFixture>;
using namespace NEO;
HWTEST_F(BlitterDispatcheTest, givenBlitterWhenAskingForPreemptionCmdSizeThenReturnZero) {
BlitterDispatcher<FamilyType> blitterDispatcher;
EXPECT_EQ(0u, blitterDispatcher.getSizePreemption());
}
HWTEST_F(BlitterDispatcheTest, givenBlitterWhenDispatchingPreemptionCmdThenDispatchNothing) {
BlitterDispatcher<FamilyType> blitterDispatcher;
blitterDispatcher.dispatchPreemption(cmdBuffer);
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
HWTEST_F(BlitterDispatcheTest, givenBlitterWhenAskingForMonitorFenceCmdSizeThenReturnZero) {
BlitterDispatcher<FamilyType> blitterDispatcher;
EXPECT_EQ(0u, blitterDispatcher.getSizeMonitorFence(pDevice->getHardwareInfo()));
}
HWTEST_F(BlitterDispatcheTest, givenBlitterWhenDispatchingMonitorFenceCmdThenDispatchNothing) {
BlitterDispatcher<FamilyType> blitterDispatcher;
blitterDispatcher.dispatchMonitorFence(cmdBuffer, MemoryConstants::pageSize64k, 1ull, pDevice->getHardwareInfo());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
HWTEST_F(BlitterDispatcheTest, givenBlitterWhenAskingForCacheFlushCmdSizeThenReturnZero) {
BlitterDispatcher<FamilyType> blitterDispatcher;
EXPECT_EQ(0u, blitterDispatcher.getSizeCacheFlush(pDevice->getHardwareInfo()));
}
HWTEST_F(BlitterDispatcheTest, givenBlitterWhenDispatchingCacheFlushCmdThenDispatchNothing) {
BlitterDispatcher<FamilyType> blitterDispatcher;
blitterDispatcher.dispatchCacheFlush(cmdBuffer, pDevice->getHardwareInfo());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}

View File

@@ -1,24 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "direct_submission/dispatchers/dispatcher_fixture.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/memory_manager/memory_constants.h"
void DispatcherFixture::SetUp() {
DeviceFixture::SetUp();
bufferAllocation = alignedMalloc(MemoryConstants::pageSize, MemoryConstants::pageSize);
cmdBuffer.replaceBuffer(bufferAllocation, MemoryConstants::pageSize);
}
void DispatcherFixture::TearDown() {
alignedFree(bufferAllocation);
DeviceFixture::TearDown();
}

View File

@@ -1,18 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/linear_stream.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
class DispatcherFixture : public DeviceFixture {
public:
void SetUp();
void TearDown();
NEO::LinearStream cmdBuffer;
void *bufferAllocation;
};

View File

@@ -1,126 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/direct_submission/dispatchers/render_dispatcher.h"
#include "direct_submission/dispatchers/dispatcher_fixture.h"
#include "fixtures/preemption_fixture.h"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "test.h"
using RenderDispatcheTest = Test<DispatcherFixture>;
using namespace NEO;
HWTEST_F(RenderDispatcheTest, givenRenderWhenAskingForPreemptionCmdSizeThenReturnSetMmioCmdSize) {
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
size_t expectedCmdSize = 0u;
if (GetPreemptionTestHwDetails<FamilyType>().supportsPreemptionProgramming()) {
expectedCmdSize = sizeof(MI_LOAD_REGISTER_IMM);
}
RenderDispatcher<FamilyType> renderDispatcher;
EXPECT_EQ(expectedCmdSize, renderDispatcher.getSizePreemption());
}
HWTEST_F(RenderDispatcheTest, givenRenderWhenAddingPreemptionCmdThenExpectProperMmioAddress) {
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
auto preemptionDetails = GetPreemptionTestHwDetails<FamilyType>();
RenderDispatcher<FamilyType> renderDispatcher;
renderDispatcher.dispatchPreemption(cmdBuffer);
HardwareParse hwParse;
hwParse.parseCommands<FamilyType>(cmdBuffer);
MI_LOAD_REGISTER_IMM *immCmd = hwParse.getCommand<MI_LOAD_REGISTER_IMM>();
if (preemptionDetails.supportsPreemptionProgramming()) {
ASSERT_NE(nullptr, immCmd);
uint32_t expectedMmio = preemptionDetails.regAddress;
uint32_t expectedValue = preemptionDetails.modeToRegValueMap[PreemptionMode::MidBatch];
EXPECT_EQ(expectedMmio, immCmd->getRegisterOffset());
EXPECT_EQ(expectedValue, immCmd->getDataDword());
} else {
EXPECT_EQ(nullptr, immCmd);
}
}
HWTEST_F(RenderDispatcheTest, givenRenderWhenAskingForMonitorFenceCmdSizeThenReturnRequiredPipeControlCmdSize) {
size_t expectedSize = MemorySynchronizationCommands<FamilyType>::getSizeForPipeControlWithPostSyncOperation(hardwareInfo);
RenderDispatcher<FamilyType> renderDispatcher;
EXPECT_EQ(expectedSize, renderDispatcher.getSizeMonitorFence(hardwareInfo));
}
HWTEST_F(RenderDispatcheTest, givenRenderWhenAddingMonitorFenceCmdThenExpectPipeControlWithProperAddressAndValue) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
using POST_SYNC_OPERATION = typename FamilyType::PIPE_CONTROL::POST_SYNC_OPERATION;
uint64_t gpuVa = 0xFF00FF0000ull;
uint64_t value = 0x102030;
uint32_t gpuVaLow = static_cast<uint32_t>(gpuVa & 0x0000FFFFFFFFull);
uint32_t gpuVaHigh = static_cast<uint32_t>(gpuVa >> 32);
RenderDispatcher<FamilyType> renderDispatcher;
renderDispatcher.dispatchMonitorFence(cmdBuffer, gpuVa, value, hardwareInfo);
HardwareParse hwParse;
hwParse.parseCommands<FamilyType>(cmdBuffer);
bool foundMonitorFence = false;
for (auto &it : hwParse.cmdList) {
PIPE_CONTROL *pipeControl = genCmdCast<PIPE_CONTROL *>(it);
if (pipeControl) {
foundMonitorFence =
(pipeControl->getPostSyncOperation() == POST_SYNC_OPERATION::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA) &&
(pipeControl->getAddress() == gpuVaLow) &&
(pipeControl->getAddressHigh() == gpuVaHigh) &&
(pipeControl->getImmediateData() == value);
if (foundMonitorFence) {
break;
}
}
}
EXPECT_TRUE(foundMonitorFence);
}
HWTEST_F(RenderDispatcheTest, givenRenderWhenAskingForCacheFlushCmdSizeThenReturnSetRequiredPipeControls) {
size_t expectedSize = MemorySynchronizationCommands<FamilyType>::getSizeForFullCacheFlush();
RenderDispatcher<FamilyType> renderDispatcher;
size_t actualSize = renderDispatcher.getSizeCacheFlush(hardwareInfo);
EXPECT_EQ(expectedSize, actualSize);
}
HWTEST_F(RenderDispatcheTest, givenRenderWhenAddingCacheFlushCmdThenExpectPipeControlWithProperFields) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
RenderDispatcher<FamilyType> renderDispatcher;
renderDispatcher.dispatchCacheFlush(cmdBuffer, hardwareInfo);
HardwareParse hwParse;
hwParse.parseCommands<FamilyType>(cmdBuffer);
bool foundCacheFlush = false;
for (auto &it : hwParse.cmdList) {
PIPE_CONTROL *pipeControl = genCmdCast<PIPE_CONTROL *>(it);
if (pipeControl) {
foundCacheFlush =
pipeControl->getRenderTargetCacheFlushEnable() &&
pipeControl->getInstructionCacheInvalidateEnable() &&
pipeControl->getTextureCacheInvalidationEnable() &&
pipeControl->getPipeControlFlushEnable() &&
pipeControl->getConstantCacheInvalidationEnable() &&
pipeControl->getStateCacheInvalidationEnable();
if (foundCacheFlush) {
break;
}
}
}
EXPECT_TRUE(foundCacheFlush);
}

View File

@@ -1,14 +0,0 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_DIRECT_SUBMISSION_LINUX_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/drm_direct_submission_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_DIRECT_SUBMISSION_LINUX_TESTS ${NEO_CORE_DIRECT_SUBMISSION_LINUX_TESTS})
add_subdirectories()

View File

@@ -1,74 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/direct_submission/dispatchers/render_dispatcher.h"
#include "shared/source/direct_submission/linux/drm_direct_submission.h"
#include "shared/source/os_interface/linux/os_context_linux.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/os_interface/linux/drm_mock.h"
#include "test.h"
#include <memory>
struct DrmDirectSubmissionFixture : public DeviceFixture {
void SetUp() {
DeviceFixture::SetUp();
osContext = std::make_unique<OsContextLinux>(drmMock, 0u, 0u, aub_stream::ENGINE_RCS, PreemptionMode::ThreadGroup, false);
}
void TearDown() {
DeviceFixture::TearDown();
}
std::unique_ptr<OsContextLinux> osContext;
DrmMock drmMock;
};
template <typename GfxFamily>
struct MockDrmDirectSubmission : public DrmDirectSubmission<GfxFamily> {
MockDrmDirectSubmission(Device &device,
std::unique_ptr<Dispatcher> cmdDispatcher,
OsContext &osContext)
: DrmDirectSubmission<GfxFamily>(device, std::move(cmdDispatcher), osContext) {
}
using BaseClass = DrmDirectSubmission<GfxFamily>;
using BaseClass::allocateOsResources;
using BaseClass::getTagAddressValue;
using BaseClass::handleResidency;
using BaseClass::submit;
using BaseClass::switchRingBuffers;
using BaseClass::updateTagValue;
};
using DrmDirectSubmissionTest = Test<DrmDirectSubmissionFixture>;
using namespace NEO;
HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplementationThenExpectAllFailAsNotImplemented) {
MockDrmDirectSubmission<FamilyType> drmDirectSubmission(*pDevice,
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
DirectSubmissionAllocations allocations;
EXPECT_FALSE(drmDirectSubmission.allocateOsResources(allocations));
uint64_t gpuAddress = 0x1000;
size_t size = 0x1000;
EXPECT_FALSE(drmDirectSubmission.submit(gpuAddress, size));
EXPECT_FALSE(drmDirectSubmission.handleResidency());
EXPECT_EQ(0ull, drmDirectSubmission.switchRingBuffers());
EXPECT_EQ(0ull, drmDirectSubmission.updateTagValue());
TagData tagData = {1ull, 1ull};
drmDirectSubmission.getTagAddressValue(tagData);
EXPECT_EQ(0ull, tagData.tagAddress);
EXPECT_EQ(0ull, tagData.tagValue);
}

View File

@@ -1,14 +0,0 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_DIRECT_SUBMISSION_WINDOWS_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/wddm_direct_submission_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_DIRECT_SUBMISSION_WINDOWS_TESTS ${NEO_CORE_DIRECT_SUBMISSION_WINDOWS_TESTS})
add_subdirectories()

View File

@@ -1,380 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/direct_submission/dispatchers/render_dispatcher.h"
#include "shared/source/direct_submission/windows/wddm_direct_submission.h"
#include "shared/source/os_interface/windows/os_context_win.h"
#include "shared/source/os_interface/windows/wddm/wddm.h"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/mocks/mock_device.h"
#include "opencl/test/unit_test/os_interface/windows/wddm_fixture.h"
struct WddmDirectSubmissionFixture : public WddmFixture {
void SetUp() override {
WddmFixture::SetUp();
wddm->wddmInterface.reset(new WddmMockInterface20(*wddm));
wddmMockInterface = static_cast<WddmMockInterface20 *>(wddm->wddmInterface.get());
osContext = std::make_unique<OsContextWin>(*wddm, 0u, 0u, aub_stream::ENGINE_RCS, PreemptionMode::ThreadGroup, false);
device.reset(MockDevice::create<MockDevice>(executionEnvironment, 0u));
device->setPreemptionMode(PreemptionMode::ThreadGroup);
}
WddmMockInterface20 *wddmMockInterface;
std::unique_ptr<MockDevice> device;
std::unique_ptr<OsContextWin> osContext;
};
template <typename GfxFamily>
struct MockWddmDirectSubmission : public WddmDirectSubmission<GfxFamily> {
MockWddmDirectSubmission(Device &device,
std::unique_ptr<Dispatcher> cmdDispatcher,
OsContext &osContext)
: WddmDirectSubmission<GfxFamily>(device, std::move(cmdDispatcher), osContext) {
}
using BaseClass = WddmDirectSubmission<GfxFamily>;
using BaseClass::allocateOsResources;
using BaseClass::commandBufferHeader;
using BaseClass::completionRingBuffers;
using BaseClass::currentRingBuffer;
using BaseClass::getSizeSwitchRingBufferSection;
using BaseClass::getTagAddressValue;
using BaseClass::handleCompletionRingBuffer;
using BaseClass::handleResidency;
using BaseClass::osContextWin;
using BaseClass::ringBuffer;
using BaseClass::ringBuffer2;
using BaseClass::ringCommandStream;
using BaseClass::ringFence;
using BaseClass::ringStart;
using BaseClass::semaphores;
using BaseClass::submit;
using BaseClass::switchRingBuffers;
using BaseClass::updateTagValue;
using BaseClass::wddm;
using typename BaseClass::RingBufferUse;
};
using WddmDirectSubmissionTest = WddmDirectSubmissionFixture;
using namespace NEO;
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenDirectIsInitializedAndStartedThenExpectProperCommandsDispatched) {
std::unique_ptr<MockWddmDirectSubmission<FamilyType>> wddmDirectSubmission =
std::make_unique<MockWddmDirectSubmission<FamilyType>>(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
EXPECT_EQ(1u, wddmDirectSubmission->commandBufferHeader->NeedsMidBatchPreEmptionSupport);
bool ret = wddmDirectSubmission->initialize(true);
EXPECT_TRUE(ret);
EXPECT_TRUE(wddmDirectSubmission->ringStart);
EXPECT_NE(nullptr, wddmDirectSubmission->ringBuffer);
EXPECT_NE(nullptr, wddmDirectSubmission->ringBuffer2);
EXPECT_NE(nullptr, wddmDirectSubmission->semaphores);
EXPECT_EQ(1u, wddm->makeResidentResult.called);
EXPECT_EQ(3u, wddm->makeResidentResult.handleCount);
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
EXPECT_EQ(1u, wddm->submitResult.called);
EXPECT_NE(0u, wddmDirectSubmission->ringCommandStream.getUsed());
*wddmDirectSubmission->ringFence.cpuAddress = 1ull;
wddmDirectSubmission->completionRingBuffers[wddmDirectSubmission->currentRingBuffer] = 2ull;
wddmDirectSubmission.reset(nullptr);
EXPECT_EQ(1u, wddm->waitFromCpuResult.called);
EXPECT_EQ(1u, wddmMockInterface->destroyMonitorFenceCalled);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenDirectIsInitializedAndNotStartedThenExpectNoCommandsDispatched) {
device->setPreemptionMode(PreemptionMode::Disabled);
std::unique_ptr<MockWddmDirectSubmission<FamilyType>> wddmDirectSubmission =
std::make_unique<MockWddmDirectSubmission<FamilyType>>(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
EXPECT_EQ(0u, wddmDirectSubmission->commandBufferHeader->NeedsMidBatchPreEmptionSupport);
bool ret = wddmDirectSubmission->initialize(false);
EXPECT_TRUE(ret);
EXPECT_FALSE(wddmDirectSubmission->ringStart);
EXPECT_NE(nullptr, wddmDirectSubmission->ringBuffer);
EXPECT_NE(nullptr, wddmDirectSubmission->ringBuffer2);
EXPECT_NE(nullptr, wddmDirectSubmission->semaphores);
EXPECT_EQ(1u, wddm->makeResidentResult.called);
EXPECT_EQ(3u, wddm->makeResidentResult.handleCount);
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
EXPECT_EQ(0u, wddm->submitResult.called);
EXPECT_EQ(0u, wddmDirectSubmission->ringCommandStream.getUsed());
wddmDirectSubmission.reset(nullptr);
EXPECT_EQ(0u, wddm->waitFromCpuResult.called);
EXPECT_EQ(1u, wddmMockInterface->destroyMonitorFenceCalled);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSubmitingCmdBufferThenExpectPassWddmContextAndProperHeader) {
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
bool ret = wddmDirectSubmission.initialize(false);
EXPECT_TRUE(ret);
uint64_t gpuAddress = 0xFF00FF000;
size_t size = 0xF0;
ret = wddmDirectSubmission.submit(gpuAddress, size);
EXPECT_TRUE(ret);
EXPECT_EQ(1u, wddm->submitResult.called);
EXPECT_EQ(gpuAddress, wddm->submitResult.commandBufferSubmitted);
EXPECT_EQ(size, wddm->submitResult.size);
EXPECT_EQ(wddmDirectSubmission.commandBufferHeader.get(), wddm->submitResult.commandHeaderSubmitted);
EXPECT_EQ(&wddmDirectSubmission.ringFence, wddm->submitResult.submitArgs.monitorFence);
EXPECT_EQ(osContext->getWddmContextHandle(), wddm->submitResult.submitArgs.contextHandle);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesThenExpectRingMonitorFenceCreatedAndAllocationsResident) {
MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get();
const auto allocationSize = MemoryConstants::pageSize;
const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(),
true, allocationSize,
GraphicsAllocation::AllocationType::RING_BUFFER,
false};
GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties);
ASSERT_NE(nullptr, ringBuffer);
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
DirectSubmissionAllocations allocations;
allocations.push_back(ringBuffer);
bool ret = wddmDirectSubmission.allocateOsResources(allocations);
EXPECT_TRUE(ret);
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
EXPECT_EQ(1u, wddm->makeResidentResult.called);
EXPECT_EQ(1u, wddm->makeResidentResult.handleCount);
memoryManager->freeGraphicsMemory(ringBuffer);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesFenceCreationFailsThenExpectRingMonitorFenceNotCreatedAndAllocationsNotResident) {
MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get();
const auto allocationSize = MemoryConstants::pageSize;
const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(),
true, allocationSize,
GraphicsAllocation::AllocationType::RING_BUFFER,
false};
GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties);
ASSERT_NE(nullptr, ringBuffer);
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
DirectSubmissionAllocations allocations;
allocations.push_back(ringBuffer);
wddmMockInterface->createMonitoredFenceCalledFail = true;
bool ret = wddmDirectSubmission.allocateOsResources(allocations);
EXPECT_FALSE(ret);
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
EXPECT_EQ(0u, wddm->makeResidentResult.called);
EXPECT_EQ(0u, wddm->makeResidentResult.handleCount);
memoryManager->freeGraphicsMemory(ringBuffer);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesResidencyFailsThenExpectRingMonitorFenceCreatedAndAllocationsNotResident) {
MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get();
const auto allocationSize = MemoryConstants::pageSize;
const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(),
true, allocationSize,
GraphicsAllocation::AllocationType::RING_BUFFER,
false};
GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties);
ASSERT_NE(nullptr, ringBuffer);
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
DirectSubmissionAllocations allocations;
allocations.push_back(ringBuffer);
wddm->callBaseMakeResident = false;
wddm->makeResidentStatus = false;
bool ret = wddmDirectSubmission.allocateOsResources(allocations);
EXPECT_FALSE(ret);
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
//expect 2 makeResident calls, due to fail on 1st and then retry (which also fails)
EXPECT_EQ(2u, wddm->makeResidentResult.called);
EXPECT_EQ(1u, wddm->makeResidentResult.handleCount);
memoryManager->freeGraphicsMemory(ringBuffer);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenGettingTagDataThenExpectContextMonitorFence) {
uint64_t address = 0xFF00FF0000ull;
uint64_t value = 0x12345678ull;
MonitoredFence &contextFence = osContext->getResidencyController().getMonitoredFence();
contextFence.gpuAddress = address;
contextFence.currentFenceValue = value;
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
TagData tagData;
wddmDirectSubmission.getTagAddressValue(tagData);
EXPECT_EQ(address, tagData.tagAddress);
EXPECT_EQ(value, tagData.tagValue);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenHandleResidencyThenExpectWddmWaitOnPaginfFenceFromCpuCalled) {
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
wddmDirectSubmission.handleResidency();
EXPECT_EQ(1u, wddm->waitOnPagingFenceFromCpuResult.called);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenHandlingRingBufferCompletionThenExpectWaitFromCpuWithCorrectFenceValue) {
uint64_t address = 0xFF00FF0000ull;
uint64_t value = 0x12345678ull;
MonitoredFence &contextFence = osContext->getResidencyController().getMonitoredFence();
contextFence.gpuAddress = address;
contextFence.currentFenceValue = value;
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
uint64_t completionValue = 0x12345679ull;
wddmDirectSubmission.handleCompletionRingBuffer(completionValue, contextFence);
EXPECT_EQ(1u, wddm->waitFromCpuResult.called);
EXPECT_EQ(completionValue, wddm->waitFromCpuResult.uint64ParamPassed);
EXPECT_EQ(address, wddm->waitFromCpuResult.monitoredFence->gpuAddress);
EXPECT_EQ(value, wddm->waitFromCpuResult.monitoredFence->currentFenceValue);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSwitchingRingBufferStartedThenExpectDispatchSwitchCommandsLinearStreamUpdated) {
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
wddmDirectSubmission.initialize(true);
size_t usedSpace = wddmDirectSubmission.ringCommandStream.getUsed();
uint64_t expectedGpuVa = wddmDirectSubmission.ringBuffer->getGpuAddress() + usedSpace;
uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers();
EXPECT_EQ(expectedGpuVa, gpuVa);
EXPECT_EQ(wddmDirectSubmission.ringBuffer2, wddmDirectSubmission.ringCommandStream.getGraphicsAllocation());
LinearStream tmpCmdBuffer;
tmpCmdBuffer.replaceBuffer(wddmDirectSubmission.ringBuffer->getUnderlyingBuffer(),
wddmDirectSubmission.ringCommandStream.getMaxAvailableSpace());
tmpCmdBuffer.getSpace(usedSpace + wddmDirectSubmission.getSizeSwitchRingBufferSection());
HardwareParse hwParse;
hwParse.parseCommands<FamilyType>(tmpCmdBuffer, usedSpace);
MI_BATCH_BUFFER_START *bbStart = hwParse.getCommand<MI_BATCH_BUFFER_START>();
ASSERT_NE(nullptr, bbStart);
EXPECT_EQ(wddmDirectSubmission.ringBuffer2->getGpuAddress(), bbStart->getBatchBufferStartAddressGraphicsaddress472());
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSwitchingRingBufferNotStartedThenExpectNoSwitchCommandsLinearStreamUpdated) {
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
wddmDirectSubmission.initialize(false);
size_t usedSpace = wddmDirectSubmission.ringCommandStream.getUsed();
EXPECT_EQ(0u, usedSpace);
uint64_t expectedGpuVa = wddmDirectSubmission.ringBuffer->getGpuAddress();
uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers();
EXPECT_EQ(expectedGpuVa, gpuVa);
EXPECT_EQ(wddmDirectSubmission.ringBuffer2, wddmDirectSubmission.ringCommandStream.getGraphicsAllocation());
LinearStream tmpCmdBuffer;
tmpCmdBuffer.replaceBuffer(wddmDirectSubmission.ringBuffer->getUnderlyingBuffer(),
wddmDirectSubmission.ringCommandStream.getMaxAvailableSpace());
HardwareParse hwParse;
hwParse.parseCommands<FamilyType>(tmpCmdBuffer, 0u);
MI_BATCH_BUFFER_START *bbStart = hwParse.getCommand<MI_BATCH_BUFFER_START>();
EXPECT_EQ(nullptr, bbStart);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSwitchingRingBufferStartedAndWaitFenceUpdateThenExpectWaitCalled) {
using RingBufferUse = typename MockWddmDirectSubmission<FamilyType>::RingBufferUse;
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
wddmDirectSubmission.initialize(true);
uint64_t expectedWaitFence = 0x10ull;
wddmDirectSubmission.completionRingBuffers[RingBufferUse::SecondBuffer] = expectedWaitFence;
size_t usedSpace = wddmDirectSubmission.ringCommandStream.getUsed();
uint64_t expectedGpuVa = wddmDirectSubmission.ringBuffer->getGpuAddress() + usedSpace;
uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers();
EXPECT_EQ(expectedGpuVa, gpuVa);
EXPECT_EQ(wddmDirectSubmission.ringBuffer2, wddmDirectSubmission.ringCommandStream.getGraphicsAllocation());
LinearStream tmpCmdBuffer;
tmpCmdBuffer.replaceBuffer(wddmDirectSubmission.ringBuffer->getUnderlyingBuffer(),
wddmDirectSubmission.ringCommandStream.getMaxAvailableSpace());
tmpCmdBuffer.getSpace(usedSpace + wddmDirectSubmission.getSizeSwitchRingBufferSection());
HardwareParse hwParse;
hwParse.parseCommands<FamilyType>(tmpCmdBuffer, usedSpace);
MI_BATCH_BUFFER_START *bbStart = hwParse.getCommand<MI_BATCH_BUFFER_START>();
ASSERT_NE(nullptr, bbStart);
EXPECT_EQ(wddmDirectSubmission.ringBuffer2->getGpuAddress(), bbStart->getBatchBufferStartAddressGraphicsaddress472());
EXPECT_EQ(1u, wddm->waitFromCpuResult.called);
EXPECT_EQ(expectedWaitFence, wddm->waitFromCpuResult.uint64ParamPassed);
}
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenUpdatingTagValueThenExpectCompletionRingBufferUpdated) {
uint64_t address = 0xFF00FF0000ull;
uint64_t value = 0x12345678ull;
MonitoredFence &contextFence = osContext->getResidencyController().getMonitoredFence();
contextFence.gpuAddress = address;
contextFence.currentFenceValue = value;
MockWddmDirectSubmission<FamilyType> wddmDirectSubmission(*device.get(),
std::make_unique<RenderDispatcher<FamilyType>>(),
*osContext.get());
uint64_t actualTagValue = wddmDirectSubmission.updateTagValue();
EXPECT_EQ(value, actualTagValue);
EXPECT_EQ(value + 1, contextFence.currentFenceValue);
EXPECT_EQ(value, wddmDirectSubmission.completionRingBuffers[wddmDirectSubmission.currentRingBuffer]);
}

View File

@@ -1,19 +0,0 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_ENCODERS_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_atomic.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_command_buffer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_dispatch_kernel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_math.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_media_interface_descriptor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_semaphore.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_set_mmio.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_encode_states.cpp
)
add_subdirectories()
set_property(GLOBAL PROPERTY NEO_CORE_ENCODERS_TESTS ${NEO_CORE_ENCODERS_TESTS})

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/ptr_math.h"
#include "fixtures/command_container_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
using namespace NEO;
using CommandEncodeAtomic = Test<CommandEncodeStatesFixture>;
HWTEST_F(CommandEncodeAtomic, programMiAtomic) {
using MI_ATOMIC = typename FamilyType::MI_ATOMIC;
MI_ATOMIC miAtomic;
EncodeAtomic<FamilyType>::programMiAtomic(&miAtomic, 0x123400, MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_4B_DECREMENT,
MI_ATOMIC::DATA_SIZE::DATA_SIZE_DWORD);
EXPECT_EQ(MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_4B_DECREMENT, miAtomic.getAtomicOpcode());
EXPECT_EQ(MI_ATOMIC::DATA_SIZE::DATA_SIZE_DWORD, miAtomic.getDataSize());
EXPECT_EQ(0x123400u, miAtomic.getMemoryAddress());
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_container/cmdcontainer.h"
#include "shared/source/command_container/command_encoder.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "test.h"
using namespace NEO;
using EncodeBatchBufferStartOrEndTest = Test<DeviceFixture>;
HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBEndThenCommandIsAdded) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeBatchBufferStartOrEnd<FamilyType>::programBatchBufferEnd(cmdContainer);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_BATCH_BUFFER_END = typename FamilyType::MI_BATCH_BUFFER_END;
auto itor = find<MI_BATCH_BUFFER_END *>(commands.begin(), commands.end());
ASSERT_NE(itor, commands.end());
}
HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBStartThenCommandIsAdded) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeBatchBufferStartOrEnd<FamilyType>::programBatchBufferStart(cmdContainer.getCommandStream(), 0, true);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
auto itor = find<MI_BATCH_BUFFER_START *>(commands.begin(), commands.end());
ASSERT_NE(itor, commands.end());
}
HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBStartWithSecondLevelParameterThenCommandIsProgrammedCorrectly) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeBatchBufferStartOrEnd<FamilyType>::programBatchBufferStart(cmdContainer.getCommandStream(), 0, true);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
auto itor = find<MI_BATCH_BUFFER_START *>(commands.begin(), commands.end());
ASSERT_NE(itor, commands.end());
{
auto cmd = genCmdCast<MI_BATCH_BUFFER_START *>(*itor);
EXPECT_EQ(MI_BATCH_BUFFER_START::SECOND_LEVEL_BATCH_BUFFER_SECOND_LEVEL_BATCH, cmd->getSecondLevelBatchBuffer());
}
}
HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBStartWithFirstLevelParameterThenCommandIsProgrammedCorrectly) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeBatchBufferStartOrEnd<FamilyType>::programBatchBufferStart(cmdContainer.getCommandStream(), 0, false);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
auto itor = find<MI_BATCH_BUFFER_START *>(commands.begin(), commands.end());
ASSERT_NE(itor, commands.end());
{
auto cmd = genCmdCast<MI_BATCH_BUFFER_START *>(*itor);
EXPECT_EQ(MI_BATCH_BUFFER_START::SECOND_LEVEL_BATCH_BUFFER_FIRST_LEVEL_BATCH, cmd->getSecondLevelBatchBuffer());
}
}
HWTEST_F(EncodeBatchBufferStartOrEndTest, givenGpuAddressWhenEncodeBBStartThenAddressIsProgrammedCorrectly) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
uint64_t gpuAddress = 12 * MemoryConstants::pageSize;
EncodeBatchBufferStartOrEnd<FamilyType>::programBatchBufferStart(cmdContainer.getCommandStream(), gpuAddress, false);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
auto itor = find<MI_BATCH_BUFFER_START *>(commands.begin(), commands.end());
ASSERT_NE(itor, commands.end());
{
auto cmd = genCmdCast<MI_BATCH_BUFFER_START *>(*itor);
EXPECT_EQ(gpuAddress, cmd->getBatchBufferStartAddressGraphicsaddress472());
}
}

View File

@@ -1,322 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/ptr_math.h"
#include "fixtures/command_container_fixture.h"
#include "mocks/mock_dispatch_kernel_encoder_interface.h"
#include "opencl/source/helpers/hardware_commands_helper.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
using namespace NEO;
using CommandEncodeStatesTest = Test<CommandEncodeStatesFixture>;
TEST_F(CommandEncodeStatesTest, givenDefaultCommandConatinerGetNumIddsInBlock) {
auto numIdds = cmdContainer->getNumIddPerBlock();
EXPECT_EQ(64u, numIdds);
}
TEST_F(CommandEncodeStatesTest, givenCommandConatinerCreatedWithMaxNumAggregateIddThenVerifyGetNumIddsInBlockIsCorrect) {
auto cmdContainer = new CommandContainer(1);
auto numIdds = cmdContainer->getNumIddPerBlock();
EXPECT_EQ(1u, numIdds);
delete cmdContainer;
}
HWTEST_F(CommandEncodeStatesTest, givenenDispatchInterfaceWhenDispatchKernelThenWalkerCommandProgrammed) {
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
using WALKER_TYPE = typename FamilyType::WALKER_TYPE;
auto itorPC = find<WALKER_TYPE *>(commands.begin(), commands.end());
ASSERT_NE(itorPC, commands.end());
}
HWTEST_F(CommandEncodeStatesTest, givenCommandContainerWithUsedAvailableSizeWhenDispatchKernelThenNextCommandBufferIsAdded) {
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
auto cmdBuffersCountBefore = cmdContainer->getCmdBufferAllocations().size();
cmdContainer->getCommandStream()->getSpace(cmdContainer->getCommandStream()->getAvailableSpace() - sizeof(typename FamilyType::MI_BATCH_BUFFER_END));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
auto cmdBuffersCountAfter = cmdContainer->getCmdBufferAllocations().size();
EXPECT_GT(cmdBuffersCountAfter, cmdBuffersCountBefore);
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, givenSlmTotalSizeGraterThanZeroWhenDispatchingKernelThenSharedMemorySizeSetCorrectly) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS;
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
uint32_t slmTotalSize = 1;
EXPECT_CALL(*dispatchInterface.get(), getSlmTotalSize()).WillRepeatedly(::testing::Return(slmTotalSize));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
auto interfaceDescriptorData = static_cast<INTERFACE_DESCRIPTOR_DATA *>(cmdContainer->getIddBlock());
uint32_t expectedValue = static_cast<typename INTERFACE_DESCRIPTOR_DATA::SHARED_LOCAL_MEMORY_SIZE>(HardwareCommandsHelper<FamilyType>::computeSlmValues(slmTotalSize));
EXPECT_EQ(expectedValue, interfaceDescriptorData->getSharedLocalMemorySize());
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, givenSlmTotalSizeEqualZeroWhenDispatchingKernelThenSharedMemorySizeSetCorrectly) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS;
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
uint32_t slmTotalSize = 0;
EXPECT_CALL(*dispatchInterface.get(), getSlmTotalSize()).WillRepeatedly(::testing::Return(slmTotalSize));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
auto interfaceDescriptorData = static_cast<INTERFACE_DESCRIPTOR_DATA *>(cmdContainer->getIddBlock());
uint32_t expectedValue = INTERFACE_DESCRIPTOR_DATA::SHARED_LOCAL_MEMORY_SIZE_ENCODES_0K;
EXPECT_EQ(expectedValue, interfaceDescriptorData->getSharedLocalMemorySize());
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, givennumBindingTableOneWhenDispatchingKernelThenBindingTableOffsetIsCorrect) {
using BINDING_TABLE_STATE = typename FamilyType::BINDING_TABLE_STATE;
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
uint32_t numBindingTable = 1;
BINDING_TABLE_STATE bindingTableState;
bindingTableState.sInit();
auto ssh = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
uint32_t sizeUsed = 0x20;
ssh->getSpace(sizeUsed);
auto expectedOffset = alignUp(sizeUsed, BINDING_TABLE_STATE::SURFACESTATEPOINTER_ALIGN_SIZE);
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EXPECT_CALL(*dispatchInterface.get(), getNumSurfaceStates()).WillRepeatedly(::testing::Return(numBindingTable));
EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeap()).WillRepeatedly(::testing::Return(&bindingTableState));
EXPECT_CALL(*dispatchInterface.get(), getSizeSurfaceStateHeapData()).WillRepeatedly(::testing::Return(static_cast<uint32_t>(sizeof(BINDING_TABLE_STATE))));
EXPECT_CALL(*dispatchInterface.get(), getBindingTableOffset()).WillRepeatedly(::testing::Return(0));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
auto interfaceDescriptorData = static_cast<INTERFACE_DESCRIPTOR_DATA *>(cmdContainer->getIddBlock());
EXPECT_EQ(interfaceDescriptorData->getBindingTablePointer(), expectedOffset);
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, giveNumBindingTableZeroWhenDispatchingKernelThenBindingTableOffsetIsZero) {
using BINDING_TABLE_STATE = typename FamilyType::BINDING_TABLE_STATE;
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
uint32_t numBindingTable = 0;
BINDING_TABLE_STATE bindingTableState;
bindingTableState.sInit();
auto ssh = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
uint32_t sizeUsed = 0x20;
ssh->getSpace(sizeUsed);
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EXPECT_CALL(*dispatchInterface.get(), getNumSurfaceStates()).WillRepeatedly(::testing::Return(numBindingTable));
EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeap()).WillRepeatedly(::testing::Return(&bindingTableState));
EXPECT_CALL(*dispatchInterface.get(), getSizeSurfaceStateHeapData()).WillRepeatedly(::testing::Return(static_cast<uint32_t>(sizeof(BINDING_TABLE_STATE))));
EXPECT_CALL(*dispatchInterface.get(), getBindingTableOffset()).WillRepeatedly(::testing::Return(0));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
auto interfaceDescriptorData = static_cast<INTERFACE_DESCRIPTOR_DATA *>(cmdContainer->getIddBlock());
EXPECT_EQ(interfaceDescriptorData->getBindingTablePointer(), 0u);
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, giveNumSamplersOneWhenDispatchingKernelThensamplerStateWasCopied) {
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
uint32_t numSamplers = 1;
SAMPLER_STATE samplerState;
memset(&samplerState, 2, sizeof(SAMPLER_STATE));
auto dsh = cmdContainer->getIndirectHeap(HeapType::DYNAMIC_STATE);
auto usedBefore = dsh->getUsed();
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EXPECT_CALL(*dispatchInterface.get(), getNumSamplers()).WillRepeatedly(::testing::Return(numSamplers));
EXPECT_CALL(*dispatchInterface.get(), getSamplerTableOffset()).WillRepeatedly(::testing::Return(0));
EXPECT_CALL(*dispatchInterface.get(), getBorderColor()).WillRepeatedly(::testing::Return(0));
EXPECT_CALL(*dispatchInterface.get(), getDynamicStateHeap()).WillRepeatedly(::testing::Return(&samplerState));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
auto interfaceDescriptorData = static_cast<INTERFACE_DESCRIPTOR_DATA *>(cmdContainer->getIddBlock());
auto borderColorOffsetInDsh = usedBefore;
samplerState.setIndirectStatePointer(static_cast<uint32_t>(borderColorOffsetInDsh));
auto samplerStateOffset = interfaceDescriptorData->getSamplerStatePointer();
auto pSmplr = reinterpret_cast<SAMPLER_STATE *>(ptrOffset(dsh->getCpuBase(), samplerStateOffset));
EXPECT_EQ(memcmp(pSmplr, &samplerState, sizeof(SAMPLER_STATE)), 0);
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, giveNumSamplersZeroWhenDispatchingKernelThensamplerStateWasNotCopied) {
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
uint32_t numSamplers = 0;
SAMPLER_STATE samplerState;
memset(&samplerState, 2, sizeof(SAMPLER_STATE));
auto dsh = cmdContainer->getIndirectHeap(HeapType::DYNAMIC_STATE);
auto usedBefore = dsh->getUsed();
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EXPECT_CALL(*dispatchInterface.get(), getNumSamplers()).WillRepeatedly(::testing::Return(numSamplers));
EXPECT_CALL(*dispatchInterface.get(), getSamplerTableOffset()).WillRepeatedly(::testing::Return(0));
EXPECT_CALL(*dispatchInterface.get(), getBorderColor()).WillRepeatedly(::testing::Return(0));
EXPECT_CALL(*dispatchInterface.get(), getDynamicStateHeap()).WillRepeatedly(::testing::Return(&samplerState));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
auto interfaceDescriptorData = static_cast<INTERFACE_DESCRIPTOR_DATA *>(cmdContainer->getIddBlock());
auto borderColorOffsetInDsh = usedBefore;
samplerState.setIndirectStatePointer(static_cast<uint32_t>(borderColorOffsetInDsh));
auto samplerStateOffset = interfaceDescriptorData->getSamplerStatePointer();
auto pSmplr = reinterpret_cast<SAMPLER_STATE *>(ptrOffset(dsh->getCpuBase(), samplerStateOffset));
EXPECT_NE(memcmp(pSmplr, &samplerState, sizeof(SAMPLER_STATE)), 0);
}
HWTEST_F(CommandEncodeStatesTest, givenIndarectOffsetsCountsWhenDispatchingKernelThenCorrestMIStoreOffsetsSet) {
using MI_STORE_REGISTER_MEM = typename FamilyType::MI_STORE_REGISTER_MEM;
uint32_t dims[] = {2, 1, 1};
uint32_t offsets[] = {0x10, 0x20, 0x30};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EXPECT_CALL(*dispatchInterface.get(), hasGroupCounts()).WillRepeatedly(::testing::Return(true));
EXPECT_CALL(*dispatchInterface.get(), getCountOffsets()).WillRepeatedly(::testing::Return(offsets));
EXPECT_CALL(*dispatchInterface.get(), hasGroupSize()).WillRepeatedly(::testing::Return(false));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, true, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itor = commands.begin();
for (int i = 0; i < 3; i++) {
ASSERT_NE(itor, commands.end());
itor = find<MI_STORE_REGISTER_MEM *>(++itor, commands.end());
}
}
HWTEST_F(CommandEncodeStatesTest, givenIndarectOffsetsSizeWhenDispatchingKernelThenMiMathEncoded) {
using MI_MATH = typename FamilyType::MI_MATH;
uint32_t dims[] = {2, 1, 1};
uint32_t offsets[] = {0x10, 0x20, 0x30};
uint32_t lws[] = {1, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EXPECT_CALL(*dispatchInterface.get(), hasGroupCounts()).WillRepeatedly(::testing::Return(false));
EXPECT_CALL(*dispatchInterface.get(), getSizeOffsets()).WillRepeatedly(::testing::Return(offsets));
EXPECT_CALL(*dispatchInterface.get(), hasGroupSize()).WillRepeatedly(::testing::Return(true));
EXPECT_CALL(*dispatchInterface.get(), getLocalWorkSize()).WillRepeatedly(::testing::Return(lws));
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, true, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itor = find<MI_MATH *>(commands.begin(), commands.end());
ASSERT_NE(itor, commands.end());
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, givenCleanHeapsAndSlmNotChangedWhenDispatchKernelThenFlushNotAdded) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
cmdContainer->slmSize = 1;
EXPECT_CALL(*dispatchInterface.get(), getSlmTotalSize()).WillRepeatedly(::testing::Return(cmdContainer->slmSize));
cmdContainer->setDirtyStateForAllHeaps(false);
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itorPC = find<PIPE_CONTROL *>(commands.begin(), commands.end());
ASSERT_EQ(itorPC, commands.end());
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, givenDirtyHeapsAndSlmNotChangedWhenDispatchKernelThenHeapsAreCleanAndFlushAdded) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
cmdContainer->slmSize = 1;
EXPECT_CALL(*dispatchInterface.get(), getSlmTotalSize()).WillRepeatedly(::testing::Return(cmdContainer->slmSize));
cmdContainer->setDirtyStateForAllHeaps(true);
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itorPC = find<PIPE_CONTROL *>(commands.begin(), commands.end());
ASSERT_NE(itorPC, commands.end());
EXPECT_FALSE(cmdContainer->isAnyHeapDirty());
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, givenCleanHeapsAndSlmChangedWhenDispatchKernelThenFlushAdded) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
EXPECT_CALL(*dispatchInterface.get(), getSlmTotalSize()).WillRepeatedly(::testing::Return(cmdContainer->slmSize + 1));
cmdContainer->setDirtyStateForAllHeaps(false);
auto slmSizeBefore = cmdContainer->slmSize;
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itorPC = find<PIPE_CONTROL *>(commands.begin(), commands.end());
ASSERT_NE(itorPC, commands.end());
EXPECT_EQ(slmSizeBefore + 1, cmdContainer->slmSize);
}
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, giveNextIddInBlockZeorWhenDispatchKernelThenMediaInterfaceDescriptorEncoded) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
using MEDIA_INTERFACE_DESCRIPTOR_LOAD = typename FamilyType::MEDIA_INTERFACE_DESCRIPTOR_LOAD;
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
cmdContainer->getIndirectHeap(HeapType::DYNAMIC_STATE)->align(HardwareCommandsHelper<FamilyType>::alignInterfaceDescriptorData);
cmdContainer->setIddBlock(cmdContainer->getHeapSpaceAllowGrow(HeapType::DYNAMIC_STATE, sizeof(INTERFACE_DESCRIPTOR_DATA) * cmdContainer->getNumIddPerBlock()));
cmdContainer->nextIddInBlock = 0;
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itorPC = find<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(commands.begin(), commands.end());
ASSERT_NE(itorPC, commands.end());
}

View File

@@ -1,185 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_container/command_encoder.h"
#include "shared/source/helpers/register_offsets.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "test.h"
using namespace NEO;
using EncodeMathMMIOTest = testing::Test;
HWTEST_F(EncodeMathMMIOTest, encodeAluAddHasCorrectOpcodesOperands) {
using MI_MATH_ALU_INST_INLINE = typename FamilyType::MI_MATH_ALU_INST_INLINE;
MI_MATH_ALU_INST_INLINE aluParam[5];
uint32_t regA = ALU_REGISTER_R_0;
uint32_t regB = ALU_REGISTER_R_1;
memset(aluParam, 0, sizeof(MI_MATH_ALU_INST_INLINE) * 5);
EncodeMathMMIO<FamilyType>::encodeAluAdd(aluParam, regA, regB);
EXPECT_EQ(aluParam[0].DW0.BitField.ALUOpcode, ALU_OPCODE_LOAD);
EXPECT_EQ(aluParam[0].DW0.BitField.Operand1, ALU_REGISTER_R_SRCA);
EXPECT_EQ(aluParam[0].DW0.BitField.Operand2, regA);
EXPECT_EQ(aluParam[1].DW0.BitField.ALUOpcode, ALU_OPCODE_LOAD);
EXPECT_EQ(aluParam[1].DW0.BitField.Operand1, ALU_REGISTER_R_SRCB);
EXPECT_EQ(aluParam[1].DW0.BitField.Operand2, regB);
EXPECT_EQ(aluParam[2].DW0.BitField.ALUOpcode, ALU_OPCODE_ADD);
EXPECT_EQ(aluParam[2].DW0.BitField.Operand1, 0u);
EXPECT_EQ(aluParam[2].DW0.BitField.Operand2, 0u);
EXPECT_EQ(aluParam[3].DW0.BitField.ALUOpcode, ALU_OPCODE_STORE);
EXPECT_EQ(aluParam[3].DW0.BitField.Operand1, ALU_REGISTER_R_0);
EXPECT_EQ(aluParam[3].DW0.BitField.Operand2, ALU_REGISTER_R_ACCU);
EXPECT_EQ(aluParam[4].DW0.Value, 0u);
}
HWTEST_F(EncodeMathMMIOTest, encodeAluSubStoreCarryHasCorrectOpcodesOperands) {
using MI_MATH_ALU_INST_INLINE = typename FamilyType::MI_MATH_ALU_INST_INLINE;
MI_MATH_ALU_INST_INLINE aluParam[5];
uint32_t regA = ALU_REGISTER_R_0;
uint32_t regB = ALU_REGISTER_R_1;
uint32_t finalResultRegister = ALU_REGISTER_R_2;
memset(aluParam, 0, sizeof(MI_MATH_ALU_INST_INLINE) * 5);
EncodeMathMMIO<FamilyType>::encodeAluSubStoreCarry(aluParam, regA, regB,
finalResultRegister);
EXPECT_EQ(aluParam[0].DW0.BitField.ALUOpcode, ALU_OPCODE_LOAD);
EXPECT_EQ(aluParam[0].DW0.BitField.Operand1, ALU_REGISTER_R_SRCA);
EXPECT_EQ(aluParam[0].DW0.BitField.Operand2, regA);
EXPECT_EQ(aluParam[1].DW0.BitField.ALUOpcode, ALU_OPCODE_LOAD);
EXPECT_EQ(aluParam[1].DW0.BitField.Operand1, ALU_REGISTER_R_SRCB);
EXPECT_EQ(aluParam[1].DW0.BitField.Operand2, regB);
EXPECT_EQ(aluParam[2].DW0.BitField.ALUOpcode, ALU_OPCODE_SUB);
EXPECT_EQ(aluParam[2].DW0.BitField.Operand1, 0u);
EXPECT_EQ(aluParam[2].DW0.BitField.Operand2, 0u);
EXPECT_EQ(aluParam[3].DW0.BitField.ALUOpcode, ALU_OPCODE_STORE);
EXPECT_EQ(aluParam[3].DW0.BitField.Operand1, ALU_REGISTER_R_2);
EXPECT_EQ(aluParam[3].DW0.BitField.Operand2, ALU_REGISTER_R_CF);
EXPECT_EQ(aluParam[4].DW0.Value, 0u);
}
using CommandEncoderMathTest = Test<DeviceFixture>;
HWTEST_F(CommandEncoderMathTest, appendsAGreaterThanPredicate) {
using MI_LOAD_REGISTER_MEM = typename FamilyType::MI_LOAD_REGISTER_MEM;
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
using MI_LOAD_REGISTER_REG = typename FamilyType::MI_LOAD_REGISTER_REG;
using MI_MATH = typename FamilyType::MI_MATH;
using MI_MATH_ALU_INST_INLINE = typename FamilyType::MI_MATH_ALU_INST_INLINE;
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeMathMMIO<FamilyType>::encodeGreaterThanPredicate(cmdContainer, 0xDEADBEEFCAF0u, 17u);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
auto itor = commands.begin();
itor = find<MI_LOAD_REGISTER_IMM *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
auto cmdIMM = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itor);
EXPECT_EQ(cmdIMM->getRegisterOffset(), CS_GPR_R0);
EXPECT_EQ(cmdIMM->getDataDword(), 17u);
itor = find<MI_LOAD_REGISTER_MEM *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
auto cmdMEM = genCmdCast<MI_LOAD_REGISTER_MEM *>(*itor);
EXPECT_EQ(cmdMEM->getRegisterAddress(), CS_GPR_R1);
EXPECT_EQ(cmdMEM->getMemoryAddress(), 0xDEADBEEFCAF0u);
itor = find<MI_MATH *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
auto cmdMATH = genCmdCast<MI_MATH *>(*itor);
EXPECT_EQ(cmdMATH->DW0.BitField.DwordLength, 3u);
itor = find<MI_LOAD_REGISTER_REG *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
auto cmdREG = genCmdCast<MI_LOAD_REGISTER_REG *>(*itor);
EXPECT_EQ(cmdREG->getSourceRegisterAddress(), CS_GPR_R2);
EXPECT_EQ(cmdREG->getDestinationRegisterAddress(), CS_PREDICATE_RESULT);
auto cmdALU = reinterpret_cast<MI_MATH_ALU_INST_INLINE *>(cmdMATH + 3);
EXPECT_EQ(cmdALU->DW0.BitField.ALUOpcode, ALU_OPCODE_SUB);
}
HWTEST_F(CommandEncoderMathTest, setGroupSizeIndirect) {
using MI_MATH = typename FamilyType::MI_MATH;
using MI_MATH_ALU_INST_INLINE = typename FamilyType::MI_MATH_ALU_INST_INLINE;
using MI_STORE_REGISTER_MEM = typename FamilyType::MI_STORE_REGISTER_MEM;
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
uint32_t offsets[3] = {0, sizeof(uint32_t), 2 * sizeof(uint32_t)};
uint32_t crossThreadAdress[3] = {};
uint32_t lws[3] = {2, 1, 1};
EncodeIndirectParams<FamilyType>::setGroupSizeIndirect(cmdContainer, offsets, crossThreadAdress, lws);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
auto itor = commands.begin();
itor = find<MI_MATH *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
itor = find<MI_STORE_REGISTER_MEM *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
}
HWTEST_F(CommandEncoderMathTest, setGroupCountIndirect) {
using MI_MATH = typename FamilyType::MI_MATH;
using MI_MATH_ALU_INST_INLINE = typename FamilyType::MI_MATH_ALU_INST_INLINE;
using MI_STORE_REGISTER_MEM = typename FamilyType::MI_STORE_REGISTER_MEM;
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
uint32_t offsets[3] = {0, sizeof(uint32_t), 2 * sizeof(uint32_t)};
uint32_t crossThreadAdress[3] = {};
EncodeIndirectParams<FamilyType>::setGroupCountIndirect(cmdContainer, offsets, crossThreadAdress);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
auto itor = commands.begin();
itor = find<MI_STORE_REGISTER_MEM *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
itor = find<MI_STORE_REGISTER_MEM *>(++itor, commands.end());
ASSERT_NE(itor, commands.end());
itor = find<MI_STORE_REGISTER_MEM *>(++itor, commands.end());
ASSERT_NE(itor, commands.end());
itor = find<MI_STORE_REGISTER_MEM *>(++itor, commands.end());
ASSERT_EQ(itor, commands.end());
}

View File

@@ -1,29 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/ptr_math.h"
#include "fixtures/command_container_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
using namespace NEO;
using CommandEncodeStatesTest = Test<CommandEncodeStatesFixture>;
HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, ecodeMediaInterfaceDescriptor) {
using MEDIA_STATE_FLUSH = typename FamilyType::MEDIA_STATE_FLUSH;
using MEDIA_INTERFACE_DESCRIPTOR_LOAD = typename FamilyType::MEDIA_INTERFACE_DESCRIPTOR_LOAD;
EncodeMediaInterfaceDescriptorLoad<FamilyType>::encode(*cmdContainer.get());
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itorCmd = find<MEDIA_STATE_FLUSH *>(commands.begin(), commands.end());
ASSERT_NE(itorCmd, commands.end());
itorCmd = find<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(++itorCmd, commands.end());
ASSERT_NE(itorCmd, commands.end());
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/linear_stream.h"
#include "shared/source/helpers/ptr_math.h"
#include "fixtures/command_container_fixture.h"
#include "opencl/test/unit_test/helpers/hw_parse.h"
using namespace NEO;
using CommandEncodeSemaphore = Test<CommandEncodeStatesFixture>;
HWTEST_F(CommandEncodeSemaphore, programMiSemaphoreWait) {
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
MI_SEMAPHORE_WAIT miSemaphore;
EncodeSempahore<FamilyType>::programMiSemaphoreWait(&miSemaphore,
0x123400,
4,
MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_NOT_EQUAL_SDD);
EXPECT_EQ(MI_SEMAPHORE_WAIT::COMPARE_OPERATION::COMPARE_OPERATION_SAD_NOT_EQUAL_SDD, miSemaphore.getCompareOperation());
EXPECT_EQ(4u, miSemaphore.getSemaphoreDataDword());
EXPECT_EQ(0x123400u, miSemaphore.getSemaphoreGraphicsAddress());
EXPECT_EQ(MI_SEMAPHORE_WAIT::WAIT_MODE::WAIT_MODE_POLLING_MODE, miSemaphore.getWaitMode());
}
HWTEST_F(CommandEncodeSemaphore, whenAddingMiSemaphoreCommandThenExpectCompareFieldsAreSetCorrectly) {
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
using COMPARE_OPERATION = typename FamilyType::MI_SEMAPHORE_WAIT::COMPARE_OPERATION;
using WAIT_MODE = typename FamilyType::MI_SEMAPHORE_WAIT::WAIT_MODE;
std::unique_ptr<uint8_t> buffer(new uint8_t[128]);
LinearStream stream(buffer.get(), 128);
COMPARE_OPERATION compareMode = COMPARE_OPERATION::COMPARE_OPERATION_SAD_GREATER_THAN_OR_EQUAL_SDD;
EncodeSempahore<FamilyType>::addMiSemaphoreWaitCommand(stream,
0xFF00FF000u,
5u,
compareMode);
EXPECT_EQ(sizeof(MI_SEMAPHORE_WAIT), stream.getUsed());
HardwareParse hwParse;
hwParse.parseCommands<FamilyType>(stream);
MI_SEMAPHORE_WAIT *miSemaphore = hwParse.getCommand<MI_SEMAPHORE_WAIT>();
ASSERT_NE(nullptr, miSemaphore);
EXPECT_EQ(compareMode, miSemaphore->getCompareOperation());
EXPECT_EQ(5u, miSemaphore->getSemaphoreDataDword());
EXPECT_EQ(0xFF00FF000u, miSemaphore->getSemaphoreGraphicsAddress());
EXPECT_EQ(WAIT_MODE::WAIT_MODE_POLLING_MODE, miSemaphore->getWaitMode());
}
HWTEST_F(CommandEncodeSemaphore, whenGettingMiSemaphoreCommandSizeThenExpectSingleMiSemaphoreCommandSize) {
using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT;
size_t expectedSize = sizeof(MI_SEMAPHORE_WAIT);
size_t actualSize = EncodeSempahore<FamilyType>::getSizeMiSemaphoreWait();
EXPECT_EQ(expectedSize, actualSize);
}

View File

@@ -1,77 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_container/command_encoder.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "test.h"
using namespace NEO;
class CommandSetMMIOFixture : public DeviceFixture {
public:
void SetUp() {
DeviceFixture::SetUp();
cmdContainer = std::make_unique<CommandContainer>();
cmdContainer->initialize(pDevice);
}
void TearDown() {
cmdContainer.reset();
DeviceFixture::TearDown();
}
std::unique_ptr<CommandContainer> cmdContainer;
};
using CommandSetMMIOTest = Test<CommandSetMMIOFixture>;
HWTEST_F(CommandSetMMIOTest, appendsAMI_LOAD_REGISTER_IMM) {
EncodeSetMMIO<FamilyType>::encodeIMM(*cmdContainer.get(), 0xf00, 0xbaa);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(commands.begin(), commands.end());
ASSERT_NE(itorLRI, commands.end());
{
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
EXPECT_EQ(cmd->getRegisterOffset(), 0xf00u);
EXPECT_EQ(cmd->getDataDword(), 0xbaau);
}
}
HWTEST_F(CommandSetMMIOTest, appendsAMI_LOAD_REGISTER_MEM) {
EncodeSetMMIO<FamilyType>::encodeMEM(*cmdContainer.get(), 0xf00, 0xDEADBEEFCAF0);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
using MI_LOAD_REGISTER_MEM = typename FamilyType::MI_LOAD_REGISTER_MEM;
auto itorLRI = find<MI_LOAD_REGISTER_MEM *>(commands.begin(), commands.end());
ASSERT_NE(itorLRI, commands.end());
{
auto cmd = genCmdCast<MI_LOAD_REGISTER_MEM *>(*itorLRI);
EXPECT_EQ(cmd->getRegisterAddress(), 0xf00u);
EXPECT_EQ(cmd->getMemoryAddress(), 0xDEADBEEFCAF0u);
}
}
HWTEST_F(CommandSetMMIOTest, appendsAMI_LOAD_REGISTER_REG) {
EncodeSetMMIO<FamilyType>::encodeREG(*cmdContainer.get(), 0xf10, 0xaf0);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
using MI_LOAD_REGISTER_REG = typename FamilyType::MI_LOAD_REGISTER_REG;
auto itorLRI = find<MI_LOAD_REGISTER_REG *>(commands.begin(), commands.end());
ASSERT_NE(itorLRI, commands.end());
{
auto cmd = genCmdCast<MI_LOAD_REGISTER_REG *>(*itorLRI);
EXPECT_EQ(cmd->getDestinationRegisterAddress(), 0xf10u);
EXPECT_EQ(cmd->getSourceRegisterAddress(), 0xaf0u);
}
}

View File

@@ -1,163 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/ptr_math.h"
#include "fixtures/command_container_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
using namespace NEO;
using CommandEncodeStatesTest = Test<CommandEncodeStatesFixture>;
HWTEST_F(CommandEncodeStatesTest, encodeCopySamplerState) {
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1;
SAMPLER_STATE samplerState;
auto dsh = cmdContainer->getIndirectHeap(HeapType::DYNAMIC_STATE);
auto usedBefore = dsh->getUsed();
auto samplerStateOffset = EncodeStates<FamilyType>::copySamplerState(dsh, 0, numSamplers, 0, &samplerState);
auto pSmplr = reinterpret_cast<SAMPLER_STATE *>(ptrOffset(dsh->getCpuBase(), samplerStateOffset));
EXPECT_EQ(pSmplr->getIndirectStatePointer(), usedBefore);
}
HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenAllocationProvidedThenUseAllocationAsInput) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
using SURFACE_TYPE = typename RENDER_SURFACE_STATE::SURFACE_TYPE;
using AUXILIARY_SURFACE_MODE = typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE;
void *stateBuffer = alignedMalloc(sizeof(RENDER_SURFACE_STATE), sizeof(RENDER_SURFACE_STATE));
ASSERT_NE(nullptr, stateBuffer);
RENDER_SURFACE_STATE *state = reinterpret_cast<RENDER_SURFACE_STATE *>(stateBuffer);
memset(stateBuffer, 0, sizeof(RENDER_SURFACE_STATE));
size_t size = 0x1000;
SURFACE_STATE_BUFFER_LENGTH length;
void *cpuAddr = reinterpret_cast<void *>(0x4000);
uint64_t gpuAddr = 0x4000u;
size_t allocSize = size;
length.Length = static_cast<uint32_t>(allocSize - 1);
GraphicsAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, cpuAddr, gpuAddr, 0u, allocSize, MemoryPool::MemoryNull);
EncodeSurfaceState<FamilyType>::encodeBuffer(stateBuffer, reinterpret_cast<void *>(gpuAddr), allocSize, 1,
RENDER_SURFACE_STATE::COHERENCY_TYPE_IA_COHERENT);
EXPECT_EQ(length.SurfaceState.Depth + 1u, state->getDepth());
EXPECT_EQ(length.SurfaceState.Width + 1u, state->getWidth());
EXPECT_EQ(length.SurfaceState.Height + 1u, state->getHeight());
EXPECT_EQ(gpuAddr, state->getSurfaceBaseAddress());
alignedFree(stateBuffer);
}
HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenAllocationNotProvidedThenStateTypeIsNull) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
void *stateBuffer = alignedMalloc(sizeof(RENDER_SURFACE_STATE), sizeof(RENDER_SURFACE_STATE));
ASSERT_NE(nullptr, stateBuffer);
RENDER_SURFACE_STATE *state = reinterpret_cast<RENDER_SURFACE_STATE *>(stateBuffer);
memset(stateBuffer, 0, sizeof(RENDER_SURFACE_STATE));
size_t size = 0x1000;
SURFACE_STATE_BUFFER_LENGTH length;
uint64_t gpuAddr = 0;
size_t allocSize = size;
length.Length = static_cast<uint32_t>(allocSize - 1);
EncodeSurfaceState<FamilyType>::encodeBuffer(stateBuffer, reinterpret_cast<void *>(gpuAddr), allocSize, 1,
RENDER_SURFACE_STATE::COHERENCY_TYPE_IA_COHERENT);
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_NULL, state->getSurfaceType());
alignedFree(stateBuffer);
}
HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenGpuCoherencyProvidedThenCoherencyGpuIsSet) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
void *stateBuffer = alignedMalloc(sizeof(RENDER_SURFACE_STATE), sizeof(RENDER_SURFACE_STATE));
ASSERT_NE(nullptr, stateBuffer);
RENDER_SURFACE_STATE *state = reinterpret_cast<RENDER_SURFACE_STATE *>(stateBuffer);
memset(stateBuffer, 0, sizeof(RENDER_SURFACE_STATE));
size_t size = 0x1000;
SURFACE_STATE_BUFFER_LENGTH length;
uint64_t gpuAddr = 0;
size_t allocSize = size;
length.Length = static_cast<uint32_t>(allocSize - 1);
EncodeSurfaceState<FamilyType>::encodeBuffer(stateBuffer, reinterpret_cast<void *>(gpuAddr), allocSize, 1,
RENDER_SURFACE_STATE::COHERENCY_TYPE_GPU_COHERENT);
EXPECT_EQ(RENDER_SURFACE_STATE::COHERENCY_TYPE_GPU_COHERENT, state->getCoherencyType());
alignedFree(stateBuffer);
}
HWTEST_F(CommandEncodeStatesTest, givenCommandContainerWithDirtyHeapsWhenSetStateBaseAddressCalledThenStateBaseAddressAreNotSet) {
using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS;
cmdContainer->dirtyHeaps = 0;
auto baseAddres = cmdContainer->getCommandStream()->getCpuBase();
cmdContainer->setHeapDirty(NEO::HeapType::DYNAMIC_STATE);
cmdContainer->setHeapDirty(NEO::HeapType::INDIRECT_OBJECT);
cmdContainer->setHeapDirty(NEO::HeapType::SURFACE_STATE);
EncodeStateBaseAddress<FamilyType>::encode(*cmdContainer.get());
auto dsh = cmdContainer->getIndirectHeap(NEO::HeapType::DYNAMIC_STATE);
auto ioh = cmdContainer->getIndirectHeap(NEO::HeapType::INDIRECT_OBJECT);
auto ssh = cmdContainer->getIndirectHeap(NEO::HeapType::SURFACE_STATE);
auto pCmd = static_cast<STATE_BASE_ADDRESS *>(baseAddres);
EXPECT_EQ(dsh->getHeapGpuBase(), pCmd->getDynamicStateBaseAddress());
EXPECT_EQ(ioh->getHeapGpuBase(), pCmd->getIndirectObjectBaseAddress());
EXPECT_EQ(ssh->getHeapGpuBase(), pCmd->getSurfaceStateBaseAddress());
}
HWTEST_F(CommandEncodeStatesTest, givenCommandContainerWhenSetStateBaseAddressCalledThenStateBaseAddressIsSetCorrectly) {
using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS;
cmdContainer->dirtyHeaps = 0;
EncodeStateBaseAddress<FamilyType>::encode(*cmdContainer.get());
auto dsh = cmdContainer->getIndirectHeap(NEO::HeapType::DYNAMIC_STATE);
auto ssh = cmdContainer->getIndirectHeap(NEO::HeapType::SURFACE_STATE);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed());
auto itorCmd = find<STATE_BASE_ADDRESS *>(commands.begin(), commands.end());
ASSERT_NE(itorCmd, commands.end());
auto cmd = genCmdCast<STATE_BASE_ADDRESS *>(*itorCmd);
EXPECT_NE(dsh->getHeapGpuBase(), cmd->getDynamicStateBaseAddress());
EXPECT_NE(ssh->getHeapGpuBase(), cmd->getSurfaceStateBaseAddress());
}
HWTEST_F(CommandEncodeStatesTest, givenAnAlignedDstPtrThenNoAlignmentNorOffsetNeeded) {
uintptr_t ptr = NEO::EncodeSurfaceState<FamilyType>::getSurfaceBaseAddressAlignment() << 1;
size_t offset = 0;
NEO::EncodeSurfaceState<FamilyType>::getSshAlignedPointer(ptr, offset);
EXPECT_TRUE((ptr & (NEO::EncodeSurfaceState<FamilyType>::getSurfaceBaseAddressAlignment() - 1)) == 0x0u);
EXPECT_EQ(0u, offset);
}
HWTEST_F(CommandEncodeStatesTest, givenAnUnalignedDstPtrThenCorrectAlignedPtrAndOffsetAreCalculated) {
uintptr_t ptr = NEO::EncodeSurfaceState<FamilyType>::getSurfaceBaseAddressAlignment() >> 1;
size_t offset = 0;
NEO::EncodeSurfaceState<FamilyType>::getSshAlignedPointer(ptr, offset);
EXPECT_TRUE((ptr & (NEO::EncodeSurfaceState<FamilyType>::getSurfaceBaseAddressAlignment() - 1)) == 0x0u);
EXPECT_NE(0u, offset);
}

View File

@@ -1,13 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_tests_fixtures
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/command_container_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/preemption_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/preemption_fixture.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_tests_fixtures ${NEO_CORE_tests_fixtures})

View File

@@ -1,30 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/command_container/command_encoder.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "test.h"
class CommandEncodeStatesFixture : public DeviceFixture {
public:
class MyMockCommandContainer : public CommandContainer {
public:
using CommandContainer::dirtyHeaps;
};
void SetUp() {
DeviceFixture::SetUp();
cmdContainer = std::make_unique<MyMockCommandContainer>();
cmdContainer->initialize(pDevice);
}
void TearDown() {
cmdContainer.reset();
DeviceFixture::TearDown();
}
std::unique_ptr<MyMockCommandContainer> cmdContainer;
};

View File

@@ -1,99 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "fixtures/preemption_fixture.h"
#include "shared/source/command_stream/preemption.h"
#include "shared/source/helpers/hw_info.h"
#include "opencl/source/command_queue/enqueue_common.h"
#include "opencl/source/command_queue/enqueue_kernel.h"
#include "opencl/source/command_queue/enqueue_marker.h"
#include "opencl/source/helpers/dispatch_info.h"
#include "opencl/source/scheduler/scheduler_kernel.h"
#include "opencl/test/unit_test/fixtures/hello_world_fixture.h"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "opencl/test/unit_test/mocks/mock_device.h"
#include "opencl/test/unit_test/mocks/mock_kernel.h"
#include "test.h"
#include "gtest/gtest.h"
using namespace NEO;
DevicePreemptionTests::DevicePreemptionTests() = default;
DevicePreemptionTests::~DevicePreemptionTests() = default;
void DevicePreemptionTests::SetUp() {
if (dbgRestore == nullptr) {
dbgRestore.reset(new DebugManagerStateRestore());
}
const cl_queue_properties properties[3] = {CL_QUEUE_PROPERTIES, 0, 0};
kernelInfo = std::make_unique<KernelInfo>();
device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
context.reset(new MockContext(device.get()));
cmdQ.reset(new MockCommandQueue(context.get(), device.get(), properties));
executionEnvironment.reset(new SPatchExecutionEnvironment);
memset(executionEnvironment.get(), 0, sizeof(SPatchExecutionEnvironment));
kernelInfo->patchInfo.executionEnvironment = executionEnvironment.get();
program = std::make_unique<MockProgram>(*device->getExecutionEnvironment());
kernel.reset(new MockKernel(program.get(), *kernelInfo, *device));
dispatchInfo.reset(new DispatchInfo(kernel.get(), 1, Vec3<size_t>(1, 1, 1), Vec3<size_t>(1, 1, 1), Vec3<size_t>(0, 0, 0)));
ASSERT_NE(nullptr, device);
ASSERT_NE(nullptr, context);
ASSERT_NE(nullptr, cmdQ);
waTable = &device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable;
}
void DevicePreemptionTests::TearDown() {
dbgRestore.reset();
kernel.reset();
kernelInfo.reset();
dispatchInfo.reset();
cmdQ.reset();
context.reset();
device.reset();
}
void ThreadGroupPreemptionEnqueueKernelTest::SetUp() {
dbgRestore.reset(new DebugManagerStateRestore());
DebugManager.flags.ForcePreemptionMode.set(static_cast<int32_t>(PreemptionMode::ThreadGroup));
globalHwInfo = const_cast<HardwareInfo *>(platformDevices[0]);
originalPreemptionMode = globalHwInfo->capabilityTable.defaultPreemptionMode;
globalHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::ThreadGroup;
HelloWorldFixture::SetUp();
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
}
void ThreadGroupPreemptionEnqueueKernelTest::TearDown() {
globalHwInfo->capabilityTable.defaultPreemptionMode = originalPreemptionMode;
HelloWorldFixture::TearDown();
}
void MidThreadPreemptionEnqueueKernelTest::SetUp() {
dbgRestore.reset(new DebugManagerStateRestore());
DebugManager.flags.ForcePreemptionMode.set(static_cast<int32_t>(PreemptionMode::MidThread));
globalHwInfo = const_cast<HardwareInfo *>(platformDevices[0]);
originalPreemptionMode = globalHwInfo->capabilityTable.defaultPreemptionMode;
globalHwInfo->capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
HelloWorldFixture::SetUp();
pDevice->setPreemptionMode(PreemptionMode::MidThread);
}
void MidThreadPreemptionEnqueueKernelTest::TearDown() {
globalHwInfo->capabilityTable.defaultPreemptionMode = originalPreemptionMode;
HelloWorldFixture::TearDown();
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "helpers/debug_manager_state_restore.h"
#include "opencl/test/unit_test/fixtures/hello_world_fixture.h"
#include "test.h"
#include "gtest/gtest.h"
#include <cinttypes>
#include <memory>
#include <type_traits>
#include <unordered_map>
namespace iOpenCL {
struct SPatchExecutionEnvironment;
}
namespace NEO {
class DispatchInfo;
class MockCommandQueue;
class MockContext;
class MockDevice;
class MockKernel;
class MockProgram;
struct KernelInfo;
struct WorkaroundTable;
using PreemptionEnqueueKernelFixture = HelloWorldFixture<HelloWorldFixtureFactory>;
using PreemptionEnqueueKernelTest = Test<PreemptionEnqueueKernelFixture>;
} // namespace NEO
class DevicePreemptionTests : public ::testing::Test {
public:
void SetUp() override;
void TearDown() override;
DevicePreemptionTests();
~DevicePreemptionTests() override;
NEO::PreemptionMode preemptionMode;
NEO::WorkaroundTable *waTable = nullptr;
std::unique_ptr<NEO::DispatchInfo> dispatchInfo;
std::unique_ptr<NEO::MockKernel> kernel;
std::unique_ptr<NEO::MockCommandQueue> cmdQ;
std::unique_ptr<NEO::MockClDevice> device;
std::unique_ptr<NEO::MockContext> context;
std::unique_ptr<DebugManagerStateRestore> dbgRestore;
std::unique_ptr<iOpenCL::SPatchExecutionEnvironment> executionEnvironment;
std::unique_ptr<NEO::MockProgram> program;
std::unique_ptr<NEO::KernelInfo> kernelInfo;
};
struct ThreadGroupPreemptionEnqueueKernelTest : NEO::PreemptionEnqueueKernelTest {
void SetUp() override;
void TearDown() override;
NEO::HardwareInfo *globalHwInfo;
NEO::PreemptionMode originalPreemptionMode;
std::unique_ptr<DebugManagerStateRestore> dbgRestore;
};
struct MidThreadPreemptionEnqueueKernelTest : NEO::PreemptionEnqueueKernelTest {
void SetUp() override;
void TearDown() override;
NEO::HardwareInfo *globalHwInfo;
NEO::PreemptionMode originalPreemptionMode;
std::unique_ptr<DebugManagerStateRestore> dbgRestore;
};
struct PreemptionTestHwDetails {
struct PreemptionModeHashT {
auto operator()(const NEO::PreemptionMode &preemptionMode) const -> std::underlying_type<NEO::PreemptionMode>::type {
return static_cast<std::underlying_type<NEO::PreemptionMode>::type>(preemptionMode);
}
};
bool supportsPreemptionProgramming() const {
return modeToRegValueMap.size() > 0;
}
uint32_t regAddress = 0;
std::unordered_map<NEO::PreemptionMode, uint32_t, PreemptionModeHashT> modeToRegValueMap;
uint32_t defaultRegValue = 0;
};
template <typename FamilyType>
PreemptionTestHwDetails GetPreemptionTestHwDetails();

View File

@@ -1,16 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_TESTS_GEN11
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/image_surface_state_tests_gen11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/preamble_tests_gen11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/simd_helper_tests_gen11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_preamble_gen11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_preemption_gen11.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_TESTS_GEN11 ${NEO_CORE_TESTS_GEN11})
add_subdirectories()

View File

@@ -1,89 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "gtest/gtest.h"
using GenStruct = NEO::GEN11;
using GenGfxFamily = NEO::ICLFamily;
#include "opencl/test/unit_test/gen_common/cmd_parse_base.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_base_mi_arb.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_gpgpu_walker.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_sip.inl"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/helpers/hw_parse.inl"
template <>
size_t CmdParse<GenGfxFamily>::getCommandLengthHwSpecific(void *cmd) {
{
auto pCmd = genCmdCast<GPGPU_WALKER *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_VFE_STATE *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_STATE_FLUSH *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<STATE_SIP *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
return 0;
}
template <>
const char *CmdParse<GenGfxFamily>::getCommandNameHwSpecific(void *cmd) {
if (nullptr != genCmdCast<GPGPU_WALKER *>(cmd)) {
return "GPGPU_WALKER";
}
if (nullptr != genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd)) {
return "MEDIA_INTERFACE_DESCRIPTOR_LOAD";
}
if (nullptr != genCmdCast<MEDIA_VFE_STATE *>(cmd)) {
return "MEDIA_VFE_STATE";
}
if (nullptr != genCmdCast<MEDIA_STATE_FLUSH *>(cmd)) {
return "MEDIA_STATE_FLUSH";
}
if (nullptr != genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(cmd)) {
return "GPGPU_CSR_BASE_ADDRESS";
}
if (nullptr != genCmdCast<STATE_SIP *>(cmd)) {
return "STATE_SIP";
}
return "UNKNOWN";
}
template struct CmdParse<GenGfxFamily>;
namespace NEO {
template void HardwareParse::findHardwareCommands<ICLFamily>();
template void HardwareParse::findHardwareCommands<ICLFamily>(IndirectHeap *);
template const void *HardwareParse::getStatelessArgumentPointer<ICLFamily>(const Kernel &kernel, uint32_t indexArg, IndirectHeap &ioh);
} // namespace NEO

View File

@@ -1,38 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "image/image_surface_state_fixture.h"
using ImageSurfaceStateTestsGen11 = ImageSurfaceStateTests;
GEN11TEST_F(ImageSurfaceStateTestsGen11, givenGmmWithMediaCompressedWhenSetFlagsForMediaCompressionThenAuxiliarySurfaceNoneIsSet) {
auto size = sizeof(typename FamilyType::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename FamilyType::RENDER_SURFACE_STATE *>(surfaceState.get());
castSurfaceState->setAuxiliarySurfaceMode(FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = false;
setFlagsForMediaCompression<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = true;
setFlagsForMediaCompression<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_NONE);
}
GEN11TEST_F(ImageSurfaceStateTestsGen11, givenGmmWithMediaCompressedWhenSetMipTailStartLodThenMipTailStartLodIsSet) {
auto size = sizeof(typename FamilyType::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename FamilyType::RENDER_SURFACE_STATE *>(surfaceState.get());
setMipTailStartLod<FamilyType>(castSurfaceState, nullptr);
EXPECT_EQ(castSurfaceState->getMipTailStartLod(), 0u);
setMipTailStartLod<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getMipTailStartLod(), mockGmm.gmmResourceInfo->getMipTailStartLodSurfaceState());
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/debug_manager_state_restore.h"
#include "source_level_debugger/source_level_debugger_preamble_test.h"
#include "gtest/gtest.h"
using namespace NEO;
typedef ICLFamily GfxFamily;
#include "source_level_debugger/source_level_debugger_preamble_test.inl"
using PreambleTestGen11 = ::testing::Test;
GEN11TEST_F(PreambleTestGen11, givenMidThreadPreemptionAndDebuggingActiveWhenStateSipIsProgrammedThenCorrectSipKernelIsUsed) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDebuggingActiveWhenStateSipIsProgrammedThenCorrectSipKernelIsUsedTest();
}
GEN11TEST_F(PreambleTestGen11, givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN11TEST_F(PreambleTestGen11, givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsed) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsedTest();
}
GEN11TEST_F(PreambleTestGen11, givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN11TEST_F(PreambleTestGen11, givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsProgrammedThenCorrectSipKernelIsUsed) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsProgrammedThenCorrectSipKernelIsUsedTest();
}
GEN11TEST_F(PreambleTestGen11, givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN11TEST_F(PreambleTestGen11, givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN11TEST_F(PreambleTestGen11, givenKernelDebuggingActiveAndDisabledPreemptionWhenGetAdditionalCommandsSizeIsCalledThen2MiLoadRegisterImmCmdsAndStateSipAreInlcuded) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenKernelDebuggingActiveAndDisabledPreemptionWhenGetAdditionalCommandsSizeIsCalledThen2MiLoadRegisterImmCmdsAreInlcudedTest();
}

View File

@@ -1,16 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/simd_helper_tests.inl"
using namespace NEO;
using TestSimdConfigSet = ::testing::Test;
GEN11TEST_F(TestSimdConfigSet, GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturnedGen11) {
GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturned<typename FamilyType::GPGPU_WALKER>::TestBodyImpl();
}

View File

@@ -1,142 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/preemption.h"
#include "helpers/debug_manager_state_restore.h"
#include "preamble/preamble_fixture.h"
#include "reg_configs_common.h"
using namespace NEO;
typedef PreambleFixture IclSlm;
GEN11TEST_F(IclSlm, shouldBeEnabledOnGen11) {
typedef ICLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
LinearStream &cs = linearStream;
uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(**platformDevices, true);
PreambleHelper<FamilyType>::programL3(&cs, l3Config);
parseCommands<ICLFamily>(cs);
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorLRI);
const auto &lri = *reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
auto RegisterOffset = L3CNTLRegisterOffset<FamilyType>::registerOffset;
EXPECT_EQ(RegisterOffset, lri.getRegisterOffset());
EXPECT_EQ(0u, lri.getDataDword() & 1);
}
GEN11TEST_F(IclSlm, givenGen11WhenProgramingL3ThenErrorDetectionBehaviorControlBitSet) {
uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(**platformDevices, true);
uint32_t errorDetectionBehaviorControlBit = 1 << 9;
EXPECT_TRUE((l3Config & errorDetectionBehaviorControlBit) != 0);
}
GEN11TEST_F(IclSlm, givenGen11IsL3Programing) {
bool isL3Programmable =
PreambleHelper<FamilyType>::isL3Configurable(**platformDevices);
EXPECT_FALSE(isL3Programmable);
}
typedef PreambleFixture Gen11UrbEntryAllocationSize;
GEN11TEST_F(Gen11UrbEntryAllocationSize, getUrbEntryAllocationSize) {
uint32_t actualVal = PreambleHelper<FamilyType>::getUrbEntryAllocationSize();
EXPECT_EQ(0x782u, actualVal);
}
typedef PreambleVfeState Gen11PreambleVfeState;
GEN11TEST_F(Gen11PreambleVfeState, WaOff) {
typedef typename ICLFamily::PIPE_CONTROL PIPE_CONTROL;
testWaTable->waSendMIFLUSHBeforeVFE = 0;
LinearStream &cs = linearStream;
PreambleHelper<ICLFamily>::programVFEState(&linearStream, pPlatform->getDevice(0)->getHardwareInfo(), 0, 0, 168u, aub_stream::EngineType::ENGINE_RCS);
parseCommands<ICLFamily>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_FALSE(pc.getRenderTargetCacheFlushEnable());
EXPECT_FALSE(pc.getDepthCacheFlushEnable());
EXPECT_FALSE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}
GEN11TEST_F(Gen11PreambleVfeState, WaOn) {
typedef typename ICLFamily::PIPE_CONTROL PIPE_CONTROL;
testWaTable->waSendMIFLUSHBeforeVFE = 1;
LinearStream &cs = linearStream;
PreambleHelper<ICLFamily>::programVFEState(&linearStream, pPlatform->getDevice(0)->getHardwareInfo(), 0, 0, 168u, aub_stream::EngineType::ENGINE_RCS);
parseCommands<ICLFamily>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_TRUE(pc.getRenderTargetCacheFlushEnable());
EXPECT_TRUE(pc.getDepthCacheFlushEnable());
EXPECT_TRUE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}
typedef PreambleFixture PreemptionWatermarkGen11;
GEN11TEST_F(PreemptionWatermarkGen11, givenPreambleThenPreambleWorkAroundsIsNotProgrammed) {
PreambleHelper<FamilyType>::programGenSpecificPreambleWorkArounds(&linearStream, **platformDevices);
parseCommands<FamilyType>(linearStream);
auto cmd = findMmioCmd<FamilyType>(cmdList.begin(), cmdList.end(), FfSliceCsChknReg2::address);
ASSERT_EQ(nullptr, cmd);
MockDevice mockDevice;
mockDevice.setDebuggerActive(false);
size_t expectedSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(mockDevice);
EXPECT_EQ(expectedSize, PreambleHelper<FamilyType>::getAdditionalCommandsSize(mockDevice));
mockDevice.setDebuggerActive(true);
expectedSize += PreambleHelper<FamilyType>::getKernelDebuggingCommandsSize(mockDevice.isDebuggerActive());
EXPECT_EQ(expectedSize, PreambleHelper<FamilyType>::getAdditionalCommandsSize(mockDevice));
}
typedef PreambleFixture ThreadArbitrationGen11;
GEN11TEST_F(ThreadArbitrationGen11, givenPreambleWhenItIsProgrammedThenThreadArbitrationIsSet) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.ForcePreemptionMode.set(static_cast<int32_t>(PreemptionMode::Disabled));
typedef ICLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
typedef ICLFamily::PIPE_CONTROL PIPE_CONTROL;
LinearStream &cs = linearStream;
uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(**platformDevices, true);
MockDevice mockDevice;
PreambleHelper<FamilyType>::programPreamble(&linearStream, mockDevice, l3Config,
ThreadArbitrationPolicy::RoundRobin,
nullptr, nullptr);
parseCommands<FamilyType>(cs);
auto ppC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(ppC, cmdList.end());
auto cmd = findMmioCmd<FamilyType>(cmdList.begin(), cmdList.end(), RowChickenReg4::address);
ASSERT_NE(nullptr, cmd);
EXPECT_EQ(RowChickenReg4::regDataForArbitrationPolicy[ThreadArbitrationPolicy::RoundRobin], cmd->getDataDword());
MockDevice device;
EXPECT_EQ(0u, PreambleHelper<ICLFamily>::getAdditionalCommandsSize(device));
EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL), PreambleHelper<ICLFamily>::getThreadArbitrationCommandsSize());
}
GEN11TEST_F(ThreadArbitrationGen11, defaultArbitrationPolicy) {
EXPECT_EQ(ThreadArbitrationPolicy::RoundRobinAfterDependency, PreambleHelper<ICLFamily>::getDefaultThreadArbitrationPolicy());
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/hw_helper.h"
#include "fixtures/preemption_fixture.h"
#include "opencl/source/built_ins/built_ins.h"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/mocks/mock_buffer.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_csr.h"
using namespace NEO;
using Gen11PreemptionTests = DevicePreemptionTests;
template <>
PreemptionTestHwDetails GetPreemptionTestHwDetails<ICLFamily>() {
PreemptionTestHwDetails ret;
ret.modeToRegValueMap[PreemptionMode::ThreadGroup] = DwordBuilder::build(1, true) | DwordBuilder::build(2, true, false);
ret.modeToRegValueMap[PreemptionMode::MidBatch] = DwordBuilder::build(2, true) | DwordBuilder::build(1, true, false);
ret.modeToRegValueMap[PreemptionMode::MidThread] = DwordBuilder::build(2, true, false) | DwordBuilder::build(1, true, false);
ret.defaultRegValue = ret.modeToRegValueMap[PreemptionMode::MidBatch];
ret.regAddress = 0x2580u;
return ret;
}
GEN11TEST_F(Gen11PreemptionTests, whenMidThreadPreemptionIsNotAvailableThenDoesNotProgramStateSip) {
device->setPreemptionMode(PreemptionMode::ThreadGroup);
size_t requiredSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(device->getDevice());
EXPECT_EQ(0U, requiredSize);
LinearStream cmdStream{nullptr, 0};
PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(device->getDevice());
EXPECT_EQ(0U, cmdStream.getUsed());
}
GEN11TEST_F(Gen11PreemptionTests, whenMidThreadPreemptionIsAvailableThenStateSipIsProgrammed) {
using STATE_SIP = typename FamilyType::STATE_SIP;
device->setPreemptionMode(PreemptionMode::MidThread);
executionEnvironment->DisableMidThreadPreemption = 0;
size_t requiredCmdStreamSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(device->getDevice());
size_t expectedPreambleSize = sizeof(STATE_SIP);
EXPECT_EQ(expectedPreambleSize, requiredCmdStreamSize);
StackVec<char, 8192> streamStorage(requiredCmdStreamSize);
ASSERT_LE(requiredCmdStreamSize, streamStorage.size());
LinearStream cmdStream{streamStorage.begin(), streamStorage.size()};
PreemptionHelper::programStateSip<FamilyType>(cmdStream, device->getDevice());
HardwareParse hwParsePreamble;
hwParsePreamble.parseCommands<FamilyType>(cmdStream);
auto stateSipCmd = hwParsePreamble.getCommand<STATE_SIP>();
ASSERT_NE(nullptr, stateSipCmd);
EXPECT_EQ(device->getExecutionEnvironment()->getBuiltIns()->getSipKernel(SipKernelType::Csr, device->getDevice()).getSipAllocation()->getGpuAddressToPatch(), stateSipCmd->getSystemInstructionPointer());
}
GEN11TEST_F(Gen11PreemptionTests, getRequiredCmdQSize) {
size_t expectedSize = 0;
EXPECT_EQ(expectedSize, PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice()));
}
GEN11TEST_F(Gen11PreemptionTests, applyPreemptionWaCmds) {
size_t usedSize = 0;
auto &cmdStream = cmdQ->getCS(0);
PreemptionHelper::applyPreemptionWaCmdsBegin<FamilyType>(&cmdStream, device->getDevice());
EXPECT_EQ(usedSize, cmdStream.getUsed());
PreemptionHelper::applyPreemptionWaCmdsEnd<FamilyType>(&cmdStream, device->getDevice());
EXPECT_EQ(usedSize, cmdStream.getUsed());
}
GEN11TEST_F(Gen11PreemptionTests, givenInterfaceDescriptorDataWhenMidThreadPreemptionModeThenSetDisableThreadPreemptionBitToDisable) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
INTERFACE_DESCRIPTOR_DATA iddArg;
iddArg = FamilyType::cmdInitInterfaceDescriptorData;
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidThread);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE, iddArg.getThreadPreemptionDisable());
}
GEN11TEST_F(Gen11PreemptionTests, givenInterfaceDescriptorDataWhenNoMidThreadPreemptionModeThenSetDisableThreadPreemptionBitToEnable) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
INTERFACE_DESCRIPTOR_DATA iddArg;
iddArg = FamilyType::cmdInitInterfaceDescriptorData;
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::Disabled);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE, iddArg.getThreadPreemptionDisable());
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidBatch);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE, iddArg.getThreadPreemptionDisable());
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::ThreadGroup);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE, iddArg.getThreadPreemptionDisable());
}

View File

@@ -1,16 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_TESTS_GEN12LP
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/image_surface_state_tests_gen12lp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/simd_helper_tests_gen12lp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_preamble_gen12lp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_command_encoder_gen12lp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_preemption_gen12lp.inl
)
set_property(GLOBAL PROPERTY NEO_CORE_TESTS_GEN12LP ${NEO_CORE_TESTS_GEN12LP})
add_subdirectories()

View File

@@ -1,14 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
size_t getAdditionalCommandLengthHwSpecific(void *cmd) {
return 0;
}
const char *getAdditionalCommandNameHwSpecific(void *cmd) {
return "UNKNOWN";
}

View File

@@ -1,103 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "gtest/gtest.h"
using GenStruct = NEO::GEN12LP;
using GenGfxFamily = NEO::TGLLPFamily;
#include "opencl/test/unit_test/gen_common/cmd_parse_base.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_compute_mode.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_gpgpu_walker.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_mi_arb.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_sip.inl"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/helpers/hw_parse.inl"
#include "cmd_parse_gen12lp.inl"
template <>
size_t CmdParse<GenGfxFamily>::getCommandLengthHwSpecific(void *cmd) {
{
auto pCmd = genCmdCast<GPGPU_WALKER *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_VFE_STATE *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_STATE_FLUSH *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<STATE_COMPUTE_MODE *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<STATE_SIP *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
return getAdditionalCommandLengthHwSpecific(cmd);
}
template <>
const char *CmdParse<GenGfxFamily>::getCommandNameHwSpecific(void *cmd) {
if (nullptr != genCmdCast<GPGPU_WALKER *>(cmd)) {
return "GPGPU_WALKER";
}
if (nullptr != genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd)) {
return "MEDIA_INTERFACE_DESCRIPTOR_LOAD";
}
if (nullptr != genCmdCast<MEDIA_VFE_STATE *>(cmd)) {
return "MEDIA_VFE_STATE";
}
if (nullptr != genCmdCast<MEDIA_STATE_FLUSH *>(cmd)) {
return "MEDIA_STATE_FLUSH";
}
if (nullptr != genCmdCast<STATE_COMPUTE_MODE *>(cmd)) {
return "MEDIA_STATE_FLUSH";
}
if (nullptr != genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(cmd)) {
return "GPGPU_CSR_BASE_ADDRESS";
}
if (nullptr != genCmdCast<STATE_SIP *>(cmd)) {
return "STATE_SIP";
}
return getAdditionalCommandNameHwSpecific(cmd);
}
template struct CmdParse<GenGfxFamily>;
namespace NEO {
template void HardwareParse::findHardwareCommands<TGLLPFamily>();
template void HardwareParse::findHardwareCommands<TGLLPFamily>(IndirectHeap *);
template const void *HardwareParse::getStatelessArgumentPointer<TGLLPFamily>(const Kernel &kernel, uint32_t indexArg, IndirectHeap &ioh);
} // namespace NEO

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "image/image_surface_state_fixture.h"
using ImageSurfaceStateTestsGen12LP = ImageSurfaceStateTests;
GEN12LPTEST_F(ImageSurfaceStateTestsGen12LP, givenGmmWithMediaCompressedWhenSetFlagsForMediaCompressionThenAuxiliarySurfaceNoneIsSetAndMemoryCompressionEnable) {
auto size = sizeof(typename TGLLPFamily::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename TGLLPFamily::RENDER_SURFACE_STATE *>(surfaceState.get());
castSurfaceState->setAuxiliarySurfaceMode(TGLLPFamily::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = false;
setFlagsForMediaCompression<TGLLPFamily>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), TGLLPFamily::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
EXPECT_EQ(castSurfaceState->getMemoryCompressionEnable(), false);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = true;
setFlagsForMediaCompression<TGLLPFamily>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), TGLLPFamily::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_NONE);
EXPECT_EQ(castSurfaceState->getMemoryCompressionEnable(), true);
}
GEN12LPTEST_F(ImageSurfaceStateTestsGen12LP, givenGmmWhenSetClearColorParamsThenClearValueAddressEnable) {
auto size = sizeof(typename TGLLPFamily::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename TGLLPFamily::RENDER_SURFACE_STATE *>(surfaceState.get());
mockGmm.gmmResourceInfo->getResourceFlags()->Gpu.IndirectClearColor = true;
setClearColorParams<TGLLPFamily>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getClearValueAddressEnable(), true);
}
GEN12LPTEST_F(ImageSurfaceStateTestsGen12LP, givenGmmWithMediaCompressedWhenSetMipTailStartLodThenMipTailStartLodIsSet) {
auto size = sizeof(typename FamilyType::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename FamilyType::RENDER_SURFACE_STATE *>(surfaceState.get());
setMipTailStartLod<FamilyType>(castSurfaceState, nullptr);
EXPECT_EQ(castSurfaceState->getMipTailStartLod(), 0u);
setMipTailStartLod<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getMipTailStartLod(), mockGmm.gmmResourceInfo->getMipTailStartLodSurfaceState());
}

View File

@@ -1,16 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/simd_helper_tests.inl"
using namespace NEO;
using TestSimdConfigSet = ::testing::Test;
GEN12LPTEST_F(TestSimdConfigSet, GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturnedGen12LP) {
GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturned<typename FamilyType::GPGPU_WALKER>::TestBodyImpl();
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_container/cmdcontainer.h"
#include "shared/source/command_container/command_encoder.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "test.h"
#include "reg_configs_common.h"
using namespace NEO;
using CommandEncoderTest = Test<DeviceFixture>;
GEN12LPTEST_F(CommandEncoderTest, givenAdjustStateComputeModeStateComputeModeShowsNonCoherencySet) {
using STATE_COMPUTE_MODE = typename FamilyType::STATE_COMPUTE_MODE;
using FORCE_NON_COHERENT = typename STATE_COMPUTE_MODE::FORCE_NON_COHERENT;
CommandContainer cmdContainer;
bool ret = cmdContainer.initialize(pDevice);
ASSERT_TRUE(ret);
auto usedSpaceBefore = cmdContainer.getCommandStream()->getUsed();
// Adjust the State Compute Mode which sets FORCE_NON_COHERENT_FORCE_GPU_NON_COHERENT
EncodeStates<FamilyType>::adjustStateComputeMode(cmdContainer);
auto usedSpaceAfter = cmdContainer.getCommandStream()->getUsed();
ASSERT_GT(usedSpaceAfter, usedSpaceBefore);
auto expectedCmdSize = sizeof(STATE_COMPUTE_MODE);
auto cmdAddedSize = usedSpaceAfter - usedSpaceBefore;
EXPECT_EQ(expectedCmdSize, cmdAddedSize);
auto expectedScmCmd = FamilyType::cmdInitStateComputeMode;
expectedScmCmd.setForceNonCoherent(FORCE_NON_COHERENT::FORCE_NON_COHERENT_FORCE_GPU_NON_COHERENT);
expectedScmCmd.setMaskBits(FamilyType::stateComputeModeForceNonCoherentMask);
auto scmCmd = reinterpret_cast<STATE_COMPUTE_MODE *>(ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), usedSpaceBefore));
EXPECT_TRUE(memcmp(&expectedScmCmd, scmCmd, sizeof(STATE_COMPUTE_MODE)) == 0);
}
GEN12LPTEST_F(CommandEncoderTest, givenCommandContainerWhenEncodeL3StateThenSetCorrectMMIO) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeL3State<FamilyType>::encode(cmdContainer, false);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(commands.begin(), commands.end());
ASSERT_NE(itorLRI, commands.end());
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
EXPECT_EQ(cmd->getRegisterOffset(), 0xB134u);
EXPECT_EQ(cmd->getDataDword(), 0xD0000020u);
}

View File

@@ -1,179 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/preemption.h"
#include "helpers/debug_manager_state_restore.h"
#include "preamble/preamble_fixture.h"
#include "reg_configs_common.h"
using namespace NEO;
typedef PreambleFixture TglLpSlm;
TGLLPTEST_F(TglLpSlm, givenTglLpWhenPreambleIsBeingProgrammedThenThreadArbitrationPolicyIsIgnored) {
typedef TGLLPFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
LinearStream &cs = linearStream;
uint32_t l3Config = PreambleHelper<TGLLPFamily>::getL3Config(pDevice->getHardwareInfo(), true);
MockDevice mockDevice;
PreambleHelper<TGLLPFamily>::programPreamble(&linearStream, mockDevice, l3Config,
ThreadArbitrationPolicy::RoundRobin,
nullptr, nullptr);
parseCommands<TGLLPFamily>(cs);
// parse through commands and ensure that 0xE404 is not being programmed
EXPECT_EQ(0U, countMmio<FamilyType>(cmdList.begin(), cmdList.end(), 0xE404));
}
TGLLPTEST_F(TglLpSlm, givenTglLpIsL3Programing) {
bool isL3Programmable =
PreambleHelper<TGLLPFamily>::isL3Configurable(**platformDevices);
EXPECT_FALSE(isL3Programmable);
}
TGLLPTEST_F(TglLpSlm, shouldNotBeEnabledOnGen12) {
typedef TGLLPFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
LinearStream &cs = linearStream;
uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(pDevice->getHardwareInfo(), true);
PreambleHelper<FamilyType>::programL3(&cs, l3Config);
parseCommands<TGLLPFamily>(cs);
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(cmdList.begin(), cmdList.end());
ASSERT_EQ(cmdList.end(), itorLRI);
}
typedef PreambleFixture Gen12LpUrbEntryAllocationSize;
TGLLPTEST_F(Gen12LpUrbEntryAllocationSize, getUrbEntryAllocationSize) {
uint32_t actualVal = PreambleHelper<FamilyType>::getUrbEntryAllocationSize();
EXPECT_EQ(1024u, actualVal);
}
typedef PreambleVfeState Gen12LpPreambleVfeState;
TGLLPTEST_F(Gen12LpPreambleVfeState, WaOff) {
typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL;
testWaTable->waSendMIFLUSHBeforeVFE = 0;
LinearStream &cs = linearStream;
PreambleHelper<FamilyType>::programVFEState(&linearStream, pPlatform->getDevice(0)->getHardwareInfo(), 0, 0, 672u, aub_stream::EngineType::ENGINE_RCS);
parseCommands<FamilyType>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_FALSE(pc.getRenderTargetCacheFlushEnable());
EXPECT_FALSE(pc.getDepthCacheFlushEnable());
EXPECT_FALSE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}
TGLLPTEST_F(Gen12LpPreambleVfeState, givenCcsEngineWhenWaIsSetThenAppropriatePipeControlFlushesAreSet) {
typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL;
testWaTable->waSendMIFLUSHBeforeVFE = 1;
LinearStream &cs = linearStream;
PreambleHelper<FamilyType>::programVFEState(&linearStream, pPlatform->getDevice(0)->getHardwareInfo(), 0, 0, 672u, aub_stream::EngineType::ENGINE_CCS);
parseCommands<FamilyType>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_FALSE(pc.getRenderTargetCacheFlushEnable());
EXPECT_FALSE(pc.getDepthCacheFlushEnable());
EXPECT_TRUE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}
TGLLPTEST_F(Gen12LpPreambleVfeState, givenRcsEngineWhenWaIsSetThenAppropriatePipeControlFlushesAreSet) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
testWaTable->waSendMIFLUSHBeforeVFE = 1;
LinearStream &cs = linearStream;
PreambleHelper<FamilyType>::programVFEState(&linearStream, pPlatform->getDevice(0)->getHardwareInfo(), 0, 0, 672u, aub_stream::EngineType::ENGINE_RCS);
parseCommands<FamilyType>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_TRUE(pc.getRenderTargetCacheFlushEnable());
EXPECT_TRUE(pc.getDepthCacheFlushEnable());
EXPECT_TRUE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}
TGLLPTEST_F(Gen12LpPreambleVfeState, givenDefaultPipeControlWhenItIsProgrammedThenCsStallBitIsSet) {
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
PIPE_CONTROL *pipeControl = static_cast<PIPE_CONTROL *>(linearStream.getSpace(sizeof(PIPE_CONTROL)));
*pipeControl = FamilyType::cmdInitPipeControl;
EXPECT_EQ(1u, pipeControl->getCommandStreamerStallEnable());
}
TGLLPTEST_F(Gen12LpPreambleVfeState, givenCfeFusedEuDispatchFlagsWhenprogramAdditionalFieldsInVfeStateIsCalledThenGetDisableSlice0Subslice2ReturnsCorrectValues) {
using MEDIA_VFE_STATE = typename FamilyType::MEDIA_VFE_STATE;
DebugManagerStateRestore restorer;
auto pHwInfo = pPlatform->getDevice(0)->getExecutionEnvironment()->getMutableHardwareInfo();
auto pMediaVfeState = reinterpret_cast<MEDIA_VFE_STATE *>(linearStream.getSpace(sizeof(MEDIA_VFE_STATE)));
*pMediaVfeState = FamilyType::cmdInitMediaVfeState;
auto &waTable = pHwInfo->workaroundTable;
const std::array<std::tuple<bool, bool, int32_t>, 6> testParams{{std::make_tuple(false, false, 0),
std::make_tuple(false, true, 0),
std::make_tuple(false, false, -1),
std::make_tuple(true, false, 1),
std::make_tuple(true, true, -1),
std::make_tuple(true, true, 1)}};
for (const auto &params : testParams) {
bool expectedValue, waDisableFusedThreadScheduling;
int32_t debugKeyValue;
std::tie(expectedValue, waDisableFusedThreadScheduling, debugKeyValue) = params;
waTable.waDisableFusedThreadScheduling = waDisableFusedThreadScheduling;
::DebugManager.flags.CFEFusedEUDispatch.set(debugKeyValue);
PreambleHelper<FamilyType>::programAdditionalFieldsInVfeState(pMediaVfeState, *pHwInfo);
EXPECT_EQ(expectedValue, pMediaVfeState->getDisableSlice0Subslice2());
}
}
typedef PreambleFixture ThreadArbitrationGen12Lp;
GEN12LPTEST_F(ThreadArbitrationGen12Lp, givenPolicyWhenThreadArbitrationProgrammedThenDoNothing) {
LinearStream &cs = linearStream;
PreambleHelper<FamilyType>::programThreadArbitration(&cs, ThreadArbitrationPolicy::RoundRobin);
EXPECT_EQ(0u, cs.getUsed());
EXPECT_EQ(0u, PreambleHelper<FamilyType>::getDefaultThreadArbitrationPolicy());
}
typedef PreambleFixture PreemptionWatermarkGen12LP;
GEN12LPTEST_F(PreemptionWatermarkGen12LP, givenPreambleThenPreambleWorkAroundsIsNotProgrammed) {
PreambleHelper<FamilyType>::programGenSpecificPreambleWorkArounds(&linearStream, pDevice->getHardwareInfo());
parseCommands<FamilyType>(linearStream);
auto cmd = findMmioCmd<FamilyType>(cmdList.begin(), cmdList.end(), FfSliceCsChknReg2::address);
ASSERT_EQ(nullptr, cmd);
MockDevice mockDevice;
mockDevice.setDebuggerActive(false);
size_t expectedSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(mockDevice);
EXPECT_EQ(expectedSize, PreambleHelper<FamilyType>::getAdditionalCommandsSize(mockDevice));
mockDevice.setDebuggerActive(true);
expectedSize += PreambleHelper<FamilyType>::getKernelDebuggingCommandsSize(mockDevice.isDebuggerActive());
EXPECT_EQ(expectedSize, PreambleHelper<FamilyType>::getAdditionalCommandsSize(mockDevice));
}

View File

@@ -1,84 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "fixtures/preemption_fixture.h"
#include "opencl/test/unit_test/mocks/mock_buffer.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_csr.h"
using namespace NEO;
using Gen12LpPreemptionTests = DevicePreemptionTests;
template <>
PreemptionTestHwDetails GetPreemptionTestHwDetails<TGLLPFamily>() {
PreemptionTestHwDetails ret;
ret.modeToRegValueMap[PreemptionMode::ThreadGroup] = DwordBuilder::build(1, true) | DwordBuilder::build(2, true, false);
ret.modeToRegValueMap[PreemptionMode::MidBatch] = DwordBuilder::build(2, true) | DwordBuilder::build(1, true, false);
ret.modeToRegValueMap[PreemptionMode::MidThread] = DwordBuilder::build(2, true, false) | DwordBuilder::build(1, true, false);
ret.defaultRegValue = ret.modeToRegValueMap[PreemptionMode::MidBatch];
ret.regAddress = 0x2580u;
return ret;
}
GEN12LPTEST_F(Gen12LpPreemptionTests, whenProgramStateSipIsCalledThenStateSipCmdIsNotAddedToStream) {
size_t requiredSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(device->getDevice());
EXPECT_EQ(0U, requiredSize);
LinearStream cmdStream{nullptr, 0};
PreemptionHelper::programStateSip<FamilyType>(cmdStream, device->getDevice());
EXPECT_EQ(0U, cmdStream.getUsed());
}
GEN12LPTEST_F(Gen12LpPreemptionTests, getRequiredCmdQSize) {
size_t expectedSize = 0;
EXPECT_EQ(expectedSize, PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice()));
}
GEN12LPTEST_F(Gen12LpPreemptionTests, applyPreemptionWaCmds) {
size_t usedSize = 0;
auto &cmdStream = cmdQ->getCS(0);
PreemptionHelper::applyPreemptionWaCmdsBegin<FamilyType>(&cmdStream, device->getDevice());
EXPECT_EQ(usedSize, cmdStream.getUsed());
PreemptionHelper::applyPreemptionWaCmdsEnd<FamilyType>(&cmdStream, device->getDevice());
EXPECT_EQ(usedSize, cmdStream.getUsed());
}
GEN12LPTEST_F(Gen12LpPreemptionTests, givenInterfaceDescriptorDataWhenMidThreadPreemptionModeThenSetDisableThreadPreemptionBitToDisable) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
INTERFACE_DESCRIPTOR_DATA iddArg;
iddArg = FamilyType::cmdInitInterfaceDescriptorData;
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidThread);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE, iddArg.getThreadPreemptionDisable());
}
GEN12LPTEST_F(Gen12LpPreemptionTests, givenInterfaceDescriptorDataWhenNoMidThreadPreemptionModeThenSetDisableThreadPreemptionBitToEnable) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
INTERFACE_DESCRIPTOR_DATA iddArg;
iddArg = FamilyType::cmdInitInterfaceDescriptorData;
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::Disabled);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE, iddArg.getThreadPreemptionDisable());
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidBatch);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE, iddArg.getThreadPreemptionDisable());
iddArg.setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::ThreadGroup);
EXPECT_EQ(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE, iddArg.getThreadPreemptionDisable());
}

View File

@@ -1,15 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_TESTS_GEN8
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/image_surface_state_tests_gen8.cpp
${CMAKE_CURRENT_SOURCE_DIR}/simd_helper_tests_gen8.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_preamble_gen8.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_preemption_gen8.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_TESTS_GEN8 ${NEO_CORE_TESTS_GEN8})
add_subdirectories()

View File

@@ -1,71 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "gtest/gtest.h"
using GenStruct = NEO::GEN8;
using GenGfxFamily = NEO::BDWFamily;
#include "opencl/test/unit_test/gen_common/cmd_parse_base.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_base_mi_arb.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_gpgpu_walker.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_sip.inl"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/helpers/hw_parse.inl"
template <>
size_t CmdParse<GenGfxFamily>::getCommandLengthHwSpecific(void *cmd) {
{
auto pCmd = genCmdCast<GPGPU_WALKER *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_VFE_STATE *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_STATE_FLUSH *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
return 0;
}
template <>
const char *CmdParse<GenGfxFamily>::getCommandNameHwSpecific(void *cmd) {
if (nullptr != genCmdCast<GPGPU_WALKER *>(cmd)) {
return "GPGPU_WALKER";
}
if (nullptr != genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd)) {
return "MEDIA_INTERFACE_DESCRIPTOR_LOAD";
}
if (nullptr != genCmdCast<MEDIA_VFE_STATE *>(cmd)) {
return "MEDIA_VFE_STATE";
}
if (nullptr != genCmdCast<MEDIA_STATE_FLUSH *>(cmd)) {
return "MEDIA_STATE_FLUSH";
}
return "UNKNOWN";
}
template struct CmdParse<GenGfxFamily>;
namespace NEO {
template void HardwareParse::findHardwareCommands<BDWFamily>();
template void HardwareParse::findHardwareCommands<BDWFamily>(IndirectHeap *);
template const void *HardwareParse::getStatelessArgumentPointer<BDWFamily>(const Kernel &kernel, uint32_t indexArg, IndirectHeap &ioh);
} // namespace NEO

View File

@@ -1,32 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "image/image_surface_state_fixture.h"
using ImageSurfaceStateTestsGen8 = ImageSurfaceStateTests;
GEN8TEST_F(ImageSurfaceStateTestsGen8, givenGmmWithMediaCompressedWhenSetFlagsForMediaCompressionThenAuxiliarySurfaceNoneIsSet) {
auto size = sizeof(typename FamilyType::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename FamilyType::RENDER_SURFACE_STATE *>(surfaceState.get());
castSurfaceState->setAuxiliarySurfaceMode(FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = false;
setFlagsForMediaCompression<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = true;
setFlagsForMediaCompression<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_NONE);
}
GEN8TEST_F(ImageSurfaceStateTestsGen8, givenGmmWithMediaCompressedWhenSetMipTailStartLodThenMipTailStartLodIsSet) {
auto size = sizeof(typename FamilyType::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename FamilyType::RENDER_SURFACE_STATE *>(surfaceState.get());
setMipTailStartLod<FamilyType>(castSurfaceState, nullptr);
}

View File

@@ -1,16 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/simd_helper_tests.inl"
using namespace NEO;
using TestSimdConfigSet = ::testing::Test;
GEN8TEST_F(TestSimdConfigSet, GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturnedGen8) {
GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturned<typename FamilyType::GPGPU_WALKER>::TestBodyImpl();
}

View File

@@ -1,107 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/thread_arbitration_policy.h"
#include "shared/source/helpers/preamble.h"
#include "preamble/preamble_fixture.h"
#include "opencl/source/gen8/reg_configs.h"
#include "opencl/test/unit_test/fixtures/platform_fixture.h"
using namespace NEO;
typedef PreambleFixture BdwSlm;
BDWTEST_F(BdwSlm, shouldBeEnabledOnGen8) {
typedef BDWFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
LinearStream &cs = linearStream;
uint32_t l3Config = PreambleHelper<BDWFamily>::getL3Config(**platformDevices, true);
PreambleHelper<BDWFamily>::programL3(&cs, l3Config);
parseCommands<BDWFamily>(cs);
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorLRI);
const auto &lri = *reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
auto RegisterOffset = L3CNTLRegisterOffset<BDWFamily>::registerOffset;
EXPECT_EQ(RegisterOffset, lri.getRegisterOffset());
EXPECT_EQ(1u, lri.getDataDword() & 1);
}
typedef PreambleFixture Gen8L3Config;
BDWTEST_F(Gen8L3Config, checkNoSLM) {
bool slmUsed = false;
uint32_t l3Config = 0;
l3Config = getL3ConfigHelper<IGFX_BROADWELL>(slmUsed);
EXPECT_EQ(0x80000340u, l3Config);
uint32_t errorDetectionBehaviorControlBit = 1 << 9;
EXPECT_TRUE((l3Config & errorDetectionBehaviorControlBit) != 0);
}
BDWTEST_F(Gen8L3Config, checkSLM) {
bool slmUsed = true;
uint32_t l3Config = 0;
l3Config = getL3ConfigHelper<IGFX_BROADWELL>(slmUsed);
EXPECT_EQ(0x60000321u, l3Config);
uint32_t errorDetectionBehaviorControlBit = 1 << 9;
EXPECT_TRUE((l3Config & errorDetectionBehaviorControlBit) != 0);
}
BDWTEST_F(Gen8L3Config, givenGen8IsL3Programing) {
bool l3ConfigDifference;
bool isL3Programmable;
l3ConfigDifference =
PreambleHelper<BDWFamily>::getL3Config(**platformDevices, true) !=
PreambleHelper<BDWFamily>::getL3Config(**platformDevices, false);
isL3Programmable =
PreambleHelper<BDWFamily>::isL3Configurable(**platformDevices);
EXPECT_EQ(l3ConfigDifference, isL3Programmable);
}
typedef PreambleFixture ThreadArbitrationGen8;
BDWTEST_F(ThreadArbitrationGen8, givenPolicyWhenThreadArbitrationProgrammedThenDoNothing) {
typedef BDWFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
LinearStream &cs = linearStream;
PreambleHelper<BDWFamily>::programThreadArbitration(&cs, ThreadArbitrationPolicy::RoundRobin);
EXPECT_EQ(0u, cs.getUsed());
MockDevice device;
EXPECT_EQ(0u, PreambleHelper<BDWFamily>::getAdditionalCommandsSize(device));
EXPECT_EQ(0u, PreambleHelper<BDWFamily>::getThreadArbitrationCommandsSize());
EXPECT_EQ(0u, PreambleHelper<BDWFamily>::getDefaultThreadArbitrationPolicy());
}
typedef PreambleFixture Gen8UrbEntryAllocationSize;
BDWTEST_F(Gen8UrbEntryAllocationSize, getUrbEntryAllocationSize) {
uint32_t actualVal = PreambleHelper<FamilyType>::getUrbEntryAllocationSize();
EXPECT_EQ(0x782u, actualVal);
}
BDWTEST_F(PreambleVfeState, basic) {
typedef BDWFamily::PIPE_CONTROL PIPE_CONTROL;
LinearStream &cs = linearStream;
PreambleHelper<BDWFamily>::programVFEState(&linearStream, **platformDevices, 0, 0, 168u, aub_stream::EngineType::ENGINE_RCS);
parseCommands<BDWFamily>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_TRUE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}

View File

@@ -1,315 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/linear_stream.h"
#include "shared/source/command_stream/preemption.h"
#include "shared/source/helpers/hw_helper.h"
#include "shared/source/memory_manager/memory_constants.h"
#include "fixtures/preemption_fixture.h"
#include "opencl/test/unit_test/command_queue/enqueue_fixture.h"
#include "opencl/test/unit_test/fixtures/hello_world_fixture.h"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/mocks/mock_buffer.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_csr.h"
#include "opencl/test/unit_test/mocks/mock_submissions_aggregator.h"
using namespace NEO;
using Gen8PreemptionTests = DevicePreemptionTests;
using Gen8PreemptionEnqueueKernelTest = PreemptionEnqueueKernelTest;
template <>
PreemptionTestHwDetails GetPreemptionTestHwDetails<BDWFamily>() {
PreemptionTestHwDetails ret;
ret.modeToRegValueMap[PreemptionMode::ThreadGroup] = 0;
ret.modeToRegValueMap[PreemptionMode::MidBatch] = (1 << 2);
ret.defaultRegValue = ret.modeToRegValueMap[PreemptionMode::MidBatch];
ret.regAddress = 0x2248u;
return ret;
}
GEN8TEST_F(Gen8PreemptionTests, allowThreadGroupPreemptionReturnsTrue) {
PreemptionFlags flags = {};
PreemptionHelper::setPreemptionLevelFlags(flags, device->getDevice(), kernel.get());
EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(flags));
}
GEN8TEST_F(Gen8PreemptionTests, whenProgramStateSipIsCalledThenNoCmdsAreProgrammed) {
size_t requiredSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(device->getDevice());
EXPECT_EQ(0U, requiredSize);
LinearStream cmdStream{nullptr, 0};
PreemptionHelper::programStateSip<FamilyType>(cmdStream, device->getDevice());
EXPECT_EQ(0U, cmdStream.getUsed());
}
GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogram) {
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
csr.getMemoryManager()->setForce32BitAllocations(false);
csr.setMediaVFEStateDirty(false);
size_t off[3] = {0, 0, 0};
size_t gws[3] = {1, 1, 1};
MockKernelWithInternals mockKernel(*pClDevice);
HardwareParse hwParser;
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwParser.parseCommands<FamilyType>(csr.commandStream);
auto offset = csr.commandStream.getUsed();
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
pCmdQ->flush();
hwParser.parseCommands<FamilyType>(csr.commandStream, offset);
size_t numMmiosFound = countMmio<FamilyType>(hwParser.cmdList.begin(), hwParser.cmdList.end(), 0x2248u);
EXPECT_EQ(1U, numMmiosFound);
}
GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenValidKernelForPreemptionWhenEnqueueKernelCalledThenPassDevicePreemptionMode) {
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
auto mockCsr = new MockCsrHw2<FamilyType>(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
pDevice->resetCommandStreamReceiver(mockCsr);
MockKernelWithInternals mockKernel(*pClDevice);
PreemptionFlags flags = {};
MultiDispatchInfo multiDispatch(mockKernel.mockKernel);
EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(*pDevice, multiDispatch));
size_t gws[3] = {1, 0, 0};
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
pCmdQ->flush();
EXPECT_EQ(1, mockCsr->flushCalledCount);
EXPECT_EQ(PreemptionMode::ThreadGroup, mockCsr->passedDispatchFlags.preemptionMode);
}
GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenValidKernelForPreemptionWhenEnqueueKernelCalledAndBlockedThenPassDevicePreemptionMode) {
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
auto mockCsr = new MockCsrHw2<FamilyType>(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
pDevice->resetCommandStreamReceiver(mockCsr);
MockKernelWithInternals mockKernel(*pClDevice);
PreemptionFlags flags = {};
PreemptionHelper::setPreemptionLevelFlags(flags, *pDevice, mockKernel.mockKernel);
EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(pDevice->getPreemptionMode(), flags));
UserEvent userEventObj;
cl_event userEvent = &userEventObj;
size_t gws[3] = {1, 0, 0};
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 1, &userEvent, nullptr);
pCmdQ->flush();
EXPECT_EQ(0, mockCsr->flushCalledCount);
userEventObj.setStatus(CL_COMPLETE);
pCmdQ->flush();
EXPECT_EQ(1, mockCsr->flushCalledCount);
EXPECT_EQ(PreemptionMode::ThreadGroup, mockCsr->passedDispatchFlags.preemptionMode);
}
GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenDisabledPreemptionWhenEnqueueKernelCalledThenPassDisabledPreemptionMode) {
pDevice->setPreemptionMode(PreemptionMode::Disabled);
auto mockCsr = new MockCsrHw2<FamilyType>(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
pDevice->resetCommandStreamReceiver(mockCsr);
MockKernelWithInternals mockKernel(*pClDevice);
PreemptionFlags flags = {};
PreemptionHelper::setPreemptionLevelFlags(flags, *pDevice, mockKernel.mockKernel);
EXPECT_EQ(PreemptionMode::Disabled, PreemptionHelper::taskPreemptionMode(pDevice->getPreemptionMode(), flags));
size_t gws[3] = {1, 0, 0};
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
pCmdQ->flush();
EXPECT_EQ(1, mockCsr->flushCalledCount);
EXPECT_EQ(PreemptionMode::Disabled, mockCsr->passedDispatchFlags.preemptionMode);
}
GEN8TEST_F(Gen8PreemptionTests, getPreemptionWaCsSizeMidBatch) {
size_t expectedSize = 0;
device->setPreemptionMode(PreemptionMode::MidBatch);
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN8TEST_F(Gen8PreemptionTests, getPreemptionWaCsSizeThreadGroupNoWa) {
size_t expectedSize = 0;
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN8TEST_F(Gen8PreemptionTests, getPreemptionWaCsSizeThreadGroupWa) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
size_t expectedSize = 2 * sizeof(MI_LOAD_REGISTER_IMM);
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN8TEST_F(Gen8PreemptionTests, getPreemptionWaCsSizeMidThreadNoWa) {
size_t expectedSize = 0;
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN8TEST_F(Gen8PreemptionTests, getPreemptionWaCsSizeMidThreadWa) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
size_t expectedSize = 2 * sizeof(MI_LOAD_REGISTER_IMM);
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN8TEST_F(Gen8PreemptionTests, givenInterfaceDescriptorDataWhenAnyPreemptionModeThenNoChange) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
INTERFACE_DESCRIPTOR_DATA idd;
INTERFACE_DESCRIPTOR_DATA iddArg;
int ret;
idd = FamilyType::cmdInitInterfaceDescriptorData;
iddArg = FamilyType::cmdInitInterfaceDescriptorData;
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::Disabled);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidBatch);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::ThreadGroup);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidThread);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
}
struct Gen8PreemptionTestsLinearStream : public Gen8PreemptionTests {
void SetUp() override {
Gen8PreemptionTests::SetUp();
cmdBufferAllocation = alignedMalloc(MemoryConstants::pageSize, MemoryConstants::pageSize);
cmdBuffer.replaceBuffer(cmdBufferAllocation, MemoryConstants::pageSize);
}
void TearDown() override {
alignedFree(cmdBufferAllocation);
Gen8PreemptionTests::TearDown();
}
LinearStream cmdBuffer;
void *cmdBufferAllocation;
HardwareParse cmdBufferParser;
};
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenMidBatchPreemptionWhenProgrammingWaCmdsBeginThenExpectNoCmds) {
device->setPreemptionMode(PreemptionMode::MidBatch);
PreemptionHelper::applyPreemptionWaCmdsBegin<FamilyType>(&cmdBuffer, device->getDevice());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenMidBatchPreemptionWhenProgrammingWaCmdsEndThenExpectNoCmds) {
device->setPreemptionMode(PreemptionMode::MidBatch);
PreemptionHelper::applyPreemptionWaCmdsEnd<FamilyType>(&cmdBuffer, device->getDevice());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenThreadGroupPreemptionNoWaSetWhenProgrammingWaCmdsBeginThenExpectNoCmd) {
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
PreemptionHelper::applyPreemptionWaCmdsBegin<FamilyType>(&cmdBuffer, device->getDevice());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenThreadGroupPreemptionNoWaSetWhenProgrammingWaCmdsEndThenExpectNoCmd) {
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
PreemptionHelper::applyPreemptionWaCmdsEnd<FamilyType>(&cmdBuffer, device->getDevice());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenThreadGroupPreemptionWaSetWhenProgrammingWaCmdsBeginThenExpectMmioCmd) {
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
PreemptionHelper::applyPreemptionWaCmdsBegin<FamilyType>(&cmdBuffer, device->getDevice());
cmdBufferParser.parseCommands<FamilyType>(cmdBuffer);
cmdBufferParser.findHardwareCommands<FamilyType>();
GenCmdList::iterator itMmioCmd = cmdBufferParser.lriList.begin();
ASSERT_NE(cmdBufferParser.lriList.end(), itMmioCmd);
MI_LOAD_REGISTER_IMM *mmioCmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itMmioCmd);
EXPECT_EQ(0x2600u, mmioCmd->getRegisterOffset());
EXPECT_EQ(0xFFFFFFFFu, mmioCmd->getDataDword());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenThreadGroupPreemptionWaSetWhenProgrammingWaCmdsEndThenExpectMmioCmd) {
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
PreemptionHelper::applyPreemptionWaCmdsEnd<FamilyType>(&cmdBuffer, device->getDevice());
cmdBufferParser.parseCommands<FamilyType>(cmdBuffer);
cmdBufferParser.findHardwareCommands<FamilyType>();
GenCmdList::iterator itMmioCmd = cmdBufferParser.lriList.begin();
ASSERT_NE(cmdBufferParser.lriList.end(), itMmioCmd);
MI_LOAD_REGISTER_IMM *mmioCmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itMmioCmd);
EXPECT_EQ(0x2600u, mmioCmd->getRegisterOffset());
EXPECT_EQ(0x00000000u, mmioCmd->getDataDword());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenMidThreadPreemptionNoWaSetWhenProgrammingWaCmdsBeginThenExpectNoCmd) {
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
PreemptionHelper::applyPreemptionWaCmdsBegin<FamilyType>(&cmdBuffer, device->getDevice());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenMidThreadPreemptionNoWaSetWhenProgrammingWaCmdsEndThenExpectNoCmd) {
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
PreemptionHelper::applyPreemptionWaCmdsEnd<FamilyType>(&cmdBuffer, device->getDevice());
EXPECT_EQ(0u, cmdBuffer.getUsed());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenMidThreadPreemptionWaSetWhenProgrammingWaCmdsBeginThenExpectMmioCmd) {
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
PreemptionHelper::applyPreemptionWaCmdsBegin<FamilyType>(&cmdBuffer, device->getDevice());
cmdBufferParser.parseCommands<FamilyType>(cmdBuffer);
cmdBufferParser.findHardwareCommands<FamilyType>();
GenCmdList::iterator itMmioCmd = cmdBufferParser.lriList.begin();
ASSERT_NE(cmdBufferParser.lriList.end(), itMmioCmd);
MI_LOAD_REGISTER_IMM *mmioCmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itMmioCmd);
EXPECT_EQ(0x2600u, mmioCmd->getRegisterOffset());
EXPECT_EQ(0xFFFFFFFFu, mmioCmd->getDataDword());
}
GEN8TEST_F(Gen8PreemptionTestsLinearStream, givenMidThreadPreemptionWaSetWhenProgrammingWaCmdsEndThenExpectMmioCmd) {
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
PreemptionHelper::applyPreemptionWaCmdsEnd<FamilyType>(&cmdBuffer, device->getDevice());
cmdBufferParser.parseCommands<FamilyType>(cmdBuffer);
cmdBufferParser.findHardwareCommands<FamilyType>();
GenCmdList::iterator itMmioCmd = cmdBufferParser.lriList.begin();
ASSERT_NE(cmdBufferParser.lriList.end(), itMmioCmd);
MI_LOAD_REGISTER_IMM *mmioCmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itMmioCmd);
EXPECT_EQ(0x2600u, mmioCmd->getRegisterOffset());
EXPECT_EQ(0x00000000u, mmioCmd->getDataDword());
}

View File

@@ -1,16 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_TESTS_GEN9
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/image_surface_state_tests_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/preamble_tests_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/simd_helper_tests_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_command_encoder_gen9.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_preemption_gen9.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_TESTS_GEN9 ${NEO_CORE_TESTS_GEN9})
add_subdirectories()

View File

@@ -1,89 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "gtest/gtest.h"
using GenStruct = NEO::GEN9;
using GenGfxFamily = NEO::SKLFamily;
#include "opencl/test/unit_test/gen_common/cmd_parse_base.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_base_mi_arb.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_gpgpu_walker.inl"
#include "opencl/test/unit_test/gen_common/cmd_parse_sip.inl"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/helpers/hw_parse.inl"
template <>
size_t CmdParse<GenGfxFamily>::getCommandLengthHwSpecific(void *cmd) {
{
auto pCmd = genCmdCast<GPGPU_WALKER *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_VFE_STATE *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<MEDIA_STATE_FLUSH *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
{
auto pCmd = genCmdCast<STATE_SIP *>(cmd);
if (pCmd)
return pCmd->TheStructure.Common.DwordLength + 2;
}
return 0;
}
template <>
const char *CmdParse<GenGfxFamily>::getCommandNameHwSpecific(void *cmd) {
if (nullptr != genCmdCast<GPGPU_WALKER *>(cmd)) {
return "GPGPU_WALKER";
}
if (nullptr != genCmdCast<MEDIA_INTERFACE_DESCRIPTOR_LOAD *>(cmd)) {
return "MEDIA_INTERFACE_DESCRIPTOR_LOAD";
}
if (nullptr != genCmdCast<MEDIA_VFE_STATE *>(cmd)) {
return "MEDIA_VFE_STATE";
}
if (nullptr != genCmdCast<MEDIA_STATE_FLUSH *>(cmd)) {
return "MEDIA_STATE_FLUSH";
}
if (nullptr != genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(cmd)) {
return "GPGPU_CSR_BASE_ADDRESS";
}
if (nullptr != genCmdCast<STATE_SIP *>(cmd)) {
return "STATE_SIP";
}
return "UNKNOWN";
}
template struct CmdParse<GenGfxFamily>;
namespace NEO {
template void HardwareParse::findHardwareCommands<SKLFamily>();
template void HardwareParse::findHardwareCommands<SKLFamily>(IndirectHeap *);
template const void *HardwareParse::getStatelessArgumentPointer<SKLFamily>(const Kernel &kernel, uint32_t indexArg, IndirectHeap &ioh);
} // namespace NEO

View File

@@ -1,38 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "image/image_surface_state_fixture.h"
using ImageSurfaceStateTestsGen9 = ImageSurfaceStateTests;
GEN9TEST_F(ImageSurfaceStateTestsGen9, givenGmmWithMediaCompressedWhenSetFlagsForMediaCompressionThenAuxiliarySurfaceNoneIsSet) {
auto size = sizeof(typename FamilyType::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename FamilyType::RENDER_SURFACE_STATE *>(surfaceState.get());
castSurfaceState->setAuxiliarySurfaceMode(FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = false;
setFlagsForMediaCompression<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_CCS_E);
mockGmm.gmmResourceInfo->getResourceFlags()->Info.MediaCompressed = true;
setFlagsForMediaCompression<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getAuxiliarySurfaceMode(), FamilyType::RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_NONE);
}
GEN9TEST_F(ImageSurfaceStateTestsGen9, givenGmmWithMediaCompressedWhenSetMipTailStartLodThenMipTailStartLodIsSet) {
auto size = sizeof(typename FamilyType::RENDER_SURFACE_STATE);
auto surfaceState = std::make_unique<char[]>(size);
auto castSurfaceState = reinterpret_cast<typename FamilyType::RENDER_SURFACE_STATE *>(surfaceState.get());
setMipTailStartLod<FamilyType>(castSurfaceState, nullptr);
EXPECT_EQ(castSurfaceState->getMipTailStartLod(), 0u);
setMipTailStartLod<FamilyType>(castSurfaceState, &mockGmm);
EXPECT_EQ(castSurfaceState->getMipTailStartLod(), mockGmm.gmmResourceInfo->getMipTailStartLodSurfaceState());
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/debug_manager_state_restore.h"
#include "source_level_debugger/source_level_debugger_preamble_test.h"
#include "gtest/gtest.h"
using namespace NEO;
typedef SKLFamily GfxFamily;
#include "source_level_debugger/source_level_debugger_preamble_test.inl"
using PreambleTestGen9 = ::testing::Test;
GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDebuggingActiveWhenStateSipIsProgrammedThenCorrectSipKernelIsUsed) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDebuggingActiveWhenStateSipIsProgrammedThenCorrectSipKernelIsUsedTest();
}
GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN9TEST_F(PreambleTestGen9, givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsed) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenPreemptionDisabledAndDebuggingActiveWhenPreambleIsProgrammedThenCorrectSipKernelIsUsedTest();
}
GEN9TEST_F(PreambleTestGen9, givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenPreemptionDisabledAndDebuggingActiveWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsProgrammedThenCorrectSipKernelIsUsed) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleIsProgrammedThenCorrectSipKernelIsUsedTest();
}
GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenMidThreadPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN9TEST_F(PreambleTestGen9, givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN9TEST_F(PreambleTestGen9, givenKernelDebuggingActiveAndDisabledPreemptionWhenGetAdditionalCommandsSizeIsCalledThen2MiLoadRegisterImmCmdsAreInlcuded) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenKernelDebuggingActiveAndDisabledPreemptionWhenGetAdditionalCommandsSizeIsCalledThen2MiLoadRegisterImmCmdsAreInlcudedTest();
}
GEN9TEST_F(PreambleTestGen9, givenGen9IsL3Programing) {
bool l3ConfigDifference;
bool isL3Programmable;
l3ConfigDifference =
PreambleHelper<FamilyType>::getL3Config(**platformDevices, true) !=
PreambleHelper<FamilyType>::getL3Config(**platformDevices, false);
isL3Programmable =
PreambleHelper<FamilyType>::isL3Configurable(**platformDevices);
EXPECT_EQ(l3ConfigDifference, isL3Programmable);
}

View File

@@ -1,16 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/simd_helper_tests.inl"
using namespace NEO;
using TestSimdConfigSet = ::testing::Test;
GEN9TEST_F(TestSimdConfigSet, GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturnedGen9) {
GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturned<typename FamilyType::GPGPU_WALKER>::TestBodyImpl();
}

View File

@@ -1,12 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_TESTS_GEN9_SKL
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_preamble_skl.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_TESTS_GEN9_SKL ${NEO_CORE_TESTS_GEN9_SKL})
add_subdirectories()

View File

@@ -1,140 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/preemption.h"
#include "shared/source/command_stream/thread_arbitration_policy.h"
#include "shared/source/helpers/preamble.h"
#include "helpers/debug_manager_state_restore.h"
#include "preamble/preamble_fixture.h"
#include "opencl/source/gen9/reg_configs.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
using namespace NEO;
typedef PreambleFixture SklSlm;
SKLTEST_F(SklSlm, shouldBeEnabledOnGen9) {
typedef SKLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
LinearStream &cs = linearStream;
uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(**platformDevices, true);
PreambleHelper<SKLFamily>::programL3(&cs, l3Config);
parseCommands<SKLFamily>(cs);
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorLRI);
const auto &lri = *reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
auto RegisterOffset = L3CNTLRegisterOffset<FamilyType>::registerOffset;
EXPECT_EQ(RegisterOffset, lri.getRegisterOffset());
EXPECT_EQ(1u, lri.getDataDword() & 1);
}
typedef PreambleFixture Gen9L3Config;
SKLTEST_F(Gen9L3Config, checkNoSLM) {
bool slmUsed = false;
uint32_t l3Config = 0;
l3Config = getL3ConfigHelper<IGFX_SKYLAKE>(slmUsed);
EXPECT_EQ(0x80000340u, l3Config);
uint32_t errorDetectionBehaviorControlBit = 1 << 9;
EXPECT_TRUE((l3Config & errorDetectionBehaviorControlBit) != 0);
l3Config = getL3ConfigHelper<IGFX_BROXTON>(slmUsed);
EXPECT_EQ(0x80000340u, l3Config);
EXPECT_TRUE((l3Config & errorDetectionBehaviorControlBit) != 0);
}
SKLTEST_F(Gen9L3Config, checkSLM) {
bool slmUsed = true;
uint32_t l3Config = 0;
l3Config = getL3ConfigHelper<IGFX_SKYLAKE>(slmUsed);
EXPECT_EQ(0x60000321u, l3Config);
uint32_t errorDetectionBehaviorControlBit = 1 << 9;
EXPECT_TRUE((l3Config & errorDetectionBehaviorControlBit) != 0);
l3Config = getL3ConfigHelper<IGFX_BROXTON>(slmUsed);
EXPECT_EQ(0x60000321u, l3Config);
EXPECT_TRUE((l3Config & errorDetectionBehaviorControlBit) != 0);
}
typedef PreambleFixture ThreadArbitration;
SKLTEST_F(ThreadArbitration, givenPreambleWhenItIsProgrammedThenThreadArbitrationIsSetToRoundRobin) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.ForcePreemptionMode.set(static_cast<int32_t>(PreemptionMode::Disabled));
typedef SKLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
typedef SKLFamily::PIPE_CONTROL PIPE_CONTROL;
LinearStream &cs = linearStream;
uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(**platformDevices, true);
MockDevice mockDevice;
PreambleHelper<SKLFamily>::programPreamble(&linearStream, mockDevice, l3Config,
ThreadArbitrationPolicy::RoundRobin,
nullptr, nullptr);
parseCommands<SKLFamily>(cs);
auto ppC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(ppC, cmdList.end());
auto itorLRI = reverse_find<MI_LOAD_REGISTER_IMM *>(cmdList.rbegin(), cmdList.rend());
ASSERT_NE(cmdList.rend(), itorLRI);
const auto &lri = *reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
EXPECT_EQ(0xE404u, lri.getRegisterOffset());
EXPECT_EQ(0x100u, lri.getDataDword());
MockDevice device;
EXPECT_EQ(0u, PreambleHelper<SKLFamily>::getAdditionalCommandsSize(device));
EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL), PreambleHelper<SKLFamily>::getThreadArbitrationCommandsSize());
}
SKLTEST_F(ThreadArbitration, defaultArbitrationPolicy) {
EXPECT_EQ(ThreadArbitrationPolicy::RoundRobin, PreambleHelper<SKLFamily>::getDefaultThreadArbitrationPolicy());
}
GEN9TEST_F(PreambleVfeState, WaOff) {
typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL;
testWaTable->waSendMIFLUSHBeforeVFE = 0;
LinearStream &cs = linearStream;
PreambleHelper<FamilyType>::programVFEState(&linearStream, pPlatform->getDevice(0)->getHardwareInfo(), 0, 0, 168u, aub_stream::EngineType::ENGINE_RCS);
parseCommands<FamilyType>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_FALSE(pc.getRenderTargetCacheFlushEnable());
EXPECT_FALSE(pc.getDepthCacheFlushEnable());
EXPECT_FALSE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}
GEN9TEST_F(PreambleVfeState, WaOn) {
typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL;
testWaTable->waSendMIFLUSHBeforeVFE = 1;
LinearStream &cs = linearStream;
PreambleHelper<FamilyType>::programVFEState(&linearStream, pPlatform->getDevice(0)->getHardwareInfo(), 0, 0, 168u, aub_stream::EngineType::ENGINE_RCS);
parseCommands<FamilyType>(cs);
auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), itorPC);
const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
EXPECT_TRUE(pc.getRenderTargetCacheFlushEnable());
EXPECT_TRUE(pc.getDepthCacheFlushEnable());
EXPECT_TRUE(pc.getDcFlushEnable());
EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_container/cmdcontainer.h"
#include "shared/source/command_container/command_encoder.h"
#include "opencl/test/unit_test/fixtures/device_fixture.h"
#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h"
#include "test.h"
#include "reg_configs_common.h"
using namespace NEO;
using CommandEncoderTest = Test<DeviceFixture>;
GEN9TEST_F(CommandEncoderTest, appendsASetMMIO) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeL3State<FamilyType>::encode(cmdContainer, false);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(commands.begin(), commands.end());
ASSERT_NE(itorLRI, commands.end());
}
GEN9TEST_F(CommandEncoderTest, givenNoSLMSetCorrectMMIO) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeL3State<FamilyType>::encode(cmdContainer, false);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(commands.begin(), commands.end());
ASSERT_NE(itorLRI, commands.end());
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
auto expectedData = PreambleHelper<FamilyType>::isL3Configurable(cmdContainer.getDevice()->getHardwareInfo()) ? 0x80000340u : 0x60000321u;
EXPECT_EQ(cmd->getRegisterOffset(), 0x7034u);
EXPECT_EQ(cmd->getDataDword(), expectedData);
}
GEN9TEST_F(CommandEncoderTest, givenSLMSetCorrectMMIO) {
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeL3State<FamilyType>::encode(cmdContainer, true);
GenCmdList commands;
CmdParse<FamilyType>::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed());
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(commands.begin(), commands.end());
ASSERT_NE(itorLRI, commands.end());
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(*itorLRI);
EXPECT_EQ(cmd->getRegisterOffset(), 0x7034u);
EXPECT_EQ(cmd->getDataDword(), 0x60000321u);
}

View File

@@ -1,534 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/preemption.h"
#include "shared/source/helpers/hw_helper.h"
#include "fixtures/preemption_fixture.h"
#include "opencl/source/built_ins/built_ins.h"
#include "opencl/test/unit_test/command_queue/enqueue_fixture.h"
#include "opencl/test/unit_test/helpers/hw_parse.h"
#include "opencl/test/unit_test/mocks/mock_buffer.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_csr.h"
#include "opencl/test/unit_test/mocks/mock_submissions_aggregator.h"
namespace NEO {
template <>
void HardwareParse::findCsrBaseAddress<SKLFamily>() {
typedef typename GEN9::GPGPU_CSR_BASE_ADDRESS GPGPU_CSR_BASE_ADDRESS;
itorGpgpuCsrBaseAddress = find<GPGPU_CSR_BASE_ADDRESS *>(cmdList.begin(), itorWalker);
if (itorGpgpuCsrBaseAddress != itorWalker) {
cmdGpgpuCsrBaseAddress = *itorGpgpuCsrBaseAddress;
}
}
} // namespace NEO
using namespace NEO;
using Gen9PreemptionTests = DevicePreemptionTests;
using Gen9PreemptionEnqueueKernelTest = PreemptionEnqueueKernelTest;
using Gen9MidThreadPreemptionEnqueueKernelTest = MidThreadPreemptionEnqueueKernelTest;
using Gen9ThreadGroupPreemptionEnqueueKernelTest = ThreadGroupPreemptionEnqueueKernelTest;
template <>
PreemptionTestHwDetails GetPreemptionTestHwDetails<SKLFamily>() {
PreemptionTestHwDetails ret;
ret.modeToRegValueMap[PreemptionMode::ThreadGroup] = DwordBuilder::build(1, true) | DwordBuilder::build(2, true, false);
ret.modeToRegValueMap[PreemptionMode::MidBatch] = DwordBuilder::build(2, true) | DwordBuilder::build(1, true, false);
ret.modeToRegValueMap[PreemptionMode::MidThread] = DwordBuilder::build(2, true, false) | DwordBuilder::build(1, true, false);
ret.defaultRegValue = ret.modeToRegValueMap[PreemptionMode::MidBatch];
ret.regAddress = 0x2580u;
return ret;
}
GEN9TEST_F(Gen9PreemptionTests, whenMidThreadPreemptionIsNotAvailableThenDoesNotProgramPreamble) {
device->setPreemptionMode(PreemptionMode::ThreadGroup);
size_t requiredSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(device->getDevice());
EXPECT_EQ(0U, requiredSize);
LinearStream cmdStream{nullptr, 0};
PreemptionHelper::programStateSip<FamilyType>(cmdStream, device->getDevice());
EXPECT_EQ(0U, cmdStream.getUsed());
}
GEN9TEST_F(Gen9PreemptionTests, whenMidThreadPreemptionIsAvailableThenStateSipIsProgrammed) {
using STATE_SIP = typename FamilyType::STATE_SIP;
device->setPreemptionMode(PreemptionMode::MidThread);
executionEnvironment->DisableMidThreadPreemption = 0;
size_t minCsrSize = device->getHardwareInfo().gtSystemInfo.CsrSizeInMb * MemoryConstants::megaByte;
uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte;
MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize);
size_t requiredCmdStreamSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(device->getDevice());
size_t expectedPreambleSize = sizeof(STATE_SIP);
EXPECT_EQ(expectedPreambleSize, requiredCmdStreamSize);
StackVec<char, 8192> streamStorage(requiredCmdStreamSize);
ASSERT_LE(requiredCmdStreamSize, streamStorage.size());
LinearStream cmdStream{streamStorage.begin(), streamStorage.size()};
PreemptionHelper::programStateSip<FamilyType>(cmdStream, device->getDevice());
HardwareParse hwParsePreamble;
hwParsePreamble.parseCommands<FamilyType>(cmdStream);
auto stateSipCmd = hwParsePreamble.getCommand<STATE_SIP>();
ASSERT_NE(nullptr, stateSipCmd);
EXPECT_EQ(device->getExecutionEnvironment()->getBuiltIns()->getSipKernel(SipKernelType::Csr, device->getDevice()).getSipAllocation()->getGpuAddressToPatch(), stateSipCmd->getSystemInstructionPointer());
}
GEN9TEST_F(Gen9ThreadGroupPreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogramThreadGroupNoWa) {
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
pDevice->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
csr.getMemoryManager()->setForce32BitAllocations(false);
csr.setMediaVFEStateDirty(false);
auto csrSurface = csr.getPreemptionAllocation();
EXPECT_EQ(nullptr, csrSurface);
size_t off[3] = {0, 0, 0};
size_t gws[3] = {1, 1, 1};
MockKernelWithInternals mockKernel(*pClDevice);
HardwareParse hwParserCsr;
HardwareParse hwParserCmdQ;
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwParserCsr.parseCommands<FamilyType>(csr.commandStream);
hwParserCmdQ.parseCommands<FamilyType>(pCmdQ->getCS(1024));
auto offsetCsr = csr.commandStream.getUsed();
auto offsetCmdQ = pCmdQ->getCS(1024).getUsed();
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
pCmdQ->flush();
hwParserCsr.parseCommands<FamilyType>(csr.commandStream, offsetCsr);
hwParserCmdQ.parseCommands<FamilyType>(pCmdQ->getCS(1024), offsetCmdQ);
EXPECT_EQ(1U, countMmio<FamilyType>(hwParserCsr.cmdList.begin(), hwParserCsr.cmdList.end(), 0x2580u));
EXPECT_EQ(0U, countMmio<FamilyType>(hwParserCsr.cmdList.begin(), hwParserCsr.cmdList.end(), 0x2600u));
EXPECT_EQ(0U, countMmio<FamilyType>(hwParserCmdQ.cmdList.begin(), hwParserCmdQ.cmdList.end(), 0x2580u));
EXPECT_EQ(0U, countMmio<FamilyType>(hwParserCmdQ.cmdList.begin(), hwParserCmdQ.cmdList.end(), 0x2600u));
}
GEN9TEST_F(Gen9ThreadGroupPreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogramThreadGroupWa) {
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
pDevice->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
csr.getMemoryManager()->setForce32BitAllocations(false);
csr.setMediaVFEStateDirty(false);
auto csrSurface = csr.getPreemptionAllocation();
EXPECT_EQ(nullptr, csrSurface);
HardwareParse hwCsrParser;
HardwareParse hwCmdQParser;
size_t off[3] = {0, 0, 0};
size_t gws[3] = {1, 1, 1};
MockKernelWithInternals mockKernel(*pClDevice);
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwCsrParser.parseCommands<FamilyType>(csr.commandStream);
hwCsrParser.findHardwareCommands<FamilyType>();
hwCmdQParser.parseCommands<FamilyType>(pCmdQ->getCS(1024));
hwCmdQParser.findHardwareCommands<FamilyType>();
auto offsetCsr = csr.commandStream.getUsed();
auto offsetCmdQ = pCmdQ->getCS(1024).getUsed();
bool foundOne = false;
for (auto it : hwCsrParser.lriList) {
auto cmd = genCmdCast<typename FamilyType::MI_LOAD_REGISTER_IMM *>(it);
if (cmd->getRegisterOffset() == 0x2580u) {
EXPECT_FALSE(foundOne);
foundOne = true;
}
}
EXPECT_TRUE(foundOne);
hwCsrParser.cmdList.clear();
hwCsrParser.lriList.clear();
int foundWaLri = 0;
int foundWaLriBegin = 0;
int foundWaLriEnd = 0;
for (auto it : hwCmdQParser.lriList) {
auto cmd = genCmdCast<typename FamilyType::MI_LOAD_REGISTER_IMM *>(it);
if (cmd->getRegisterOffset() == 0x2600u) {
foundWaLri++;
if (cmd->getDataDword() == 0xFFFFFFFF) {
foundWaLriBegin++;
}
if (cmd->getDataDword() == 0x0) {
foundWaLriEnd++;
}
}
}
EXPECT_EQ(2, foundWaLri);
EXPECT_EQ(1, foundWaLriBegin);
EXPECT_EQ(1, foundWaLriEnd);
hwCmdQParser.cmdList.clear();
hwCmdQParser.lriList.clear();
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwCsrParser.parseCommands<FamilyType>(csr.commandStream, offsetCsr);
hwCsrParser.findHardwareCommands<FamilyType>();
hwCmdQParser.parseCommands<FamilyType>(pCmdQ->getCS(1024), offsetCmdQ);
hwCmdQParser.findHardwareCommands<FamilyType>();
for (auto it : hwCsrParser.lriList) {
auto cmd = genCmdCast<typename FamilyType::MI_LOAD_REGISTER_IMM *>(it);
EXPECT_FALSE(cmd->getRegisterOffset() == 0x2580u);
}
foundWaLri = 0;
foundWaLriBegin = 0;
foundWaLriEnd = 0;
for (auto it : hwCmdQParser.lriList) {
auto cmd = genCmdCast<typename FamilyType::MI_LOAD_REGISTER_IMM *>(it);
if (cmd->getRegisterOffset() == 0x2600u) {
foundWaLri++;
if (cmd->getDataDword() == 0xFFFFFFFF) {
foundWaLriBegin++;
}
if (cmd->getDataDword() == 0x0) {
foundWaLriEnd++;
}
}
}
EXPECT_EQ(2, foundWaLri);
EXPECT_EQ(1, foundWaLriBegin);
EXPECT_EQ(1, foundWaLriEnd);
}
GEN9TEST_F(Gen9PreemptionEnqueueKernelTest, givenValidKernelForPreemptionWhenEnqueueKernelCalledThenPassDevicePreemptionModeThreadGroup) {
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
auto mockCsr = new MockCsrHw2<FamilyType>(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
pDevice->resetCommandStreamReceiver(mockCsr);
MockKernelWithInternals mockKernel(*pClDevice);
MultiDispatchInfo multiDispatch(mockKernel.mockKernel);
EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(*pDevice, multiDispatch));
size_t gws[3] = {1, 0, 0};
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
pCmdQ->flush();
EXPECT_EQ(1, mockCsr->flushCalledCount);
EXPECT_EQ(PreemptionMode::ThreadGroup, mockCsr->passedDispatchFlags.preemptionMode);
}
GEN9TEST_F(Gen9PreemptionEnqueueKernelTest, givenValidKernelForPreemptionWhenEnqueueKernelCalledAndBlockedThenPassDevicePreemptionModeThreadGroup) {
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
auto mockCsr = new MockCsrHw2<FamilyType>(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
pDevice->resetCommandStreamReceiver(mockCsr);
MockKernelWithInternals mockKernel(*pClDevice);
MultiDispatchInfo multiDispatch(mockKernel.mockKernel);
EXPECT_EQ(PreemptionMode::ThreadGroup, PreemptionHelper::taskPreemptionMode(*pDevice, multiDispatch));
UserEvent userEventObj;
cl_event userEvent = &userEventObj;
size_t gws[3] = {1, 0, 0};
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 1, &userEvent, nullptr);
pCmdQ->flush();
EXPECT_EQ(0, mockCsr->flushCalledCount);
userEventObj.setStatus(CL_COMPLETE);
pCmdQ->flush();
EXPECT_EQ(1, mockCsr->flushCalledCount);
EXPECT_EQ(PreemptionMode::ThreadGroup, mockCsr->passedDispatchFlags.preemptionMode);
}
GEN9TEST_F(Gen9MidThreadPreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogramMidThreadNoWa) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
typedef typename FamilyType::GPGPU_CSR_BASE_ADDRESS GPGPU_CSR_BASE_ADDRESS;
pDevice->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
csr.getMemoryManager()->setForce32BitAllocations(false);
csr.setMediaVFEStateDirty(false);
auto csrSurface = csr.getPreemptionAllocation();
ASSERT_NE(nullptr, csrSurface);
HardwareParse hwCsrParser;
HardwareParse hwCmdQParser;
size_t off[3] = {0, 0, 0};
size_t gws[3] = {1, 1, 1};
MockKernelWithInternals mockKernel(*pClDevice);
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwCsrParser.parseCommands<FamilyType>(csr.commandStream);
hwCsrParser.findHardwareCommands<FamilyType>();
hwCmdQParser.parseCommands<FamilyType>(pCmdQ->getCS(1024));
hwCmdQParser.findHardwareCommands<FamilyType>();
auto offsetCsr = csr.commandStream.getUsed();
auto offsetCmdQ = pCmdQ->getCS(1024).getUsed();
bool foundOneLri = false;
for (auto it : hwCsrParser.lriList) {
auto cmdLri = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
if (cmdLri->getRegisterOffset() == 0x2580u) {
EXPECT_FALSE(foundOneLri);
foundOneLri = true;
}
}
EXPECT_TRUE(foundOneLri);
bool foundWaLri = false;
for (auto it : hwCmdQParser.lriList) {
auto cmdLri = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
if (cmdLri->getRegisterOffset() == 0x2600u) {
foundWaLri = true;
}
}
EXPECT_FALSE(foundWaLri);
hwCsrParser.findCsrBaseAddress<FamilyType>();
ASSERT_NE(nullptr, hwCsrParser.cmdGpgpuCsrBaseAddress);
auto cmdCsr = genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(hwCsrParser.cmdGpgpuCsrBaseAddress);
ASSERT_NE(nullptr, cmdCsr);
EXPECT_EQ(csrSurface->getGpuAddressToPatch(), cmdCsr->getGpgpuCsrBaseAddress());
hwCsrParser.cmdList.clear();
hwCsrParser.lriList.clear();
hwCsrParser.cmdGpgpuCsrBaseAddress = nullptr;
hwCmdQParser.cmdList.clear();
hwCmdQParser.lriList.clear();
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwCsrParser.parseCommands<FamilyType>(csr.commandStream, offsetCsr);
hwCsrParser.findHardwareCommands<FamilyType>();
hwCmdQParser.parseCommands<FamilyType>(csr.commandStream, offsetCmdQ);
hwCmdQParser.findHardwareCommands<FamilyType>();
for (auto it : hwCsrParser.lriList) {
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
EXPECT_FALSE(cmd->getRegisterOffset() == 0x2580u);
}
hwCsrParser.findCsrBaseAddress<FamilyType>();
EXPECT_EQ(nullptr, hwCsrParser.cmdGpgpuCsrBaseAddress);
for (auto it : hwCmdQParser.lriList) {
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
EXPECT_FALSE(cmd->getRegisterOffset() == 0x2600u);
}
}
GEN9TEST_F(Gen9MidThreadPreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogramMidThreadWa) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
typedef typename FamilyType::GPGPU_CSR_BASE_ADDRESS GPGPU_CSR_BASE_ADDRESS;
pDevice->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
csr.getMemoryManager()->setForce32BitAllocations(false);
csr.setMediaVFEStateDirty(false);
auto csrSurface = csr.getPreemptionAllocation();
ASSERT_NE(nullptr, csrSurface);
HardwareParse hwCsrParser;
HardwareParse hwCmdQParser;
size_t off[3] = {0, 0, 0};
size_t gws[3] = {1, 1, 1};
MockKernelWithInternals mockKernel(*pClDevice);
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwCsrParser.parseCommands<FamilyType>(csr.commandStream);
hwCsrParser.findHardwareCommands<FamilyType>();
hwCmdQParser.parseCommands<FamilyType>(pCmdQ->getCS(1024));
hwCmdQParser.findHardwareCommands<FamilyType>();
auto offsetCsr = csr.commandStream.getUsed();
auto offsetCmdQ = pCmdQ->getCS(1024).getUsed();
bool foundOneLri = false;
for (auto it : hwCsrParser.lriList) {
auto cmdLri = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
if (cmdLri->getRegisterOffset() == 0x2580u) {
EXPECT_FALSE(foundOneLri);
foundOneLri = true;
}
}
EXPECT_TRUE(foundOneLri);
int foundWaLri = 0;
int foundWaLriBegin = 0;
int foundWaLriEnd = 0;
for (auto it : hwCmdQParser.lriList) {
auto cmdLri = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
if (cmdLri->getRegisterOffset() == 0x2600u) {
foundWaLri++;
if (cmdLri->getDataDword() == 0xFFFFFFFF) {
foundWaLriBegin++;
}
if (cmdLri->getDataDword() == 0x0) {
foundWaLriEnd++;
}
}
}
EXPECT_EQ(2, foundWaLri);
EXPECT_EQ(1, foundWaLriBegin);
EXPECT_EQ(1, foundWaLriEnd);
hwCsrParser.findCsrBaseAddress<FamilyType>();
ASSERT_NE(nullptr, hwCsrParser.cmdGpgpuCsrBaseAddress);
auto cmdCsr = genCmdCast<GPGPU_CSR_BASE_ADDRESS *>(hwCsrParser.cmdGpgpuCsrBaseAddress);
ASSERT_NE(nullptr, cmdCsr);
EXPECT_EQ(csrSurface->getGpuAddressToPatch(), cmdCsr->getGpgpuCsrBaseAddress());
hwCsrParser.cmdList.clear();
hwCsrParser.lriList.clear();
hwCsrParser.cmdGpgpuCsrBaseAddress = nullptr;
hwCmdQParser.cmdList.clear();
hwCmdQParser.lriList.clear();
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr);
hwCsrParser.parseCommands<FamilyType>(csr.commandStream, offsetCsr);
hwCsrParser.findHardwareCommands<FamilyType>();
hwCmdQParser.parseCommands<FamilyType>(pCmdQ->getCS(1024), offsetCmdQ);
hwCmdQParser.findHardwareCommands<FamilyType>();
for (auto it : hwCsrParser.lriList) {
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
EXPECT_FALSE(cmd->getRegisterOffset() == 0x2580u);
}
hwCsrParser.findCsrBaseAddress<FamilyType>();
EXPECT_EQ(nullptr, hwCsrParser.cmdGpgpuCsrBaseAddress);
foundWaLri = 0;
foundWaLriBegin = 0;
foundWaLriEnd = 0;
for (auto it : hwCmdQParser.lriList) {
auto cmd = genCmdCast<MI_LOAD_REGISTER_IMM *>(it);
if (cmd->getRegisterOffset() == 0x2600u) {
foundWaLri++;
if (cmd->getDataDword() == 0xFFFFFFFF) {
foundWaLriBegin++;
}
if (cmd->getDataDword() == 0x0) {
foundWaLriEnd++;
}
}
}
EXPECT_EQ(2, foundWaLri);
EXPECT_EQ(1, foundWaLriBegin);
EXPECT_EQ(1, foundWaLriEnd);
}
GEN9TEST_F(Gen9PreemptionEnqueueKernelTest, givenDisabledPreemptionWhenEnqueueKernelCalledThenPassDisabledPreemptionMode) {
pDevice->setPreemptionMode(PreemptionMode::Disabled);
auto mockCsr = new MockCsrHw2<FamilyType>(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex());
pDevice->resetCommandStreamReceiver(mockCsr);
MockKernelWithInternals mockKernel(*pClDevice);
MultiDispatchInfo multiDispatch(mockKernel.mockKernel);
EXPECT_EQ(PreemptionMode::Disabled, PreemptionHelper::taskPreemptionMode(*pDevice, multiDispatch));
size_t gws[3] = {1, 0, 0};
pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
pCmdQ->flush();
EXPECT_EQ(1, mockCsr->flushCalledCount);
EXPECT_EQ(PreemptionMode::Disabled, mockCsr->passedDispatchFlags.preemptionMode);
}
GEN9TEST_F(Gen9PreemptionTests, getPreemptionWaCsSizeMidBatch) {
size_t expectedSize = 0;
device->setPreemptionMode(PreemptionMode::MidBatch);
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN9TEST_F(Gen9PreemptionTests, getPreemptionWaCsSizeThreadGroupNoWa) {
size_t expectedSize = 0;
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN9TEST_F(Gen9PreemptionTests, getPreemptionWaCsSizeThreadGroupWa) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
size_t expectedSize = 2 * sizeof(MI_LOAD_REGISTER_IMM);
device->setPreemptionMode(PreemptionMode::ThreadGroup);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN9TEST_F(Gen9PreemptionTests, getPreemptionWaCsSizeMidThreadNoWa) {
size_t expectedSize = 0;
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = false;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN9TEST_F(Gen9PreemptionTests, getPreemptionWaCsSizeMidThreadWa) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
size_t expectedSize = 2 * sizeof(MI_LOAD_REGISTER_IMM);
device->setPreemptionMode(PreemptionMode::MidThread);
device->getExecutionEnvironment()->getMutableHardwareInfo()->workaroundTable.waModifyVFEStateAfterGPGPUPreemption = true;
size_t size = PreemptionHelper::getPreemptionWaCsSize<FamilyType>(device->getDevice());
EXPECT_EQ(expectedSize, size);
}
GEN9TEST_F(Gen9PreemptionTests, givenInterfaceDescriptorDataWhenAnyPreemptionModeThenNoChange) {
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
INTERFACE_DESCRIPTOR_DATA idd;
INTERFACE_DESCRIPTOR_DATA iddArg;
int ret;
idd = FamilyType::cmdInitInterfaceDescriptorData;
iddArg = FamilyType::cmdInitInterfaceDescriptorData;
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::Disabled);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidBatch);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::ThreadGroup);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
PreemptionHelper::programInterfaceDescriptorDataPreemption<FamilyType>(&iddArg, PreemptionMode::MidThread);
ret = memcmp(&idd, &iddArg, sizeof(INTERFACE_DESCRIPTOR_DATA));
EXPECT_EQ(0, ret);
}
GEN9TEST_F(Gen9PreemptionTests, givenMidThreadPreemptionModeWhenStateSipIsProgrammedThenSipEqualsSipAllocationGpuAddressToPatch) {
using STATE_SIP = typename FamilyType::STATE_SIP;
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
auto cmdSizePreemptionMidThread = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(*mockDevice);
StackVec<char, 4096> preemptionBuffer;
preemptionBuffer.resize(cmdSizePreemptionMidThread);
LinearStream preemptionStream(&*preemptionBuffer.begin(), preemptionBuffer.size());
PreemptionHelper::programStateSip<FamilyType>(preemptionStream, *mockDevice);
HardwareParse hwParserOnlyPreemption;
hwParserOnlyPreemption.parseCommands<FamilyType>(preemptionStream, 0);
auto cmd = hwParserOnlyPreemption.getCommand<STATE_SIP>();
EXPECT_NE(nullptr, cmd);
auto sipType = SipKernel::getSipKernelType(mockDevice->getHardwareInfo().platform.eRenderCoreFamily, mockDevice->isDebuggerActive());
EXPECT_EQ(mockDevice->getExecutionEnvironment()->getBuiltIns()->getSipKernel(sipType, *mockDevice).getSipAllocation()->getGpuAddressToPatch(), cmd->getSystemInstructionPointer());
}

View File

@@ -1,26 +0,0 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_HELPERS_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debug_manager_state_restore.h
${CMAKE_CURRENT_SOURCE_DIR}/default_hw_info.h
${CMAKE_CURRENT_SOURCE_DIR}/default_hw_info.inl
${CMAKE_CURRENT_SOURCE_DIR}/file_io_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hash_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/kernel_helpers_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/memory_leak_listener.h
${CMAKE_CURRENT_SOURCE_DIR}/memory_management.h
${CMAKE_CURRENT_SOURCE_DIR}/simd_helper_tests.inl
${CMAKE_CURRENT_SOURCE_DIR}/string_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string_to_hash_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ult_hw_config.h
${CMAKE_CURRENT_SOURCE_DIR}/ult_hw_config.inl
${CMAKE_CURRENT_SOURCE_DIR}/ult_hw_helper.h
)
set_property(GLOBAL PROPERTY NEO_CORE_HELPERS_TESTS ${NEO_CORE_HELPERS_TESTS})
add_subdirectories()

View File

@@ -1,281 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/aligned_memory.h"
#include "gtest/gtest.h"
#include <cstdint>
TEST(AlignedFree, nullptrShouldntCrash) {
alignedFree(nullptr);
}
void *ptrAlignedToPage = (void *)0x1000;
void *ptrNotAlignedToPage = (void *)0x1001;
struct AlignedMalloc : public ::testing::TestWithParam<size_t> {
public:
void SetUp() override {
ptr = nullptr;
alignAlloc = GetParam();
}
void TearDown() override {
alignedFree(ptr);
}
void *ptr;
size_t alignAlloc;
};
TEST_P(AlignedMalloc, size0) {
size_t sizeAlloc = 0;
ptr = alignedMalloc(sizeAlloc, alignAlloc);
EXPECT_NE(nullptr, ptr);
EXPECT_EQ(0u, (uintptr_t)ptr % alignAlloc);
}
TEST_P(AlignedMalloc, size4096) {
size_t sizeAlloc = 4096;
ptr = alignedMalloc(sizeAlloc, alignAlloc);
EXPECT_NE(nullptr, ptr);
EXPECT_EQ(0u, (uintptr_t)ptr % alignAlloc);
}
TEST(AlignedMallocTests, size0align4096) {
size_t sizeAlloc = 0;
auto ptr = alignedMalloc(sizeAlloc, 4096);
EXPECT_NE(nullptr, ptr);
EXPECT_EQ(0u, (uintptr_t)ptr % 4096);
alignedFree(ptr);
}
INSTANTIATE_TEST_CASE_P(
AlignedMallocParameterized,
AlignedMalloc,
testing::Values(
1,
4,
8,
64,
4096));
struct AlignUp : public ::testing::TestWithParam<size_t> {
};
TEST_P(AlignUp, belowAlignmentBefore) {
uintptr_t addrBefore = 0x1fffffff;
auto ptrBefore = (uint32_t *)addrBefore;
auto alignment = GetParam();
auto ptrAfter = alignUp(ptrBefore, alignment);
auto addrAfter = (uintptr_t)ptrAfter;
EXPECT_EQ(0u, addrAfter % alignment);
}
TEST_P(AlignUp, AtAlignmentBefore) {
uintptr_t addrBefore = 0x20000000;
auto ptrBefore = (uint32_t *)addrBefore;
auto alignment = GetParam();
auto ptrAfter = alignUp(ptrBefore, alignment);
auto addrAfter = (uintptr_t)ptrAfter;
EXPECT_EQ(0u, addrAfter % alignment);
}
TEST_P(AlignUp, AboveAlignmentBefore) {
uintptr_t addrBefore = 0x20000001;
auto ptrBefore = (uint32_t *)addrBefore;
auto alignment = GetParam();
auto ptrAfter = alignUp(ptrBefore, alignment);
auto addrAfter = (uintptr_t)ptrAfter;
EXPECT_EQ(0u, addrAfter % alignment);
}
TEST_P(AlignUp, preserve64Bit) {
uint64_t aligned = 1ULL << 48;
auto alignment = GetParam();
auto result = alignUp(aligned, alignment);
EXPECT_EQ(aligned, result);
}
INSTANTIATE_TEST_CASE_P(
AlignUpParameterized,
AlignUp,
testing::Values(
1,
4,
8,
32,
64,
256,
4096));
TEST(AlignWholeSize, alignWholeSizeToPage) {
int size = 1;
auto retSize = alignSizeWholePage(ptrAlignedToPage, size);
EXPECT_EQ(retSize, 4096u);
}
TEST(AlignWholeSize, sizeGreaterThenPageResultsIn2Pages) {
int size = 4097;
auto retSize = alignSizeWholePage(ptrAlignedToPage, size);
EXPECT_EQ(retSize, 4096u * 2);
}
TEST(AlignWholeSize, allocationNotPageAligned) {
int size = 4097;
auto retSize = alignSizeWholePage(ptrNotAlignedToPage, size);
EXPECT_EQ(retSize, 4096u * 2);
}
TEST(AlignWholeSize, ptrNotAligned) {
int size = 1;
auto retSize = alignSizeWholePage(ptrNotAlignedToPage, size);
EXPECT_EQ(retSize, 4096u);
}
TEST(AlignWholeSize, allocationFitsToOnePage) {
int size = 4095;
auto retSize = alignSizeWholePage(ptrNotAlignedToPage, size);
EXPECT_EQ(retSize, 4096u);
}
TEST(AlignWholeSize, allocationFitsTo2Pages) {
int size = 4095 + 4096;
auto retSize = alignSizeWholePage(ptrNotAlignedToPage, size);
EXPECT_EQ(retSize, 4096u * 2);
}
TEST(AlignWholeSize, allocationOverlapsToAnotherPage) {
int size = 4096;
auto retSize = alignSizeWholePage(ptrNotAlignedToPage, size);
EXPECT_EQ(retSize, 4096u * 2);
}
TEST(AlignWholeSize, allocationOverlapsTo2AnotherPage) {
int size = 4096 * 2;
auto retSize = alignSizeWholePage(ptrNotAlignedToPage, size);
EXPECT_EQ(retSize, 4096u * 3);
}
TEST(AlignWholeSize, ptrProperlyAlignedTo2Pages) {
int size = 4096 * 2;
auto retSize = alignSizeWholePage(ptrAlignedToPage, size);
EXPECT_EQ(retSize, 4096u * 2);
}
TEST(AlignDown, ptrAlignedToPageWhenAlignedDownReturnsTheSamePointer) {
void *ptr = (void *)0x1000;
auto alignedDownPtr = alignDown(ptr, MemoryConstants::pageSize);
EXPECT_EQ(ptr, alignedDownPtr);
}
TEST(AlignDown, ptrNotAlignedToPageWhenAlignedDownReturnsPageAlignedPointer) {
void *ptr = (void *)0x1001;
void *expected_ptr = (void *)0x1000;
auto alignedDownPtr = alignDown(ptr, MemoryConstants::pageSize);
EXPECT_EQ(expected_ptr, alignedDownPtr);
}
TEST(AlignDown, ptrNotAlignedToPage2WhenAlignedDownReturnsPageAlignedPointer) {
void *ptr = (void *)0x1241;
void *expected_ptr = (void *)0x1000;
auto alignedDownPtr = alignDown(ptr, MemoryConstants::pageSize);
EXPECT_EQ(expected_ptr, alignedDownPtr);
}
TEST(AlignDown, ptrNotAlignedToPage3WhenAlignedDownReturnsPageAlignedPointer) {
void *ptr = (void *)0x3241;
void *expected_ptr = (void *)0x3000;
auto alignedDownPtr = alignDown(ptr, MemoryConstants::pageSize);
EXPECT_EQ(expected_ptr, alignedDownPtr);
}
TEST(AlignDown, ptrNotAlignedToDwordWhenAlignedDownReturnsDwordAlignedPointer) {
void *ptr = (void *)0x3241;
void *expected_ptr = (void *)0x3240;
auto alignedDownPtr = alignDown(ptr, 4);
EXPECT_EQ(expected_ptr, alignedDownPtr);
}
TEST(AlignDown, preserve64Bit) {
uint64_t aligned = 1ULL << 48;
auto result = alignDown(aligned, MemoryConstants::pageSize);
EXPECT_EQ(aligned, result);
}
TEST(DLLbitness, Given32or64BitLibraryWhenAskedIfItIs32BitThenProperValueIsReturned) {
auto pointerSize = sizeof(void *);
if (pointerSize == 8) {
EXPECT_FALSE(is32bit);
EXPECT_TRUE(is64bit);
} else if (pointerSize == 4) {
EXPECT_TRUE(is32bit);
EXPECT_FALSE(is64bit);
} else {
FAIL() << "unrecognized bitness";
}
auto pointerSizeFromSizeT = sizeof(size_t);
if (pointerSizeFromSizeT == 8) {
EXPECT_FALSE(is32bit);
EXPECT_TRUE(is64bit);
} else if (pointerSizeFromSizeT == 4) {
EXPECT_TRUE(is32bit);
EXPECT_FALSE(is64bit);
} else {
FAIL() << "unrecognized bitness";
}
}
template <typename T>
class IsAlignedTests : public ::testing::Test {
};
typedef ::testing::Types<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, float, double> IsAlignedTypes;
TYPED_TEST_CASE(IsAlignedTests, IsAlignedTypes);
TYPED_TEST(IsAlignedTests, aligned) {
TypeParam *ptr = reinterpret_cast<TypeParam *>(static_cast<uintptr_t>(0xdeadbeefu));
// one byte alignment should always return true
if (alignof(TypeParam) == 1)
EXPECT_TRUE(isAligned(ptr));
else
EXPECT_FALSE(isAligned(ptr));
auto ptr1 = reinterpret_cast<TypeParam *>(reinterpret_cast<uintptr_t>(ptr) & ~(alignof(TypeParam) - 1));
EXPECT_TRUE(isAligned(ptr1));
auto ptr2 = reinterpret_cast<TypeParam *>(reinterpret_cast<uintptr_t>(ptr) & ~((alignof(TypeParam) << 1) - 1));
EXPECT_TRUE(isAligned(ptr2));
// this is hard to align in the middle of byte aligned types
if (alignof(TypeParam) == 1)
return;
auto ptr3 = reinterpret_cast<TypeParam *>(reinterpret_cast<uintptr_t>(ptr) & ~((alignof(TypeParam) >> 1) - 1));
EXPECT_FALSE(isAligned(ptr3));
}
TEST(IsAligned, nonPointerType) {
EXPECT_TRUE(isAligned<3>(0));
EXPECT_FALSE(isAligned<3>(1));
EXPECT_FALSE(isAligned<3>(2));
EXPECT_TRUE(isAligned<3>(3));
EXPECT_FALSE(isAligned<3>(4));
EXPECT_FALSE(isAligned<3>(5));
EXPECT_TRUE(isAligned<3>(6));
}
TEST(IsAligned, supportsConstexprEvaluation) {
static_assert(false == isAligned<3>(2), "");
static_assert(true == isAligned<3>(3), "");
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/utilities/debug_settings_reader.h"
using namespace NEO;
class DebugManagerStateRestore {
public:
DebugManagerStateRestore() {
debugVarSnapshot = DebugManager.flags;
injectFcnSnapshot = DebugManager.injectFcn;
}
~DebugManagerStateRestore() {
DebugManager.flags = debugVarSnapshot;
DebugManager.injectFcn = injectFcnSnapshot;
#undef DECLARE_DEBUG_VARIABLE
#define DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description) shrink(DebugManager.flags.variableName.getRef());
#include "debug_variables.inl"
#undef DECLARE_DEBUG_VARIABLE
}
DebugVariables debugVarSnapshot;
void *injectFcnSnapshot = nullptr;
protected:
void shrink(std::string &flag) {
flag.shrink_to_fit();
}
void shrink(int32_t &flag) {}
void shrink(bool &flag) {}
};
class RegistryReaderMock : public SettingsReader {
public:
RegistryReaderMock() {}
~RegistryReaderMock() override {}
unsigned int forceRetValue = 1;
int32_t getSetting(const char *settingName, int32_t defaultValue) override {
return static_cast<int32_t>(forceRetValue);
}
bool getSetting(const char *settingName, bool defaultValue) override {
return true;
}
std::string getSetting(const char *settingName, const std::string &value) override {
return "";
}
const char *appSpecificLocation(const std::string &name) override {
return name.c_str();
}
};

View File

@@ -1,15 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <cstddef>
namespace NEO {
struct HardwareInfo;
extern const HardwareInfo **platformDevices;
} // namespace NEO

View File

@@ -1,17 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/array_count.h"
#include "shared/source/helpers/hw_cmds.h"
namespace NEO {
static const HardwareInfo *DefaultPlatformDevices[] = {
&DEFAULT_TEST_PLATFORM::hwInfo,
};
const HardwareInfo **platformDevices = DefaultPlatformDevices;
} // namespace NEO

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/file_io.h"
#include "shared/source/helpers/stdio.h"
#include "gtest/gtest.h"
#include <cstdio>
TEST(FileIO, existsHasSize) {
std::string fileName("fileIO.bin");
std::remove(fileName.c_str());
ASSERT_FALSE(fileExists(fileName.c_str()));
FILE *fp = nullptr;
fopen_s(&fp, fileName.c_str(), "wb");
ASSERT_NE(nullptr, fp);
fprintf(fp, "TEST");
fclose(fp);
EXPECT_TRUE(fileExists(fileName.c_str()));
EXPECT_TRUE(fileExistsHasSize(fileName.c_str()));
}
TEST(FileIO, existsSizeZero) {
std::string fileName("fileIO.bin");
std::remove(fileName.c_str());
ASSERT_FALSE(fileExists(fileName.c_str()));
FILE *fp = nullptr;
fopen_s(&fp, fileName.c_str(), "wb");
ASSERT_NE(nullptr, fp);
fclose(fp);
EXPECT_TRUE(fileExists(fileName.c_str()));
EXPECT_FALSE(fileExistsHasSize(fileName.c_str()));
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/hash.h"
#include "gtest/gtest.h"
using namespace NEO;
TEST(HashTests, givenSamePointersWhenHashIsCalculatedThenSame32BitValuesAreGenerated) {
uintptr_t ptr1UI = 1;
uintptr_t ptr2UI = 1;
void *ptr1 = reinterpret_cast<void *>(ptr1UI);
void *ptr2 = reinterpret_cast<void *>(ptr2UI);
uint32_t hash1 = hashPtrToU32(ptr1);
uint32_t hash2 = hashPtrToU32(ptr2);
EXPECT_EQ(hash1, hash2);
}
TEST(HashTests, givenDifferentPointersWhenHashIsCalculatedThenUnique32BitValuesAreGenerated) {
uintptr_t ptr1UI = 1;
uintptr_t ptr2UI = ptr1UI | (ptr1UI << ((sizeof(uintptr_t) / 2) * 8));
void *ptr1 = reinterpret_cast<void *>(ptr1UI);
void *ptr2 = reinterpret_cast<void *>(ptr2UI);
uint32_t hash1 = hashPtrToU32(ptr1);
uint32_t hash2 = hashPtrToU32(ptr2);
EXPECT_NE(hash1, hash2);
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/kernel_helpers.h"
#include "test.h"
using namespace NEO;
struct KernelHelperMaxWorkGroupsTests : ::testing::Test {
uint32_t simd = 8;
uint32_t threadCount = 8 * 1024;
uint32_t dssCount = 16;
uint32_t availableSlm = 64 * KB;
uint32_t usedSlm = 0;
uint32_t maxBarrierCount = 32;
uint32_t numberOfBarriers = 0;
uint32_t workDim = 3;
size_t lws[3] = {10, 10, 10};
uint32_t getMaxWorkGroupCount() {
return KernelHelper::getMaxWorkGroupCount(simd, threadCount, dssCount, availableSlm, usedSlm,
maxBarrierCount, numberOfBarriers, workDim, lws);
}
};
TEST_F(KernelHelperMaxWorkGroupsTests, GivenNoBarriersOrSlmUsedWhenCalculatingMaxWorkGroupsCountThenResultIsCalculatedWithSimd) {
auto workGroupSize = lws[0] * lws[1] * lws[2];
auto expected = threadCount / Math::divideAndRoundUp(workGroupSize, simd);
EXPECT_EQ(expected, getMaxWorkGroupCount());
}
TEST_F(KernelHelperMaxWorkGroupsTests, GivenBarriersWhenCalculatingMaxWorkGroupsCountThenResultIsCalculatedWithRegardToBarriersCount) {
numberOfBarriers = 16;
auto expected = dssCount * (maxBarrierCount / numberOfBarriers);
EXPECT_EQ(expected, getMaxWorkGroupCount());
}
TEST_F(KernelHelperMaxWorkGroupsTests, GivenUsedSlmSizeWhenCalculatingMaxWorkGroupsCountThenResultIsCalculatedWithRegardToUsedSlmSize) {
usedSlm = 4 * KB;
auto expected = availableSlm / usedSlm;
EXPECT_EQ(expected, getMaxWorkGroupCount());
}
TEST_F(KernelHelperMaxWorkGroupsTests, GivenVariousValuesWhenCalculatingMaxWorkGroupsCountThenLowestResultIsAlwaysReturned) {
usedSlm = 1 * KB;
numberOfBarriers = 1;
dssCount = 1;
workDim = 1;
lws[0] = simd;
threadCount = 1;
EXPECT_EQ(1u, getMaxWorkGroupCount());
threadCount = 1024;
EXPECT_NE(1u, getMaxWorkGroupCount());
numberOfBarriers = 32;
EXPECT_EQ(1u, getMaxWorkGroupCount());
numberOfBarriers = 1;
EXPECT_NE(1u, getMaxWorkGroupCount());
usedSlm = availableSlm;
EXPECT_EQ(1u, getMaxWorkGroupCount());
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "memory_leak_listener.h"
#include "helpers/memory_management.h"
using ::testing::TestInfo;
using namespace NEO;
void MemoryLeakListener::OnTestStart(const TestInfo &testInfo) {
MemoryManagement::logTraces = MemoryManagement::captureCallStacks;
if (MemoryManagement::captureCallStacks) {
MemoryManagement::detailedAllocationLoggingActive = true;
}
MemoryManagement::fastLeakDetectionEnabled = true;
}
void MemoryLeakListener::OnTestEnd(const TestInfo &testInfo) {
MemoryManagement::fastLeakDetectionEnabled = false;
if (testInfo.result()->Passed()) {
if (MemoryManagement::fastLeaksDetectionMode != MemoryManagement::LeakDetectionMode::STANDARD) {
if (MemoryManagement::fastLeaksDetectionMode == MemoryManagement::LeakDetectionMode::EXPECT_TO_LEAK) {
EXPECT_GT(MemoryManagement::fastEventsAllocatedCount, MemoryManagement::fastEventsDeallocatedCount);
}
MemoryManagement::fastLeaksDetectionMode = MemoryManagement::LeakDetectionMode::STANDARD;
} else if (MemoryManagement::captureCallStacks && (MemoryManagement::fastEventsAllocatedCount != MemoryManagement::fastEventsDeallocatedCount)) {
auto leak = MemoryManagement::enumerateLeak(MemoryManagement::indexAllocation.load(), MemoryManagement::indexDeallocation.load(), true, true);
if (leak != MemoryManagement::failingAllocation) {
printf("\n %s ", printCallStack(MemoryManagement::eventsAllocated[leak]).c_str());
}
EXPECT_EQ(MemoryManagement::indexAllocation.load(), MemoryManagement::indexDeallocation.load());
} else if (MemoryManagement::fastEventsAllocatedCount != MemoryManagement::fastEventsDeallocatedCount) {
auto leak = MemoryManagement::detectLeaks();
EXPECT_EQ(leak, (int)MemoryManagement::failingAllocation) << "To locate call stack, change the value of captureCallStacks to true";
}
}
MemoryManagement::fastEventsAllocatedCount = 0;
MemoryManagement::fastEventsDeallocatedCount = 0;
}

View File

@@ -1,18 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "gtest/gtest.h"
namespace NEO {
class MemoryLeakListener : public ::testing::EmptyTestEventListener {
protected:
void OnTestStart(const ::testing::TestInfo &) override;
void OnTestEnd(const ::testing::TestInfo &) override;
};
} // namespace NEO

View File

@@ -1,404 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/memory_management.h"
#include "gtest/gtest.h"
#include <atomic>
#include <cassert>
#include <cinttypes>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <iostream>
#include <new>
#if defined(__linux__)
#include <cstdio>
#include <dlfcn.h>
#include <execinfo.h>
#elif defined(_WIN32)
#include <Windows.h>
#include <DbgHelp.h>
#endif
namespace MemoryManagement {
size_t failingAllocation = -1;
std::atomic<size_t> numAllocations(0);
std::atomic<size_t> indexAllocation(0);
std::atomic<size_t> indexDeallocation(0);
bool logTraces = false;
bool fastLeakDetectionEnabled = false;
AllocationEvent eventsAllocated[maxEvents];
AllocationEvent eventsDeallocated[maxEvents];
void *fastEventsAllocated[maxEvents];
void *fastEventsDeallocated[maxEvents];
std::atomic<int> fastEventsAllocatedCount(0);
std::atomic<int> fastEventsDeallocatedCount(0);
std::atomic<int> fastLeaksDetectionMode(LeakDetectionMode::STANDARD);
size_t breakOnAllocationEvent = -1;
size_t breakOnDeallocationEvent = -1;
bool detailedAllocationLoggingActive = false;
// limit size of single allocation in ULT
const size_t maxAllowedAllocationSize = 128 * 1024 * 1024 + 4096;
static void onAllocationEvent() {
/*
//switch to true to turn on dillignet breakpoint setting place
bool setBreakPointHereForLeaks = false;
if (setBreakPointHereForLeaks) {
if (breakOnAllocationEvent == indexAllocation.load()) {
//set breakpoint on line below
setBreakPointHereForLeaks = false;
}
}*/
}
static void onDeallocationEvent(void *) {
/*
//switch to true to turn on dillignet breakpoint setting place
bool setBreakPointHereForLeaks = false;
if (setBreakPointHereForLeaks) {
if (breakOnDeallocationEvent == indexDeallocation.load()) {
//set breakpoint on line below
setBreakPointHereForLeaks = false;
}
}*/
}
void (*deleteCallback)(void *) = onDeallocationEvent;
template <AllocationEvent::EventType typeValid, AllocationEvent::EventType typeFail>
static void *allocate(size_t size) {
onAllocationEvent();
if (size > maxAllowedAllocationSize) {
return nullptr;
}
if (!fastLeakDetectionEnabled) {
return malloc(size);
}
void *p;
if (detailedAllocationLoggingActive) {
auto indexAllocation = MemoryManagement::indexAllocation.fetch_add(1);
indexAllocation %= maxEvents;
auto &eventAllocation = eventsAllocated[indexAllocation];
eventAllocation.size = size;
while ((p = malloc(size)) == nullptr) {
eventAllocation.address = p;
eventAllocation.event = typeFail;
throw std::bad_alloc();
}
eventAllocation.address = p;
eventAllocation.event = typeValid;
#if defined(__linux__)
eventAllocation.frames = logTraces ? backtrace(eventAllocation.callstack, AllocationEvent::CallStackSize) : 0;
#elif defined(_WIN32)
eventAllocation.frames = logTraces ? CaptureStackBackTrace(0, AllocationEvent::CallStackSize, eventAllocation.callstack, NULL) : 0;
#else
eventAllocation.frames = 0;
#endif
eventAllocation.fastLeakDetectionEnabled = fastLeakDetectionEnabled;
numAllocations++;
} else {
p = malloc(size);
}
if (fastLeakDetectionEnabled && p && fastLeaksDetectionMode == LeakDetectionMode::STANDARD) {
auto currentIndex = fastEventsAllocatedCount++;
fastEventsAllocated[currentIndex] = p;
assert(currentIndex <= fastEvents);
}
return p;
}
template <AllocationEvent::EventType typeValid, AllocationEvent::EventType typeFail>
static void *allocate(size_t size, const std::nothrow_t &) {
onAllocationEvent();
if (size > maxAllowedAllocationSize) {
return nullptr;
}
if (!fastLeakDetectionEnabled) {
return malloc(size);
}
void *p;
if (detailedAllocationLoggingActive) {
auto indexAllocation = MemoryManagement::indexAllocation.fetch_add(1);
indexAllocation %= maxEvents;
p = indexAllocation == failingAllocation
? nullptr
: malloc(size);
auto &eventAllocation = eventsAllocated[indexAllocation];
eventAllocation.event = p
? typeValid
: typeFail;
eventAllocation.address = p;
eventAllocation.size = size;
#if defined(__linux__)
eventAllocation.frames = logTraces ? backtrace(eventAllocation.callstack, AllocationEvent::CallStackSize) : 0;
#elif defined(_WIN32)
eventAllocation.frames = logTraces ? CaptureStackBackTrace(0, AllocationEvent::CallStackSize, eventAllocation.callstack, NULL) : 0;
#else
eventAllocation.frames = 0;
#endif
eventAllocation.fastLeakDetectionEnabled = fastLeakDetectionEnabled;
numAllocations += p ? 1 : 0;
} else {
p = malloc(size);
}
if (fastLeakDetectionEnabled && p && fastLeaksDetectionMode == LeakDetectionMode::STANDARD) {
auto currentIndex = fastEventsAllocatedCount++;
fastEventsAllocated[currentIndex] = p;
assert(currentIndex <= fastEvents);
}
return p;
}
template <AllocationEvent::EventType typeValid>
static void deallocate(void *p) {
deleteCallback(p);
if (!fastLeakDetectionEnabled) {
if (p) {
free(p);
}
return;
}
if (p) {
if (detailedAllocationLoggingActive) {
auto indexDeallocation = MemoryManagement::indexDeallocation.fetch_add(1);
indexDeallocation %= maxEvents;
--numAllocations;
auto &eventDeallocation = eventsDeallocated[indexDeallocation];
eventDeallocation.event = typeValid;
eventDeallocation.address = p;
eventDeallocation.size = -1;
#if defined(__linux__)
eventDeallocation.frames = logTraces ? backtrace(eventDeallocation.callstack, AllocationEvent::CallStackSize) : 0;
#elif defined(_WIN32)
eventDeallocation.frames = logTraces ? CaptureStackBackTrace(0, AllocationEvent::CallStackSize, eventDeallocation.callstack, NULL) : 0;
#else
eventDeallocation.frames = 0;
#endif
eventDeallocation.fastLeakDetectionEnabled = fastLeakDetectionEnabled;
}
free(p);
if (fastLeakDetectionEnabled && p && fastLeaksDetectionMode == LeakDetectionMode::STANDARD) {
auto currentIndex = fastEventsDeallocatedCount++;
fastEventsDeallocated[currentIndex] = p;
assert(currentIndex <= fastEvents);
}
}
}
int detectLeaks() {
int indexLeak = -1;
for (int allocationIndex = 0u; allocationIndex < fastEventsAllocatedCount; allocationIndex++) {
auto &eventAllocation = fastEventsAllocated[allocationIndex];
int deallocationIndex = 0u;
for (; deallocationIndex < fastEventsDeallocatedCount; deallocationIndex++) {
if (fastEventsDeallocated[deallocationIndex] == nullptr) {
continue;
}
if (fastEventsDeallocated[deallocationIndex] == eventAllocation) {
fastEventsDeallocated[deallocationIndex] = nullptr;
break;
}
}
if (deallocationIndex == fastEventsDeallocatedCount) {
indexLeak = allocationIndex;
break;
}
}
return indexLeak;
}
size_t enumerateLeak(size_t indexAllocationTop, size_t indexDeallocationTop, bool lookFromBack, bool requireCallStack) {
using MemoryManagement::AllocationEvent;
using MemoryManagement::eventsAllocated;
using MemoryManagement::eventsDeallocated;
static auto start = MemoryManagement::invalidLeakIndex;
auto newIndex = start == MemoryManagement::invalidLeakIndex ? 0 : start;
bool potentialLeak = false;
auto potentialLeakIndex = newIndex;
for (; newIndex < indexAllocationTop; ++newIndex) {
auto currentIndex = lookFromBack ? indexAllocationTop - newIndex - 1 : newIndex;
auto &eventAllocation = eventsAllocated[currentIndex];
if (requireCallStack && eventAllocation.frames == 0) {
continue;
}
if (eventAllocation.event != AllocationEvent::EVENT_UNKNOWN) {
// Should be some sort of allocation
size_t deleteIndex = 0;
for (; deleteIndex < indexDeallocationTop; ++deleteIndex) {
auto &eventDeallocation = eventsDeallocated[deleteIndex];
if (eventDeallocation.address == eventAllocation.address &&
eventDeallocation.event != AllocationEvent::EVENT_UNKNOWN) {
//this memory was once freed, now it is allocated but not freed
if (requireCallStack && eventDeallocation.frames == 0) {
potentialLeak = true;
potentialLeakIndex = currentIndex;
continue;
}
// Clear the NEW and DELETE event.
eventAllocation.event = AllocationEvent::EVENT_UNKNOWN;
eventDeallocation.event = AllocationEvent::EVENT_UNKNOWN;
potentialLeak = false;
// Found a corresponding match
break;
}
}
if (potentialLeak) {
return potentialLeakIndex;
}
if (deleteIndex == indexDeallocationTop) {
start = newIndex + 1;
return currentIndex;
}
}
}
start = MemoryManagement::invalidLeakIndex;
return start;
}
std::string printCallStack(const MemoryManagement::AllocationEvent &event) {
std::string result = "";
printf("printCallStack.%d\n", event.frames);
if (!MemoryManagement::captureCallStacks) {
printf("for detailed stack information turn on captureCallStacks in memory_management.h\n");
}
if (event.frames > 0) {
#if defined(__linux__)
char **bt = backtrace_symbols(event.callstack, event.frames);
char *demangled;
int status;
char output[1024];
Dl_info info;
result += "\n";
for (int i = 0; i < event.frames; ++i) {
dladdr(event.callstack[i], &info);
if (info.dli_sname) {
demangled = nullptr;
status = -1;
if (info.dli_sname[0] == '_') {
demangled = abi::__cxa_demangle(info.dli_sname, nullptr, 0, &status);
}
snprintf(output, sizeof(output), "%-3d %*p %s + %zd\n",
(event.frames - i - 1), (int)(sizeof(void *) + 2), event.callstack[i],
status == 0 ? demangled : info.dli_sname == 0 ? bt[i] : info.dli_sname,
(char *)event.callstack[i] - (char *)info.dli_saddr);
free(demangled);
} else {
snprintf(output, sizeof(output), "%-3d %*p %s\n",
(event.frames - i - 1), (int)(sizeof(void *) + 2), event.callstack[i], bt[i]);
}
result += std::string(output);
}
result += "\n";
free(bt);
#elif defined(_WIN32)
SYMBOL_INFO *symbol;
HANDLE process;
process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
for (int i = 0; i < event.frames; i++) {
SymFromAddr(process, (DWORD64)(event.callstack[i]), 0, symbol);
printf("%i: %s - 0x%0" PRIx64 "\n", event.frames - i - 1, symbol->Name, symbol->Address);
}
free(symbol);
#endif
}
return result;
}
} // namespace MemoryManagement
using MemoryManagement::allocate;
using MemoryManagement::AllocationEvent;
using MemoryManagement::deallocate;
#if defined(_WIN32)
#pragma warning(disable : 4290)
#endif
void *operator new(size_t size) {
return allocate<AllocationEvent::EVENT_NEW, AllocationEvent::EVENT_NEW_FAIL>(size);
}
void *operator new(size_t size, const std::nothrow_t &) noexcept {
return allocate<AllocationEvent::EVENT_NEW_NOTHROW, AllocationEvent::EVENT_NEW_NOTHROW_FAIL>(size, std::nothrow);
}
void *operator new[](size_t size) {
return allocate<AllocationEvent::EVENT_NEW_ARRAY, AllocationEvent::EVENT_NEW_ARRAY_FAIL>(size);
}
void *operator new[](size_t size, const std::nothrow_t &t) noexcept {
return allocate<AllocationEvent::EVENT_NEW_ARRAY_NOTHROW, AllocationEvent::EVENT_NEW_ARRAY_NOTHROW_FAIL>(size, std::nothrow);
}
void operator delete(void *p) noexcept {
deallocate<AllocationEvent::EVENT_DELETE>(p);
}
void operator delete[](void *p) noexcept {
deallocate<AllocationEvent::EVENT_DELETE_ARRAY>(p);
}
void operator delete(void *p, size_t size) noexcept {
deallocate<AllocationEvent::EVENT_DELETE>(p);
}
void operator delete[](void *p, size_t size) noexcept {
deallocate<AllocationEvent::EVENT_DELETE_ARRAY>(p);
}

View File

@@ -1,88 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <string>
namespace MemoryManagement {
#if defined(__clang__)
#define NO_SANITIZE __attribute__((no_sanitize("undefined")))
#else
#define NO_SANITIZE
#endif
enum LeakDetectionMode {
STANDARD,
EXPECT_TO_LEAK,
TURN_OFF_LEAK_DETECTION
};
struct AllocationEvent { // NOLINT(clang-analyzer-optin.performance.Padding)
enum {
CallStackSize = 16
};
enum EventType {
EVENT_UNKNOWN,
EVENT_NEW,
EVENT_NEW_FAIL,
EVENT_NEW_NOTHROW,
EVENT_NEW_NOTHROW_FAIL,
EVENT_NEW_ARRAY,
EVENT_NEW_ARRAY_FAIL,
EVENT_NEW_ARRAY_NOTHROW,
EVENT_NEW_ARRAY_NOTHROW_FAIL,
EVENT_DELETE,
EVENT_DELETE_ARRAY
};
EventType event;
const void *address;
size_t size;
int frames;
void *callstack[CallStackSize];
bool fastLeakDetectionEnabled = false;
};
enum : int {
maxEvents = 1024 * 1024,
fastEvents = 1024 * 1024
};
extern AllocationEvent eventsAllocated[maxEvents];
extern AllocationEvent eventsDeallocated[maxEvents];
extern void *fastEventsAllocated[maxEvents];
extern void *fastEventsDeallocated[maxEvents];
extern std::atomic<int> fastEventsAllocatedCount;
extern std::atomic<int> fastEventsDeallocatedCount;
extern std::atomic<int> fastLeaksDetectionMode;
extern bool memsetNewAllocations;
extern size_t failingAllocation;
extern std::atomic<size_t> numAllocations;
extern std::atomic<size_t> indexAllocation;
extern std::atomic<size_t> indexDeallocation;
extern size_t breakOnAllocationEvent;
extern size_t breakOnDeallocationEvent;
extern bool logTraces;
extern bool detailedAllocationLoggingActive;
extern bool fastLeakDetectionEnabled;
extern void (*deleteCallback)(void *);
constexpr auto nonfailingAllocation = static_cast<size_t>(-1);
constexpr auto invalidLeakIndex = static_cast<size_t>(-1);
// capture allocations call stacks to print them during memory leak in ULTs
constexpr bool captureCallStacks = false;
int detectLeaks();
std::string printCallStack(const MemoryManagement::AllocationEvent &event);
size_t enumerateLeak(size_t indexAllocationTop, size_t indexDeallocationTop, bool lookFromEnd, bool requireCallStack);
} // namespace MemoryManagement

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/simd_helper.h"
#include "test.h"
namespace NEO {
template <typename WALKER_TYPE>
class GivenSimdSizeWhenGetSimdConfigCalledThenCorrectEnumReturned {
public:
static void TestBodyImpl() {
uint32_t simd = 32;
auto result = getSimdConfig<WALKER_TYPE>(simd);
EXPECT_EQ(result, WALKER_TYPE::SIMD_SIZE::SIMD_SIZE_SIMD32);
simd = 16;
result = getSimdConfig<WALKER_TYPE>(simd);
EXPECT_EQ(result, WALKER_TYPE::SIMD_SIZE::SIMD_SIZE_SIMD16);
simd = 8;
result = getSimdConfig<WALKER_TYPE>(simd);
EXPECT_EQ(result, WALKER_TYPE::SIMD_SIZE::SIMD_SIZE_SIMD8);
simd = 1;
result = getSimdConfig<WALKER_TYPE>(simd);
EXPECT_EQ(result, WALKER_TYPE::SIMD_SIZE::SIMD_SIZE_SIMD32);
}
};
} // namespace NEO

View File

@@ -1,150 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/hash.h"
#include "shared/source/helpers/string.h"
#include "gtest/gtest.h"
#if defined(__linux__)
TEST(StringHelpers, strncpy) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
//preconditions
ASSERT_EQ(sizeof(dst), sizeof(src));
//String must be smaller than array capacity
ASSERT_LT(strlen(src), sizeof(src));
auto ret = strncpy_s(nullptr, 1024, src, 1024);
EXPECT_EQ(ret, -EINVAL);
ret = strncpy_s(dst, 1024, nullptr, 1024);
EXPECT_EQ(ret, -EINVAL);
ret = strncpy_s(dst, 512, src, 1024);
EXPECT_EQ(ret, -ERANGE);
memset(dst, 0, sizeof(dst));
ret = strncpy_s(dst, 1024, src, strlen(src) / 2);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src) / 2));
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
memset(dst, 0, sizeof(dst));
ret = strncpy_s(dst, strlen(src) / 2, src, strlen(src) / 2);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src) / 2));
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
strncpy_s(dst, 1024, src, 1024);
EXPECT_EQ(0, memcmp(dst, src, strlen(src)));
for (size_t i = strlen(src); i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
}
TEST(StringHelpers, memmove) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
ASSERT_EQ(sizeof(dst), sizeof(src));
auto ret = memmove_s(nullptr, sizeof(dst), src, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memmove_s(dst, sizeof(dst), nullptr, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memmove_s(dst, sizeof(src) / 2, src, sizeof(src));
EXPECT_EQ(ret, -ERANGE);
memset(dst, 0, sizeof(dst));
ret = memmove_s(dst, sizeof(dst), src, sizeof(src));
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, sizeof(dst)));
}
TEST(StringHelpers, strcpy) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
ASSERT_EQ(sizeof(dst), sizeof(src));
auto ret = strcpy_s(nullptr, 0, src);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(nullptr, sizeof(dst), src);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(nullptr, 0, nullptr);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(nullptr, sizeof(dst), nullptr);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(dst, 0, nullptr);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(dst, strlen(src) / 2, src);
EXPECT_EQ(ret, -ERANGE);
ret = strcpy_s(dst, strlen(src), src);
EXPECT_EQ(ret, -ERANGE);
char pattern = 0x5a;
memset(dst, pattern, sizeof(dst));
ret = strcpy_s(dst, sizeof(dst), src);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src)));
EXPECT_EQ(0, dst[strlen(src)]);
for (size_t i = strlen(src) + 1; i < sizeof(dst); i++)
EXPECT_EQ(pattern, dst[i]);
}
TEST(StringHelpers, strnlen) {
char src[1024] = "HelloWorld";
auto ret = strnlen_s(nullptr, sizeof(src));
EXPECT_EQ(ret, 0u);
ret = strnlen_s(src, 0);
EXPECT_EQ(ret, 0u);
ret = strnlen_s(src, sizeof(src));
EXPECT_EQ(ret, strlen(src));
}
TEST(StringHelpers, memcpy) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
//preconditions
ASSERT_EQ(sizeof(dst), sizeof(src));
//String must be smaller than array capacity
ASSERT_LT(strlen(src), sizeof(src));
auto ret = memcpy_s(nullptr, sizeof(dst), src, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memcpy_s(dst, sizeof(dst), nullptr, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memcpy_s(dst, sizeof(dst) / 2, src, sizeof(src));
EXPECT_EQ(ret, -ERANGE);
memset(dst, 0, sizeof(dst));
ret = memcpy_s(dst, sizeof(dst), src, strlen(src) / 2);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src) / 2));
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
}
#endif

View File

@@ -1,238 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/hash.h"
#include "opencl/source/helpers/string_helpers.h"
#include "gtest/gtest.h"
using NEO::Hash;
TEST(CreateCombinedStrings, singleString) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char srcString[] = "HelloWorld";
const char *pSrcString = srcString;
auto srcStrings = &pSrcString;
size_t lengths = strlen(srcString);
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
srcStrings,
&lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(lengths + 1, dstStringSizeInBytes);
EXPECT_EQ(0, strcmp(srcString, dstString.c_str()));
}
TEST(CreateCombinedStrings, SingleStringWithNullLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char srcString[] = "HelloWorld";
const char *pSrcString = srcString;
auto srcStrings = &pSrcString;
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
srcStrings,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(srcString, dstString.c_str()));
}
TEST(CreateCombinedStrings, SingleStringWithZeroLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char srcString[] = "HelloWorld";
const char *pSrcString = srcString;
auto srcStrings = &pSrcString;
size_t lengths = 0;
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
srcStrings,
&lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(srcString, dstString.c_str()));
}
TEST(CreateCombinedStrings, multiString) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
auto srcStrings = &srcString[0];
size_t lengths[2] = {strlen(srcString[0]), strlen(srcString[1])};
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, multiStringWithNullLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
auto srcStrings = &srcString[0];
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, multiStringWithZeroLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
auto srcStrings = &srcString[0];
size_t lengths[2] = {0, strlen(srcString[1])};
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, GivenMultipleStringWhichOneContainsAndErrorAndSizeThatForcesDriverToOmitTheErorrThenProgramSourceDoesntContainErrorString) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleHBABA"};
const char *expString[] = {"HelloWorld", "dlroWolleH"};
size_t lengths[2] = {0, strlen(expString[1])};
std::string combined(expString[0]);
combined += expString[1];
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcString,
lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, negativeScenarios) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
const char *srcStrings[2] = {srcString[0], srcString[1]};
size_t lengths[2] = {0, strlen(srcString[1])};
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
0,
srcStrings,
lengths);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
nullptr,
lengths);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
srcStrings[0] = nullptr;
retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
lengths);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST(CreateCombinedStrings, GivenMultipleStringThatCountIsHigherThenMaximalStackSizeSizesWhenAskedForCombinedThenProperStringIsRetruned) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *defaultString = "hello";
const char *srcString[maximalStackSizeSizes + 2];
std::string combinedString;
for (int i = 0; i < maximalStackSizeSizes + 2; i++) {
srcString[i] = defaultString;
combinedString += defaultString;
}
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
maximalStackSizeSizes + 2,
srcString,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combinedString.c_str(), dstString.c_str()));
}
TEST(CreateHash, HashBuffers) {
char pBuffer[128];
memset(pBuffer, 0x23, sizeof(pBuffer));
// make sure we can get a hash and make sure we can get the same hash
auto hash1 = Hash::hash(pBuffer, sizeof(pBuffer));
auto hash2 = Hash::hash(pBuffer, sizeof(pBuffer));
EXPECT_NE(0u, hash1);
EXPECT_NE(0u, hash2);
EXPECT_EQ(hash1, hash2);
// make sure that we get a different hash for different length/data
auto hash3 = Hash::hash(pBuffer, sizeof(pBuffer) - 1);
EXPECT_NE(0u, hash3);
EXPECT_NE(hash2, hash3);
}
TEST(CreateHash, unalignedLengths) {
char pBuffer[] = {
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
// Use unaligned lengths. Wiggle the byte after the length
// Shouldn't affect hash.
for (auto length = 1u; length < sizeof(pBuffer); length++) {
auto hash1 = Hash::hash(pBuffer, length);
pBuffer[length]++;
EXPECT_EQ(hash1, Hash::hash(pBuffer, length));
}
}

View File

@@ -1,22 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
namespace NEO {
struct UltHwConfig {
bool mockedGetDevicesFuncResult = true;
bool useHwCsr = false;
bool useMockedGetDevicesFunc = true;
bool forceOsAgnosticMemoryManager = true;
bool csrFailInitDirectSubmission = false;
bool csrBaseCallDirectSubmissionAvailable = false;
bool csrSuperBaseCallDirectSubmissionAvailable = false;
};
extern UltHwConfig ultHwConfig;
} // namespace NEO

View File

@@ -1,12 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helpers/ult_hw_config.h"
namespace NEO {
UltHwConfig ultHwConfig{};
} // namespace NEO

View File

@@ -1,25 +0,0 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/hw_helper.h"
namespace NEO {
template <typename GfxFamily>
struct UltMemorySynchronizationCommands : MemorySynchronizationCommands<GfxFamily> {
using MemorySynchronizationCommands<GfxFamily>::getSizeForAdditonalSynchronization;
static size_t getExpectedPipeControlCount(const HardwareInfo &hwInfo) {
return (MemorySynchronizationCommands<GfxFamily>::getSizeForPipeControlWithPostSyncOperation(hwInfo) -
MemorySynchronizationCommands<GfxFamily>::getSizeForAdditonalSynchronization(hwInfo)) /
sizeof(typename GfxFamily::PIPE_CONTROL);
}
};
} // namespace NEO

View File

@@ -1,15 +0,0 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_IMAGE_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/image_surface_state_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/image_surface_state_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_IMAGE_TESTS ${NEO_CORE_IMAGE_TESTS})
add_subdirectories()

Some files were not shown because too many files have changed in this diff Show More