From dfd4e767e01a0dcfea122428fb1059538227abad Mon Sep 17 00:00:00 2001 From: "Hoppe, Mateusz" Date: Sun, 23 Sep 2018 21:42:07 -0700 Subject: [PATCH] Introducing AubFixture with minimum required initialization - fixture is creating AUBCsr or TBXWithAubCsr only and sets executionEnvironment used by Device - this sequence ensures correct initialization without redundant objects creation - adding new AUB test: AubWriteCopyReadBufferTest Change-Id: I678410585c91c008fc53a44b13e885e970fd315b --- .../aub_command_stream_receiver_hw.h | 2 + .../aub_command_stream_receiver_hw.inl | 33 +++++ .../aub_tests/command_queue/CMakeLists.txt | 2 + ...queue_write_copy_read_buffer_aub_tests.cpp | 126 ++++++++++++++++++ ...enqueue_write_copy_read_buffer_aub_tests.h | 30 +++++ unit_tests/aub_tests/fixtures/aub_fixture.h | 75 +++++++++++ .../aub_command_stream_receiver_tests.cpp | 59 ++++++++ 7 files changed, 327 insertions(+) create mode 100644 unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.cpp create mode 100644 unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.h create mode 100644 unit_tests/aub_tests/fixtures/aub_fixture.h diff --git a/runtime/command_stream/aub_command_stream_receiver_hw.h b/runtime/command_stream/aub_command_stream_receiver_hw.h index 520d270d2b..b57b780f9b 100644 --- a/runtime/command_stream/aub_command_stream_receiver_hw.h +++ b/runtime/command_stream/aub_command_stream_receiver_hw.h @@ -35,6 +35,8 @@ class AUBCommandStreamReceiverHw : public CommandStreamReceiverHw { MOCKABLE_VIRTUAL bool writeMemory(GraphicsAllocation &gfxAllocation); MOCKABLE_VIRTUAL bool writeMemory(AllocationView &allocationView); + void expectMMIO(uint32_t mmioRegister, uint32_t expectedValue); + void expectMemory(void *gfxAddress, const void *srcAddress, size_t length); void activateAubSubCapture(const MultiDispatchInfo &dispatchInfo) override; diff --git a/runtime/command_stream/aub_command_stream_receiver_hw.inl b/runtime/command_stream/aub_command_stream_receiver_hw.inl index 871e8918e0..36539fa669 100644 --- a/runtime/command_stream/aub_command_stream_receiver_hw.inl +++ b/runtime/command_stream/aub_command_stream_receiver_hw.inl @@ -605,6 +605,39 @@ bool AUBCommandStreamReceiverHw::writeMemory(AllocationView &allocati return writeMemory(gfxAllocation); } +template +void AUBCommandStreamReceiverHw::expectMMIO(uint32_t mmioRegister, uint32_t expectedValue) { + using AubMemDump::CmdServicesMemTraceRegisterCompare; + CmdServicesMemTraceRegisterCompare header; + memset(&header, 0, sizeof(header)); + header.setHeader(); + + header.data[0] = expectedValue; + header.registerOffset = mmioRegister; + header.noReadExpect = CmdServicesMemTraceRegisterCompare::NoReadExpectValues::ReadExpect; + header.registerSize = CmdServicesMemTraceRegisterCompare::RegisterSizeValues::Dword; + header.registerSpace = CmdServicesMemTraceRegisterCompare::RegisterSpaceValues::Mmio; + header.readMaskLow = 0xffffffff; + header.readMaskHigh = 0xffffffff; + header.dwordCount = (sizeof(header) / sizeof(uint32_t)) - 1; + + this->stream->fileHandle.write(reinterpret_cast(&header), sizeof(header)); +} + +template +void AUBCommandStreamReceiverHw::expectMemory(void *gfxAddress, const void *srcAddress, size_t length) { + PageWalker walker = [&](uint64_t physAddress, size_t size, size_t offset, uint64_t entryBits) { + UNRECOVERABLE_IF(offset > length); + + this->stream->expectMemory(physAddress, + reinterpret_cast(reinterpret_cast(srcAddress) + offset), + size, + this->getAddressSpaceFromPTEBits(entryBits)); + }; + + this->ppgtt->pageWalk(reinterpret_cast(gfxAddress), length, 0, PageTableEntry::nonValidBits, walker, MemoryBanks::BankNotSpecified); +} + template void AUBCommandStreamReceiverHw::processResidency(ResidencyContainer &allocationsForResidency, OsContext &osContext) { if (subCaptureManager->isSubCaptureMode()) { diff --git a/unit_tests/aub_tests/command_queue/CMakeLists.txt b/unit_tests/aub_tests/command_queue/CMakeLists.txt index 014d51cc50..bf27920168 100644 --- a/unit_tests/aub_tests/command_queue/CMakeLists.txt +++ b/unit_tests/aub_tests/command_queue/CMakeLists.txt @@ -20,5 +20,7 @@ target_sources(igdrcl_aub_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_read_image_aub_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_write_buffer_aub_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_write_buffer_rect_aub_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_write_copy_read_buffer_aub_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_write_copy_read_buffer_aub_tests.h ${CMAKE_CURRENT_SOURCE_DIR}/enqueue_write_image_aub_tests.cpp ) diff --git a/unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.cpp b/unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.cpp new file mode 100644 index 0000000000..71b76dfe6a --- /dev/null +++ b/unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2017-2018 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.h" + +#include "test.h" + +using namespace OCLRT; + +template +void AubWriteCopyReadBuffer::runTest() { + auto aubCsr = AUBFixture::getAubCsr(); + + char srcMemoryInitial[] = {1, 2, 3, 4, 5, 6, 7, 8}; + char dstMemoryInitial[] = {11, 12, 13, 14, 15, 16, 17, 18}; + + char srcMemoryToWrite[] = {1, 2, 3, 4, 5, 6, 7, 8}; + char dstMemoryToWrite[] = {11, 12, 13, 14, 15, 16, 17, 18}; + + const size_t bufferSize = sizeof(srcMemoryInitial); + + static_assert(bufferSize == sizeof(dstMemoryInitial), ""); + static_assert(bufferSize == sizeof(srcMemoryToWrite), ""); + static_assert(bufferSize == sizeof(dstMemoryToWrite), ""); + + auto retVal = CL_INVALID_VALUE; + auto srcBuffer = std::unique_ptr(Buffer::create( + context, + CL_MEM_COPY_HOST_PTR, + bufferSize, + srcMemoryInitial, + retVal)); + ASSERT_NE(nullptr, srcBuffer); + + auto dstBuffer = std::unique_ptr(Buffer::create( + context, + CL_MEM_COPY_HOST_PTR, + bufferSize, + dstMemoryInitial, + retVal)); + ASSERT_NE(nullptr, dstBuffer); + + aubCsr->writeMemory(*srcBuffer->getGraphicsAllocation()); + aubCsr->writeMemory(*dstBuffer->getGraphicsAllocation()); + + getAubCsr()->expectMemory(AUBFixture::getGpuPointer(srcBuffer->getGraphicsAllocation()), srcMemoryInitial, bufferSize); + getAubCsr()->expectMemory(AUBFixture::getGpuPointer(dstBuffer->getGraphicsAllocation()), dstMemoryInitial, bufferSize); + + cl_uint numEventsInWaitList = 0; + cl_event *eventWaitList = nullptr; + cl_event *event = nullptr; + + retVal = pCmdQ->enqueueWriteBuffer( + srcBuffer.get(), + true, + 0, + bufferSize, + srcMemoryToWrite, + numEventsInWaitList, + eventWaitList, + event); + + EXPECT_EQ(CL_SUCCESS, retVal); + + retVal = pCmdQ->enqueueWriteBuffer( + dstBuffer.get(), + true, + 0, + bufferSize, + dstMemoryToWrite, + numEventsInWaitList, + eventWaitList, + event); + + EXPECT_EQ(CL_SUCCESS, retVal); + + getAubCsr()->expectMemory(AUBFixture::getGpuPointer(srcBuffer->getGraphicsAllocation()), srcMemoryToWrite, bufferSize); + getAubCsr()->expectMemory(AUBFixture::getGpuPointer(dstBuffer->getGraphicsAllocation()), dstMemoryToWrite, bufferSize); + + retVal = pCmdQ->enqueueCopyBuffer( + srcBuffer.get(), + dstBuffer.get(), + 0, + 0, + bufferSize, + numEventsInWaitList, + eventWaitList, + event); + + EXPECT_EQ(CL_SUCCESS, retVal); + + pCmdQ->flush(); + + // Destination buffer should have src buffer content + getAubCsr()->expectMemory(AUBFixture::getGpuPointer(dstBuffer->getGraphicsAllocation()), srcMemoryToWrite, bufferSize); + + char hostPtrMemory[] = {0, 0, 0, 0, 0, 0, 0, 0}; + ASSERT_EQ(bufferSize, sizeof(hostPtrMemory)); + + retVal = pCmdQ->enqueueReadBuffer( + dstBuffer.get(), + false, + 0, + bufferSize, + hostPtrMemory, + numEventsInWaitList, + eventWaitList, + event); + + pCmdQ->flush(); + + GraphicsAllocation *allocation = csr->getMemoryManager()->graphicsAllocations.peekHead(); + while (allocation && allocation->getUnderlyingBuffer() != hostPtrMemory) { + allocation = allocation->next; + } + + getAubCsr()->expectMemory(AUBFixture::getGpuPointer(allocation), srcMemoryToWrite, bufferSize); +} + +HWTEST_F(AubWriteCopyReadBuffer, givenTwoBuffersFilledWithPatternWhenSourceIsCopiedToDestinationThenDestinationDataValidates) { + runTest(); +} diff --git a/unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.h b/unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.h new file mode 100644 index 0000000000..d95bc30489 --- /dev/null +++ b/unit_tests/aub_tests/command_queue/enqueue_write_copy_read_buffer_aub_tests.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017-2018 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "runtime/command_stream/command_stream_receiver.h" +#include "runtime/helpers/options.h" +#include "runtime/helpers/ptr_math.h" +#include "runtime/mem_obj/buffer.h" + +#include "unit_tests/aub_tests/fixtures/aub_fixture.h" + +using namespace OCLRT; + +struct AubWriteCopyReadBuffer : public AUBFixture, + public ::testing::Test { + + void SetUp() override { + AUBFixture::SetUp(); + } + + void TearDown() override { + AUBFixture::TearDown(); + } + + template + void runTest(); +}; diff --git a/unit_tests/aub_tests/fixtures/aub_fixture.h b/unit_tests/aub_tests/fixtures/aub_fixture.h new file mode 100644 index 0000000000..c1ca2f7197 --- /dev/null +++ b/unit_tests/aub_tests/fixtures/aub_fixture.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017-2018 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "runtime/aub_mem_dump/aub_mem_dump.h" +#include "runtime/aub_mem_dump/page_table_entry_bits.h" +#include "runtime/command_stream/aub_command_stream_receiver_hw.h" +#include "runtime/command_stream/command_stream_receiver_with_aub_dump.h" +#include "runtime/command_stream/tbx_command_stream_receiver_hw.h" +#include "runtime/helpers/hw_helper.h" +#include "runtime/os_interface/os_interface.h" + +#include "unit_tests/command_queue/command_queue_fixture.h" +#include "unit_tests/mocks/mock_device.h" +#include "unit_tests/tests_configuration.h" + +#include + +namespace OCLRT { + +class AUBFixture : public CommandQueueHwFixture { + public: + void SetUp() { + const HardwareInfo &hwInfo = *platformDevices[0]; + uint32_t deviceIndex = 0; + + const ::testing::TestInfo *const testInfo = ::testing::UnitTest::GetInstance()->current_test_info(); + std::stringstream strfilename; + strfilename << testInfo->test_case_name() << "_" << testInfo->name(); + + executionEnvironment = new ExecutionEnvironment; + + if (testMode == TestMode::AubTests) { + this->csr = AUBCommandStreamReceiver::create(hwInfo, strfilename.str(), true, *executionEnvironment); + } else if (testMode == TestMode::AubTestsWithTbx) { + this->csr = TbxCommandStreamReceiver::create(hwInfo, true, *executionEnvironment); + } + + executionEnvironment->commandStreamReceivers.resize(deviceIndex + 1); + executionEnvironment->commandStreamReceivers[deviceIndex] = std::unique_ptr(this->csr); + device.reset(MockDevice::create(&hwInfo, executionEnvironment, deviceIndex)); + + CommandQueueHwFixture::SetUp(AUBFixture::device.get(), cl_command_queue_properties(0)); + } + void TearDown() { + CommandQueueHwFixture::TearDown(); + } + + template + AUBCommandStreamReceiverHw *getAubCsr() { + AUBCommandStreamReceiverHw *aubCsr = nullptr; + if (testMode == TestMode::AubTests) { + aubCsr = reinterpret_cast *>(csr); + } else if (testMode == TestMode::AubTestsWithTbx) { + aubCsr = reinterpret_cast *>( + reinterpret_cast> *>(csr)->aubCSR); + } + return aubCsr; + } + + static void *getGpuPointer(GraphicsAllocation *allocation) { + return reinterpret_cast(allocation->getGpuAddress()); + } + + CommandStreamReceiver *csr = nullptr; + volatile uint32_t *pTagMemory = nullptr; + std::unique_ptr device; + + ExecutionEnvironment *executionEnvironment; +}; +} // namespace OCLRT diff --git a/unit_tests/command_stream/aub_command_stream_receiver_tests.cpp b/unit_tests/command_stream/aub_command_stream_receiver_tests.cpp index 032d0be3e7..c49a4f95c3 100644 --- a/unit_tests/command_stream/aub_command_stream_receiver_tests.cpp +++ b/unit_tests/command_stream/aub_command_stream_receiver_tests.cpp @@ -24,6 +24,7 @@ #include "unit_tests/mocks/mock_kernel.h" #include "unit_tests/mocks/mock_mdi.h" +#include #include #if defined(__clang__) @@ -109,9 +110,19 @@ struct MockAubFileStream : public AUBCommandStreamReceiver::AubFileStream { lockStreamCalled = true; return AUBCommandStreamReceiver::AubFileStream::lockStream(); } + void expectMemory(uint64_t physAddress, const void *memory, size_t size, uint32_t addressSpace) override { + physAddressCapturedFromExpectMemory = physAddress; + memoryCapturedFromExpectMemory = reinterpret_cast(memory); + sizeCapturedFromExpectMemory = size; + addressSpaceCapturedFromExpectMemory = addressSpace; + } uint32_t initCalledCnt = 0; bool flushCalled = false; bool lockStreamCalled = false; + uint64_t physAddressCapturedFromExpectMemory = 0; + uintptr_t memoryCapturedFromExpectMemory = 0; + size_t sizeCapturedFromExpectMemory = 0; + uint32_t addressSpaceCapturedFromExpectMemory = 0; }; struct GmockAubFileStream : public AUBCommandStreamReceiver::AubFileStream { @@ -345,6 +356,54 @@ HWTEST_F(AubCommandStreamReceiverTests, givenAubCommandStreamReceiverWhenFlushIs EXPECT_TRUE(mockAubFileStreamPtr->lockStreamCalled); } +HWTEST_F(AubCommandStreamReceiverTests, givenAubCommandStreamReceiverWhenExpectMemoryIsCalledThenPageWalkIsCallingStreamsExpectMemory) { + auto aubCsr = std::make_unique>(**platformDevices, "", true, *pDevice->executionEnvironment); + + std::unique_ptr mockAubFileStream(std::make_unique()); + MockAubFileStream *mockAubFileStreamPtr = static_cast(mockAubFileStream.get()); + ASSERT_NE(nullptr, mockAubFileStreamPtr); + aubCsr->stream = mockAubFileStreamPtr; + + uintptr_t gpuAddress = 0x30000; + void *sourceAddress = reinterpret_cast(0x50000); + auto physicalAddress = aubCsr->ppgtt->map(gpuAddress, MemoryConstants::pageSize, PageTableEntry::presentBit, MemoryBanks::MainBank); + + aubCsr->expectMemory(reinterpret_cast(gpuAddress), sourceAddress, MemoryConstants::pageSize); + + EXPECT_EQ(AubMemDump::AddressSpaceValues::TraceNonlocal, mockAubFileStreamPtr->addressSpaceCapturedFromExpectMemory); + EXPECT_EQ(reinterpret_cast(sourceAddress), mockAubFileStreamPtr->memoryCapturedFromExpectMemory); + EXPECT_EQ(physicalAddress, mockAubFileStreamPtr->physAddressCapturedFromExpectMemory); + EXPECT_EQ(MemoryConstants::pageSize, mockAubFileStreamPtr->sizeCapturedFromExpectMemory); +} + +HWTEST_F(AubCommandStreamReceiverTests, givenAubCommandStreamReceiverWhenExpectMMIOIsCalledThenHeaderIsWrittenToFile) { + std::string fileName = "file_name.aub"; + auto aubCsr = std::make_unique>(**platformDevices, fileName.c_str(), true, *pDevice->executionEnvironment); + + std::remove(fileName.c_str()); + + std::unique_ptr mockAubFileStream(std::make_unique()); + MockAubFileStream *mockAubFileStreamPtr = static_cast(mockAubFileStream.get()); + ASSERT_NE(nullptr, mockAubFileStreamPtr); + aubCsr->stream = mockAubFileStreamPtr; + aubCsr->initFile(fileName); + + aubCsr->expectMMIO(5, 10); + + aubCsr->stream->fileHandle.flush(); + + std::ifstream aubFile(fileName); + EXPECT_TRUE(aubFile.is_open()); + + if (aubFile.is_open()) { + AubMemDump::CmdServicesMemTraceRegisterCompare header; + aubFile.read(reinterpret_cast(&header), sizeof(AubMemDump::CmdServicesMemTraceRegisterCompare)); + EXPECT_EQ(5u, header.registerOffset); + EXPECT_EQ(10u, header.data[0]); + aubFile.close(); + } +} + HWTEST_F(AubCommandStreamReceiverTests, givenGraphicsAllocationWhenMakeResidentCalledMultipleTimesAffectsResidencyOnce) { std::unique_ptr memoryManager(nullptr); std::unique_ptr> aubCsr(new AUBCommandStreamReceiverHw(*platformDevices[0], "", true, *pDevice->executionEnvironment));