mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-08 05:56:36 +08:00
Initial commit
Change-Id: I4bf1707bd3dfeadf2c17b0a7daff372b1925ebbd
This commit is contained in:
27
unit_tests/device_queue/CMakeLists.txt
Normal file
27
unit_tests/device_queue/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2017, Intel Corporation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
set(IGDRCL_SRCS_tests_device_queue
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/device_queue_tests.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/device_queue_hw_tests.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/get_device_queue_info_tests.cpp"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
632
unit_tests/device_queue/device_queue_hw_tests.cpp
Normal file
632
unit_tests/device_queue/device_queue_hw_tests.cpp
Normal file
@@ -0,0 +1,632 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw_cmds.h"
|
||||
#include "runtime/helpers/options.h"
|
||||
#include "unit_tests/fixtures/device_host_queue_fixture.h"
|
||||
#include "unit_tests/fixtures/execution_model_fixture.h"
|
||||
#include "unit_tests/helpers/hw_parse.h"
|
||||
#include "unit_tests/mocks/mock_context.h"
|
||||
#include "unit_tests/mocks/mock_device_queue.h"
|
||||
#include "unit_tests/mocks/mock_device.h"
|
||||
#include "unit_tests/mocks/mock_kernel.h"
|
||||
#include "unit_tests/helpers/debug_manager_state_restore.h"
|
||||
|
||||
#include "runtime/command_queue/dispatch_walker_helper.h"
|
||||
#include "runtime/helpers/kernel_commands.h"
|
||||
|
||||
using namespace OCLRT;
|
||||
using namespace DeviceHostQueue;
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, resetOnlyExpected) {
|
||||
// profiling disabled
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
auto deviceQueueHw = castToHwType<FamilyType>(deviceQueue);
|
||||
|
||||
auto expected = getExpectedgilCmdQueueAfterReset(deviceQueue);
|
||||
deviceQueueHw->resetDeviceQueue();
|
||||
|
||||
EXPECT_EQ(0, memcmp(deviceQueueHw->getQueueBuffer()->getUnderlyingBuffer(),
|
||||
&expected, sizeof(IGIL_CommandQueue)));
|
||||
|
||||
delete deviceQueue;
|
||||
|
||||
//profiling enabled
|
||||
deviceQueue = createQueueObject(deviceQueueProperties::minimumPropertiesWithProfiling);
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
deviceQueueHw = castToHwType<FamilyType>(deviceQueue);
|
||||
|
||||
expected = getExpectedgilCmdQueueAfterReset(deviceQueue);
|
||||
deviceQueueHw->resetDeviceQueue();
|
||||
|
||||
EXPECT_EQ(1u, expected.m_controls.m_IsProfilingEnabled);
|
||||
|
||||
EXPECT_EQ(0, memcmp(deviceQueue->getQueueBuffer()->getUnderlyingBuffer(),
|
||||
&expected, sizeof(IGIL_CommandQueue)));
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, resetStack) {
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
auto deviceQueueHw = castToHwType<FamilyType>(deviceQueue);
|
||||
|
||||
deviceQueueHw->resetDeviceQueue();
|
||||
|
||||
auto stack = static_cast<uint32_t *>(deviceQueue->getStackBuffer()->getUnderlyingBuffer());
|
||||
stack += ((deviceQueue->getStackBuffer()->getUnderlyingBufferSize() / sizeof(uint32_t)) - 1);
|
||||
EXPECT_EQ(*stack, 1u); // first stack element in surface at value "1"
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, acquireEMCriticalSectionDoesNotAcquireWhenNullHardwareIsEnabled) {
|
||||
DebugManagerStateRestore dbgRestorer;
|
||||
|
||||
DebugManager.flags.EnableNullHardware.set(1);
|
||||
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
auto deviceQueueHw = castToHwType<FamilyType>(deviceQueue);
|
||||
|
||||
deviceQueueHw->acquireEMCriticalSection();
|
||||
|
||||
EXPECT_TRUE(deviceQueueHw->isEMCriticalSectionFree());
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, getCSPrefetchSize) {
|
||||
auto mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(pContext, device,
|
||||
deviceQueueProperties::minimumProperties[0]);
|
||||
|
||||
EXPECT_NE(0u, mockDeviceQueueHw->getCSPrefetchSize());
|
||||
delete mockDeviceQueueHw;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, addLriWithArbCheck) {
|
||||
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
|
||||
auto mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(pContext, device,
|
||||
deviceQueueProperties::minimumProperties[0]);
|
||||
|
||||
mockDeviceQueueHw->addLriCmd(true);
|
||||
|
||||
HardwareParse hwParser;
|
||||
auto *slbCS = mockDeviceQueueHw->getSlbCS();
|
||||
|
||||
hwParser.parseCommands<FamilyType>(*slbCS, 0);
|
||||
auto loadRegImmItor = find<MI_LOAD_REGISTER_IMM *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
|
||||
|
||||
ASSERT_NE(hwParser.cmdList.end(), loadRegImmItor);
|
||||
|
||||
MI_LOAD_REGISTER_IMM *loadRegImm = (MI_LOAD_REGISTER_IMM *)*loadRegImmItor;
|
||||
|
||||
EXPECT_EQ(0x2248u, loadRegImm->getRegisterOffset());
|
||||
EXPECT_EQ(0x100u, loadRegImm->getDataDword());
|
||||
|
||||
EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM), slbCS->getUsed());
|
||||
delete mockDeviceQueueHw;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, addLriWithoutArbCheck) {
|
||||
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
|
||||
auto mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(pContext, device,
|
||||
deviceQueueProperties::minimumProperties[0]);
|
||||
|
||||
mockDeviceQueueHw->addLriCmd(false);
|
||||
|
||||
HardwareParse hwParser;
|
||||
auto *slbCS = mockDeviceQueueHw->getSlbCS();
|
||||
|
||||
hwParser.parseCommands<FamilyType>(*slbCS, 0);
|
||||
auto loadRegImmItor = find<MI_LOAD_REGISTER_IMM *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
|
||||
|
||||
ASSERT_NE(hwParser.cmdList.end(), loadRegImmItor);
|
||||
|
||||
MI_LOAD_REGISTER_IMM *loadRegImm = (MI_LOAD_REGISTER_IMM *)*loadRegImmItor;
|
||||
|
||||
EXPECT_EQ(0x2248u, loadRegImm->getRegisterOffset());
|
||||
EXPECT_EQ(0u, loadRegImm->getDataDword());
|
||||
|
||||
EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM), slbCS->getUsed());
|
||||
delete mockDeviceQueueHw;
|
||||
}
|
||||
|
||||
class DeviceQueueSlb : public DeviceQueueHwTest {
|
||||
public:
|
||||
template <typename Cmd>
|
||||
void *compareCmds(void *position, Cmd &cmd) {
|
||||
EXPECT_EQ(0, memcmp(position, &cmd, sizeof(Cmd)));
|
||||
return ptrOffset(position, sizeof(Cmd));
|
||||
}
|
||||
void *compareCmdsWithSize(void *position, void *cmd, size_t size) {
|
||||
EXPECT_EQ(0, memcmp(position, cmd, size));
|
||||
return ptrOffset(position, size);
|
||||
}
|
||||
};
|
||||
|
||||
HWTEST_F(DeviceQueueSlb, buildSlbAfterReset) {
|
||||
auto mockDeviceQueueHw =
|
||||
new MockDeviceQueueHw<FamilyType>(pContext, device, deviceQueueProperties::minimumProperties[0]);
|
||||
auto mockDeviceQueueHwWithProfiling =
|
||||
new MockDeviceQueueHw<FamilyType>(pContext, device, deviceQueueProperties::minimumPropertiesWithProfiling[0]);
|
||||
|
||||
LinearStream *slbCS = mockDeviceQueueHw->getSlbCS();
|
||||
auto expectedSize = (mockDeviceQueueHw->getMinimumSlbSize() + mockDeviceQueueHw->getWaCommandsSize()) * 128;
|
||||
expectedSize += sizeof(typename FamilyType::MI_BATCH_BUFFER_START);
|
||||
|
||||
mockDeviceQueueHw->resetDeviceQueue();
|
||||
mockDeviceQueueHwWithProfiling->resetDeviceQueue();
|
||||
EXPECT_EQ(slbCS->getUsed(), expectedSize);
|
||||
EXPECT_EQ(mockDeviceQueueHwWithProfiling->getSlbCS()->getUsed(), expectedSize);
|
||||
|
||||
auto cmds = mockDeviceQueueHw->expectedCmds;
|
||||
auto cmdsWithProfiling = mockDeviceQueueHwWithProfiling->expectedCmds;
|
||||
|
||||
void *currCmd = slbCS->getBase();
|
||||
void *currCmdWithProfiling = mockDeviceQueueHwWithProfiling->getSlbCS()->getBase();
|
||||
for (size_t i = 0; i < 128; i++) {
|
||||
currCmd = compareCmds(currCmd, cmds.mediaStateFlush);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.mediaStateFlush);
|
||||
|
||||
if (mockDeviceQueueHw->arbCheckWa) {
|
||||
currCmd = compareCmds(currCmd, cmds.arbCheck);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.arbCheck);
|
||||
}
|
||||
if (mockDeviceQueueHw->miAtomicWa) {
|
||||
currCmd = compareCmds(currCmd, cmds.miAtomic);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.miAtomic);
|
||||
}
|
||||
|
||||
currCmd = compareCmds(currCmd, cmds.mediaIdLoad);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.mediaIdLoad);
|
||||
|
||||
if (mockDeviceQueueHw->lriWa) {
|
||||
currCmd = compareCmds(currCmd, cmds.lriTrue);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.lriTrue);
|
||||
}
|
||||
|
||||
currCmd = compareCmds(currCmd, cmds.noopedPipeControl); // noop pipe control
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.pipeControl);
|
||||
|
||||
if (mockDeviceQueueHw->pipeControlWa) {
|
||||
currCmd = compareCmds(currCmd, cmds.noopedPipeControl); // noop pipe control
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.pipeControl);
|
||||
}
|
||||
|
||||
currCmd = compareCmds(currCmd, cmds.gpgpuWalker);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.gpgpuWalker);
|
||||
|
||||
currCmd = compareCmds(currCmd, cmds.mediaStateFlush);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.mediaStateFlush);
|
||||
|
||||
if (mockDeviceQueueHw->arbCheckWa) {
|
||||
currCmd = compareCmds(currCmd, cmds.arbCheck);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.arbCheck);
|
||||
}
|
||||
|
||||
currCmd = compareCmds(currCmd, cmds.pipeControl);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.pipeControl);
|
||||
|
||||
if (mockDeviceQueueHw->pipeControlWa) {
|
||||
currCmd = compareCmds(currCmd, cmds.pipeControl);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.pipeControl);
|
||||
}
|
||||
|
||||
if (mockDeviceQueueHw->lriWa) {
|
||||
currCmd = compareCmds(currCmd, cmds.lriFalse);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, cmdsWithProfiling.lriFalse);
|
||||
}
|
||||
|
||||
currCmd = compareCmdsWithSize(currCmd, cmds.prefetch, DeviceQueueHw<FamilyType>::getCSPrefetchSize());
|
||||
currCmdWithProfiling = compareCmdsWithSize(currCmdWithProfiling, cmdsWithProfiling.prefetch, DeviceQueueHw<FamilyType>::getCSPrefetchSize());
|
||||
}
|
||||
|
||||
currCmd = compareCmds(currCmd, cmds.bbStart);
|
||||
currCmdWithProfiling = compareCmds(currCmdWithProfiling, mockDeviceQueueHwWithProfiling->expectedCmds.bbStart);
|
||||
|
||||
delete mockDeviceQueueHw;
|
||||
delete mockDeviceQueueHwWithProfiling;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueSlb, slbEndOffset) {
|
||||
auto mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(pContext, device,
|
||||
deviceQueueProperties::minimumProperties[0]);
|
||||
|
||||
auto slb = mockDeviceQueueHw->getSlbBuffer();
|
||||
auto commandsSize = mockDeviceQueueHw->getMinimumSlbSize() + mockDeviceQueueHw->getWaCommandsSize();
|
||||
auto slbCopy = malloc(slb->getUnderlyingBufferSize());
|
||||
memset(slb->getUnderlyingBuffer(), 0xFE, slb->getUnderlyingBufferSize());
|
||||
memcpy(slbCopy, slb->getUnderlyingBuffer(), slb->getUnderlyingBufferSize());
|
||||
|
||||
auto igilCmdQueue = reinterpret_cast<IGIL_CommandQueue *>(mockDeviceQueueHw->getQueueBuffer()->getUnderlyingBuffer());
|
||||
|
||||
// slbEndOffset < commandsSize * 128
|
||||
// always fill only 1 enqueue (after offset)
|
||||
auto offset = static_cast<int>(commandsSize) * 50;
|
||||
igilCmdQueue->m_controls.m_SLBENDoffsetInBytes = offset;
|
||||
mockDeviceQueueHw->resetDeviceQueue();
|
||||
EXPECT_EQ(0, memcmp(slb->getUnderlyingBuffer(), slbCopy, offset)); // dont touch memory before offset
|
||||
EXPECT_NE(0, memcmp(ptrOffset(slb->getUnderlyingBuffer(), offset),
|
||||
slbCopy, commandsSize)); // change 1 enqueue
|
||||
EXPECT_EQ(0, memcmp(ptrOffset(slb->getUnderlyingBuffer(), offset + commandsSize),
|
||||
slbCopy, offset)); // dont touch memory after (offset + 1 enqueue)
|
||||
compareCmds(ptrOffset(slb->getUnderlyingBuffer(), commandsSize * 128),
|
||||
mockDeviceQueueHw->expectedCmds.bbStart); // bbStart always on the same place
|
||||
|
||||
// slbEndOffset == commandsSize * 128
|
||||
// dont fill commands
|
||||
memset(slb->getUnderlyingBuffer(), 0xFEFEFEFE, slb->getUnderlyingBufferSize());
|
||||
offset = static_cast<int>(commandsSize) * 128;
|
||||
igilCmdQueue->m_controls.m_SLBENDoffsetInBytes = static_cast<int>(commandsSize);
|
||||
mockDeviceQueueHw->resetDeviceQueue();
|
||||
EXPECT_EQ(0, memcmp(slb->getUnderlyingBuffer(), slbCopy, commandsSize * 128)); // dont touch memory for enqueues
|
||||
compareCmds(ptrOffset(slb->getUnderlyingBuffer(), commandsSize * 128),
|
||||
mockDeviceQueueHw->expectedCmds.bbStart); // bbStart always on the same place
|
||||
|
||||
delete mockDeviceQueueHw;
|
||||
free(slbCopy);
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueSlb, cleanupSection) {
|
||||
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
|
||||
using MI_BATCH_BUFFER_END = typename FamilyType::MI_BATCH_BUFFER_END;
|
||||
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||
|
||||
auto mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(pContext, device, deviceQueueProperties::minimumProperties[0]);
|
||||
auto commandsSize = mockDeviceQueueHw->getMinimumSlbSize() + mockDeviceQueueHw->getWaCommandsSize();
|
||||
auto igilCmdQueue = reinterpret_cast<IGIL_CommandQueue *>(mockDeviceQueueHw->getQueueBuffer()->getUnderlyingBuffer());
|
||||
MockParentKernel *mockParentKernel = MockParentKernel::create(*device);
|
||||
uint32_t taskCount = 7;
|
||||
|
||||
mockDeviceQueueHw->buildSlbDummyCommands();
|
||||
mockDeviceQueueHw->addExecutionModelCleanUpSection(mockParentKernel, nullptr, taskCount);
|
||||
|
||||
HardwareParse hwParser;
|
||||
auto *slbCS = mockDeviceQueueHw->getSlbCS();
|
||||
size_t cleanupSectionOffset = alignUp(mockDeviceQueueHw->numberOfDeviceEnqueues * commandsSize + sizeof(MI_BATCH_BUFFER_START), MemoryConstants::pageSize);
|
||||
size_t cleanupSectionOffsetToParse = cleanupSectionOffset;
|
||||
|
||||
if (mockParentKernel->getKernelInfo().patchInfo.executionEnvironment->UsesFencesForReadWriteImages) {
|
||||
|
||||
cleanupSectionOffsetToParse += getSizeForWADisableLSQCROPERFforOCL<FamilyType>(mockParentKernel) / 2;
|
||||
}
|
||||
|
||||
hwParser.parseCommands<FamilyType>(*slbCS, cleanupSectionOffsetToParse);
|
||||
hwParser.findHardwareCommands<FamilyType>();
|
||||
|
||||
uint64_t cleanUpSectionAddress = (uint64_t)slbCS->getBase() + cleanupSectionOffset;
|
||||
EXPECT_EQ(cleanUpSectionAddress, igilCmdQueue->m_controls.m_CleanupSectionAddress);
|
||||
EXPECT_EQ(slbCS->getUsed() - cleanupSectionOffset, igilCmdQueue->m_controls.m_CleanupSectionSize);
|
||||
|
||||
auto pipeControlItor = find<PIPE_CONTROL *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
|
||||
EXPECT_NE(hwParser.cmdList.end(), pipeControlItor);
|
||||
|
||||
auto bbEndItor = find<MI_BATCH_BUFFER_END *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
|
||||
EXPECT_NE(hwParser.cmdList.end(), bbEndItor);
|
||||
MI_BATCH_BUFFER_END *bbEnd = (MI_BATCH_BUFFER_END *)*bbEndItor;
|
||||
uint64_t bbEndAddres = (uint64_t)bbEnd;
|
||||
|
||||
EXPECT_LE(mockDeviceQueueHw->getSlbBuffer()->getGpuAddress() + cleanupSectionOffset, bbEndAddres);
|
||||
|
||||
delete mockParentKernel;
|
||||
delete mockDeviceQueueHw;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueSlb, AddEMCleanupSectionWithProfiling) {
|
||||
using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START;
|
||||
using MI_BATCH_BUFFER_END = typename FamilyType::MI_BATCH_BUFFER_END;
|
||||
using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
|
||||
using MI_STORE_REGISTER_MEM = typename FamilyType::MI_STORE_REGISTER_MEM;
|
||||
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
|
||||
|
||||
auto mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(pContext, device, deviceQueueProperties::minimumProperties[0]);
|
||||
auto commandsSize = mockDeviceQueueHw->getMinimumSlbSize() + mockDeviceQueueHw->getWaCommandsSize();
|
||||
auto igilCmdQueue = reinterpret_cast<IGIL_CommandQueue *>(mockDeviceQueueHw->getQueueBuffer()->getUnderlyingBuffer());
|
||||
MockParentKernel *mockParentKernel = MockParentKernel::create(*device);
|
||||
uint32_t taskCount = 7;
|
||||
|
||||
HwTimeStamps hwTimeStamp;
|
||||
mockDeviceQueueHw->buildSlbDummyCommands();
|
||||
mockDeviceQueueHw->addExecutionModelCleanUpSection(mockParentKernel, &hwTimeStamp, taskCount);
|
||||
|
||||
uint32_t eventTimestampLow = (uint32_t)(igilCmdQueue->m_controls.m_EventTimestampAddress & 0xFFFFFFFF);
|
||||
uint32_t eventTimestampHigh = (uint32_t)((igilCmdQueue->m_controls.m_EventTimestampAddress & 0xFFFFFFFF00000000) >> 32);
|
||||
|
||||
uint32_t contextCompleteLow = (uint32_t)((uint64_t)((uintptr_t)(&hwTimeStamp.ContextCompleteTS)) & 0xFFFFFFFF);
|
||||
uint32_t contextCompleteHigh = (uint32_t)(((uint64_t)((uintptr_t)(&hwTimeStamp.ContextCompleteTS)) & 0xFFFFFFFF00000000) >> 32);
|
||||
|
||||
EXPECT_EQ(contextCompleteLow, eventTimestampLow);
|
||||
EXPECT_EQ(contextCompleteHigh, eventTimestampHigh);
|
||||
|
||||
HardwareParse hwParser;
|
||||
auto *slbCS = mockDeviceQueueHw->getSlbCS();
|
||||
size_t cleanupSectionOffset = alignUp(mockDeviceQueueHw->numberOfDeviceEnqueues * commandsSize + sizeof(MI_BATCH_BUFFER_START), MemoryConstants::pageSize);
|
||||
size_t cleanupSectionOffsetToParse = cleanupSectionOffset;
|
||||
|
||||
hwParser.parseCommands<FamilyType>(*slbCS, cleanupSectionOffsetToParse);
|
||||
hwParser.findHardwareCommands<FamilyType>();
|
||||
|
||||
uint64_t cleanUpSectionAddress = (uint64_t)slbCS->getBase() + cleanupSectionOffset;
|
||||
EXPECT_EQ(cleanUpSectionAddress, igilCmdQueue->m_controls.m_CleanupSectionAddress);
|
||||
EXPECT_EQ(slbCS->getUsed() - cleanupSectionOffset, igilCmdQueue->m_controls.m_CleanupSectionSize);
|
||||
|
||||
auto pipeControlItor = find<PIPE_CONTROL *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
|
||||
|
||||
if (mockParentKernel->getKernelInfo().patchInfo.executionEnvironment->UsesFencesForReadWriteImages && getSizeForWADisableLSQCROPERFforOCL<FamilyType>(mockParentKernel) > 0) {
|
||||
auto loadRegImmItor = find<MI_LOAD_REGISTER_IMM *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
|
||||
EXPECT_NE(hwParser.cmdList.end(), loadRegImmItor);
|
||||
|
||||
pipeControlItor = find<PIPE_CONTROL *>(loadRegImmItor, hwParser.cmdList.end());
|
||||
pipeControlItor++;
|
||||
}
|
||||
|
||||
EXPECT_NE(hwParser.cmdList.end(), pipeControlItor);
|
||||
|
||||
PIPE_CONTROL *pipeControl = (PIPE_CONTROL *)*pipeControlItor;
|
||||
EXPECT_NE(0u, pipeControl->getCommandStreamerStallEnable());
|
||||
|
||||
auto loadRegImmItor = find<MI_LOAD_REGISTER_IMM *>(pipeControlItor, hwParser.cmdList.end());
|
||||
|
||||
ASSERT_NE(hwParser.cmdList.end(), loadRegImmItor);
|
||||
|
||||
MI_LOAD_REGISTER_IMM *loadRegImm = (MI_LOAD_REGISTER_IMM *)*loadRegImmItor;
|
||||
|
||||
EXPECT_EQ(0x2248u, loadRegImm->getRegisterOffset());
|
||||
EXPECT_EQ(0u, loadRegImm->getDataDword());
|
||||
|
||||
pipeControlItor++;
|
||||
EXPECT_NE(hwParser.cmdList.end(), pipeControlItor);
|
||||
|
||||
auto bbEndItor = find<MI_BATCH_BUFFER_END *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
|
||||
EXPECT_NE(hwParser.cmdList.end(), bbEndItor);
|
||||
MI_BATCH_BUFFER_END *bbEnd = (MI_BATCH_BUFFER_END *)*bbEndItor;
|
||||
uint64_t bbEndAddres = (uint64_t)bbEnd;
|
||||
|
||||
EXPECT_LE(mockDeviceQueueHw->getSlbBuffer()->getGpuAddress() + cleanupSectionOffset, bbEndAddres);
|
||||
|
||||
delete mockParentKernel;
|
||||
delete mockDeviceQueueHw;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, getIndirectHeapDSH) {
|
||||
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
|
||||
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
auto *devQueueHw = castToObject<DeviceQueueHw<FamilyType>>(deviceQueue);
|
||||
|
||||
auto heap = devQueueHw->getIndirectHeap(IndirectHeap::DYNAMIC_STATE);
|
||||
|
||||
ASSERT_NE(nullptr, heap);
|
||||
|
||||
auto dshBuffer = deviceQueue->getDshBuffer()->getUnderlyingBuffer();
|
||||
auto dshBufferSize = deviceQueue->getDshBuffer()->getUnderlyingBufferSize();
|
||||
|
||||
auto size = heap->getAvailableSpace();
|
||||
auto heapMemory = heap->getBase();
|
||||
|
||||
// ExecutionModel DSH is offseted by colorCalcState, ParentKernel Interface Descriptor Data is located in first table just after colorCalcState
|
||||
|
||||
EXPECT_EQ(dshBufferSize - DeviceQueue::colorCalcStateSize, size);
|
||||
EXPECT_EQ(dshBuffer, heapMemory);
|
||||
EXPECT_EQ(ptrOffset(dshBuffer, DeviceQueue::colorCalcStateSize), heap->getSpace(0));
|
||||
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, getIndirectHeapNonExistent) {
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
auto *devQueueHw = castToObject<DeviceQueueHw<FamilyType>>(deviceQueue);
|
||||
|
||||
auto heap = devQueueHw->getIndirectHeap(IndirectHeap::GENERAL_STATE);
|
||||
|
||||
EXPECT_EQ(nullptr, heap);
|
||||
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
HWTEST_F(DeviceQueueHwTest, getDshOffset) {
|
||||
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
|
||||
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
auto *devQueueHw = castToObject<DeviceQueueHw<FamilyType>>(deviceQueue);
|
||||
|
||||
size_t offsetDsh = sizeof(INTERFACE_DESCRIPTOR_DATA) * DeviceQueue::interfaceDescriptorEntries * DeviceQueue::numberOfIDTables + DeviceQueue::colorCalcStateSize;
|
||||
|
||||
EXPECT_EQ(devQueueHw->getDshOffset(), offsetDsh);
|
||||
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
class DeviceQueueHwWithKernel : public ExecutionModelKernelFixture {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ExecutionModelKernelFixture::SetUp();
|
||||
cl_queue_properties properties[5] = {
|
||||
CL_QUEUE_PROPERTIES,
|
||||
CL_QUEUE_ON_DEVICE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
|
||||
0, 0, 0};
|
||||
cl_int errcodeRet = 0;
|
||||
|
||||
device = Device::create<OCLRT::MockDevice>(platformDevices[0]);
|
||||
context = new MockContext();
|
||||
ASSERT_NE(nullptr, context);
|
||||
|
||||
devQueue = DeviceQueue::create(context, device,
|
||||
*properties,
|
||||
errcodeRet);
|
||||
|
||||
ASSERT_NE(nullptr, devQueue);
|
||||
}
|
||||
void TearDown() override {
|
||||
delete devQueue;
|
||||
delete context;
|
||||
delete device;
|
||||
ExecutionModelKernelFixture::TearDown();
|
||||
}
|
||||
|
||||
Device *device;
|
||||
DeviceQueue *devQueue;
|
||||
MockContext *context;
|
||||
};
|
||||
|
||||
HWTEST_P(DeviceQueueHwWithKernel, setupIndirectState) {
|
||||
if (std::string(pPlatform->getDevice(0)->getDeviceInfo().clVersion).find("OpenCL 2.") != std::string::npos) {
|
||||
EXPECT_TRUE(pKernel->isParentKernel);
|
||||
|
||||
pKernel->createReflectionSurface();
|
||||
|
||||
auto *devQueueHw = castToObject<DeviceQueueHw<FamilyType>>(devQueue);
|
||||
|
||||
ASSERT_NE(nullptr, devQueueHw);
|
||||
auto dsh = devQueueHw->getIndirectHeap(IndirectHeap::DYNAMIC_STATE);
|
||||
ASSERT_NE(nullptr, dsh);
|
||||
|
||||
size_t instructionHeapSize = pKernel->getInstructionHeapSizeForExecutionModel();
|
||||
size_t surfaceStateHeapSize = KernelCommandsHelper<FamilyType>::template getSizeRequiredForExecutionModel<IndirectHeap::SURFACE_STATE>(const_cast<const Kernel &>(*pKernel));
|
||||
|
||||
auto ish = new IndirectHeap(alignedMalloc(instructionHeapSize, MemoryConstants::pageSize), instructionHeapSize);
|
||||
auto ssh = new IndirectHeap(alignedMalloc(surfaceStateHeapSize, MemoryConstants::pageSize), surfaceStateHeapSize);
|
||||
ASSERT_NE(nullptr, ish);
|
||||
auto usedBeforeISH = ish->getUsed();
|
||||
auto usedBeforeSSH = ssh->getUsed();
|
||||
auto usedBeforeDSH = dsh->getUsed();
|
||||
|
||||
devQueueHw->setupIndirectState(*ish, *ssh, pKernel, 1);
|
||||
auto usedAfterISH = ish->getUsed();
|
||||
auto usedAfterSSH = ssh->getUsed();
|
||||
auto usedAfterDSH = dsh->getUsed();
|
||||
|
||||
EXPECT_GE(instructionHeapSize, usedAfterISH - usedBeforeISH);
|
||||
EXPECT_GE(surfaceStateHeapSize, usedAfterSSH - usedBeforeSSH);
|
||||
|
||||
EXPECT_EQ(0u, usedAfterDSH - usedBeforeDSH);
|
||||
|
||||
alignedFree(ish->getBase());
|
||||
alignedFree(ssh->getBase());
|
||||
delete ish;
|
||||
delete ssh;
|
||||
}
|
||||
}
|
||||
|
||||
HWTEST_P(DeviceQueueHwWithKernel, setupIndirectStateSetsCorrectStartBlockID) {
|
||||
if (std::string(pPlatform->getDevice(0)->getDeviceInfo().clVersion).find("OpenCL 2.") != std::string::npos) {
|
||||
EXPECT_TRUE(pKernel->isParentKernel);
|
||||
|
||||
pKernel->createReflectionSurface();
|
||||
|
||||
auto *devQueueHw = castToObject<DeviceQueueHw<FamilyType>>(devQueue);
|
||||
ASSERT_NE(nullptr, devQueueHw);
|
||||
auto dsh = devQueueHw->getIndirectHeap(IndirectHeap::DYNAMIC_STATE);
|
||||
ASSERT_NE(nullptr, dsh);
|
||||
|
||||
size_t instructionHeapSize = pKernel->getInstructionHeapSizeForExecutionModel();
|
||||
size_t surfaceStateHeapSize = KernelCommandsHelper<FamilyType>::template getSizeRequiredForExecutionModel<IndirectHeap::SURFACE_STATE>(const_cast<const Kernel &>(*pKernel));
|
||||
|
||||
auto ish = new IndirectHeap(alignedMalloc(instructionHeapSize, MemoryConstants::pageSize), instructionHeapSize);
|
||||
auto ssh = new IndirectHeap(alignedMalloc(surfaceStateHeapSize, MemoryConstants::pageSize), surfaceStateHeapSize);
|
||||
|
||||
uint32_t parentCount = 4;
|
||||
|
||||
devQueueHw->setupIndirectState(*ish, *ssh, pKernel, parentCount);
|
||||
auto *igilQueue = reinterpret_cast<IGIL_CommandQueue *>(devQueueHw->getQueueBuffer()->getUnderlyingBuffer());
|
||||
|
||||
EXPECT_EQ(parentCount, igilQueue->m_controls.m_StartBlockID);
|
||||
|
||||
alignedFree(ish->getBase());
|
||||
alignedFree(ssh->getBase());
|
||||
delete ish;
|
||||
delete ssh;
|
||||
}
|
||||
}
|
||||
|
||||
HWTEST_P(DeviceQueueHwWithKernel, setupIndirectStateSetsCorrectDSHValues) {
|
||||
using GPGPU_WALKER = typename FamilyType::GPGPU_WALKER;
|
||||
|
||||
if (std::string(pPlatform->getDevice(0)->getDeviceInfo().clVersion).find("OpenCL 2.") != std::string::npos) {
|
||||
EXPECT_TRUE(pKernel->isParentKernel);
|
||||
|
||||
pKernel->createReflectionSurface();
|
||||
|
||||
MockContext mockContext;
|
||||
MockDeviceQueueHw<FamilyType> *devQueueHw = new MockDeviceQueueHw<FamilyType>(&mockContext, device, deviceQueueProperties::minimumProperties[0]);
|
||||
ASSERT_NE(nullptr, devQueueHw);
|
||||
auto dsh = devQueueHw->getIndirectHeap(IndirectHeap::DYNAMIC_STATE);
|
||||
ASSERT_NE(nullptr, dsh);
|
||||
|
||||
size_t instructionHeapSize = pKernel->getInstructionHeapSizeForExecutionModel();
|
||||
size_t surfaceStateHeapSize = KernelCommandsHelper<FamilyType>::template getSizeRequiredForExecutionModel<IndirectHeap::SURFACE_STATE>(const_cast<const Kernel &>(*pKernel));
|
||||
|
||||
auto ish = new IndirectHeap(alignedMalloc(instructionHeapSize, MemoryConstants::pageSize), instructionHeapSize);
|
||||
auto ssh = new IndirectHeap(alignedMalloc(surfaceStateHeapSize, MemoryConstants::pageSize), surfaceStateHeapSize);
|
||||
|
||||
uint32_t parentCount = 1;
|
||||
|
||||
devQueueHw->setupIndirectState(*ish, *ssh, pKernel, parentCount);
|
||||
auto *igilQueue = reinterpret_cast<IGIL_CommandQueue *>(devQueueHw->getQueueBuffer()->getUnderlyingBuffer());
|
||||
|
||||
EXPECT_EQ(igilQueue->m_controls.m_DynamicHeapStart, devQueueHw->offsetDsh + alignUp((uint32_t)pKernel->getDynamicStateHeapSize(), GPGPU_WALKER::INDIRECTDATASTARTADDRESS_ALIGN_SIZE));
|
||||
EXPECT_EQ(igilQueue->m_controls.m_DynamicHeapSizeInBytes, (uint32_t)devQueueHw->getDshBuffer()->getUnderlyingBufferSize());
|
||||
EXPECT_EQ(igilQueue->m_controls.m_CurrentDSHoffset, devQueueHw->offsetDsh + alignUp((uint32_t)pKernel->getDynamicStateHeapSize(), GPGPU_WALKER::INDIRECTDATASTARTADDRESS_ALIGN_SIZE));
|
||||
EXPECT_EQ(igilQueue->m_controls.m_ParentDSHOffset, devQueueHw->offsetDsh);
|
||||
|
||||
alignedFree(ish->getBase());
|
||||
alignedFree(ssh->getBase());
|
||||
delete ish;
|
||||
delete ssh;
|
||||
delete devQueueHw;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *binaryFile = "simple_block_kernel";
|
||||
static const char *KernelNames[] = {"kernel_reflection", "simple_block_kernel"};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(DeviceQueueHwWithKernel,
|
||||
DeviceQueueHwWithKernel,
|
||||
::testing::Combine(
|
||||
::testing::Values(binaryFile),
|
||||
::testing::ValuesIn(KernelNames)));
|
||||
|
||||
typedef testing::Test TheSimplestDeviceQueueFixture;
|
||||
|
||||
HWTEST_F(TheSimplestDeviceQueueFixture, resetDeviceQueueSetEarlyReturnValues) {
|
||||
|
||||
DebugManagerStateRestore dbgRestorer;
|
||||
|
||||
DebugManager.flags.SchedulerSimulationReturnInstance.set(3);
|
||||
|
||||
MockDevice *device = Device::create<MockDevice>(platformDevices[0]);
|
||||
MockContext context;
|
||||
MockDeviceQueueHw<FamilyType> *mockDeviceQueueHw = new MockDeviceQueueHw<FamilyType>(&context, device, deviceQueueProperties::minimumProperties[0]);
|
||||
|
||||
mockDeviceQueueHw->resetDeviceQueue();
|
||||
|
||||
EXPECT_EQ(3u, mockDeviceQueueHw->getIgilQueue()->m_controls.m_SchedulerEarlyReturn);
|
||||
EXPECT_EQ(0u, mockDeviceQueueHw->getIgilQueue()->m_controls.m_SchedulerEarlyReturnCounter);
|
||||
|
||||
delete mockDeviceQueueHw;
|
||||
delete device;
|
||||
}
|
||||
350
unit_tests/device_queue/device_queue_tests.cpp
Normal file
350
unit_tests/device_queue/device_queue_tests.cpp
Normal file
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "unit_tests/fixtures/device_host_queue_fixture.h"
|
||||
#include "unit_tests/mocks/mock_context.h"
|
||||
#include "unit_tests/mocks/mock_kernel.h"
|
||||
#include "unit_tests/mocks/mock_program.h"
|
||||
#include "runtime/device/device_info.h"
|
||||
#include "runtime/helpers/dispatch_info.h"
|
||||
|
||||
#include "matchers.h"
|
||||
|
||||
using namespace OCLRT;
|
||||
using namespace DeviceHostQueue;
|
||||
|
||||
TEST(DeviceQueueSimpleTest, setupExecutionModelDispatchDoesNothing) {
|
||||
DeviceQueue devQueue;
|
||||
char buffer[20];
|
||||
|
||||
memset(buffer, 1, 20);
|
||||
|
||||
size_t size = 20;
|
||||
IndirectHeap ih(buffer, size);
|
||||
IndirectHeap ssh(buffer, size);
|
||||
devQueue.setupExecutionModelDispatch(ih, ssh, nullptr, 0, 0, 0);
|
||||
|
||||
EXPECT_EQ(0u, ih.getUsed());
|
||||
EXPECT_EQ(0u, ssh.getUsed());
|
||||
|
||||
for (uint32_t i = 0; i < 20; i++) {
|
||||
EXPECT_EQ(1, buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DeviceQueueSimpleTest, nonUsedBaseMethods) {
|
||||
DeviceQueue devQueue;
|
||||
devQueue.resetDeviceQueue();
|
||||
EXPECT_EQ(nullptr, devQueue.getIndirectHeap(IndirectHeap::DYNAMIC_STATE));
|
||||
}
|
||||
|
||||
class DeviceQueueTest : public DeviceHostQueueFixture<DeviceQueue> {
|
||||
public:
|
||||
using BaseClass = DeviceHostQueueFixture<DeviceQueue>;
|
||||
void SetUp() override {
|
||||
BaseClass::SetUp();
|
||||
device = castToObject<Device>(devices[0]);
|
||||
ASSERT_NE(device, nullptr);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
BaseClass::TearDown();
|
||||
}
|
||||
|
||||
void checkQueueBuffer(cl_uint expedtedSize) {
|
||||
auto alignedExpectedSize = alignUp(expedtedSize, MemoryConstants::pageSize);
|
||||
EXPECT_EQ(deviceQueue->getQueueSize(), expedtedSize);
|
||||
ASSERT_NE(deviceQueue->getQueueBuffer(), nullptr);
|
||||
EXPECT_EQ(deviceQueue->getQueueBuffer()->getUnderlyingBufferSize(), alignedExpectedSize);
|
||||
}
|
||||
|
||||
DeviceQueue *deviceQueue;
|
||||
Device *device;
|
||||
};
|
||||
|
||||
TEST_F(DeviceQueueTest, createDeviceQueueWhenNoDeviceQueueIsSupported) {
|
||||
auto maxOnDeviceQueues = device->getDeviceInfo().maxOnDeviceQueues;
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = 0;
|
||||
|
||||
auto deviceQueue = createQueueObject();
|
||||
EXPECT_EQ(deviceQueue, nullptr);
|
||||
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = maxOnDeviceQueues;
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueTest, createDeviceQueuesWhenSingleDeviceQueueIsSupported) {
|
||||
auto maxOnDeviceQueues = device->getDeviceInfo().maxOnDeviceQueues;
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = 1;
|
||||
|
||||
auto deviceQueue1 = createQueueObject();
|
||||
ASSERT_NE(deviceQueue1, nullptr);
|
||||
EXPECT_EQ(deviceQueue1->getReference(), 1);
|
||||
|
||||
auto deviceQueue2 = createQueueObject();
|
||||
EXPECT_EQ(deviceQueue2, nullptr);
|
||||
|
||||
delete deviceQueue1;
|
||||
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = maxOnDeviceQueues;
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueTest, createDeviceQueuesWhenMultipleDeviceQueuesAreSupported) {
|
||||
auto maxOnDeviceQueues = device->getDeviceInfo().maxOnDeviceQueues;
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = 2;
|
||||
|
||||
auto deviceQueue1 = createQueueObject();
|
||||
ASSERT_NE(deviceQueue1, nullptr);
|
||||
EXPECT_EQ(deviceQueue1->getReference(), 1);
|
||||
|
||||
auto deviceQueue2 = createQueueObject();
|
||||
ASSERT_NE(deviceQueue2, nullptr);
|
||||
EXPECT_EQ(deviceQueue2->getReference(), 1);
|
||||
|
||||
EXPECT_NE(deviceQueue2, deviceQueue1);
|
||||
|
||||
delete deviceQueue1;
|
||||
delete deviceQueue2;
|
||||
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = maxOnDeviceQueues;
|
||||
}
|
||||
|
||||
typedef DeviceQueueTest DeviceQueueBuffer;
|
||||
|
||||
TEST_F(DeviceQueueBuffer, setPrefferedSizeWhenNoPropertyGiven) {
|
||||
auto &deviceInfo = device->getDeviceInfo();
|
||||
deviceQueue = createQueueObject(); // only minimal properties
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
checkQueueBuffer(deviceInfo.queueOnDevicePreferredSize);
|
||||
deviceQueue->release();
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueBuffer, setPrefferedSizeWhenInvalidPropertyGiven) {
|
||||
cl_queue_properties properties[5] = {CL_QUEUE_PROPERTIES, deviceQueueProperties::minimumProperties[1],
|
||||
CL_QUEUE_SIZE, 0, 0};
|
||||
auto &deviceInfo = device->getDeviceInfo();
|
||||
|
||||
deviceQueue = createQueueObject(properties); // zero size
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
checkQueueBuffer(deviceInfo.queueOnDevicePreferredSize);
|
||||
delete deviceQueue;
|
||||
|
||||
properties[3] = static_cast<cl_queue_properties>(deviceInfo.queueOnDeviceMaxSize + 1);
|
||||
deviceQueue = createQueueObject(properties); // greater than max
|
||||
EXPECT_EQ(deviceQueue, nullptr);
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueBuffer, setValidQueueSize) {
|
||||
auto &deviceInfo = device->getDeviceInfo();
|
||||
cl_uint validSize = deviceInfo.queueOnDevicePreferredSize - 1;
|
||||
cl_queue_properties properties[5] = {CL_QUEUE_PROPERTIES, deviceQueueProperties::minimumProperties[1],
|
||||
CL_QUEUE_SIZE, static_cast<cl_queue_properties>(validSize),
|
||||
0};
|
||||
|
||||
EXPECT_NE(validSize, alignUp(validSize, MemoryConstants::pageSize)); // create aligned
|
||||
deviceQueue = createQueueObject(properties);
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
checkQueueBuffer(validSize);
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueBuffer, initValues) {
|
||||
auto &deviceInfo = device->getDeviceInfo();
|
||||
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
IGIL_CommandQueue expectedIgilCmdQueue = getExpectedInitIgilCmdQueue(deviceQueue);
|
||||
EXPECT_EQ(static_cast<uint32_t>(deviceQueue->isProfilingEnabled()), expectedIgilCmdQueue.m_controls.m_IsProfilingEnabled);
|
||||
|
||||
IGIL_EventPool expectedIgilEventPool = {0, 0, 0};
|
||||
expectedIgilEventPool.m_head = 0;
|
||||
expectedIgilEventPool.m_size = deviceInfo.maxOnDeviceEvents;
|
||||
|
||||
// initialized header
|
||||
EXPECT_EQ(0, memcmp(deviceQueue->getQueueBuffer()->getUnderlyingBuffer(),
|
||||
&expectedIgilCmdQueue, sizeof(IGIL_CommandQueue)));
|
||||
|
||||
EXPECT_EQ(0, memcmp(deviceQueue->getEventPoolBuffer()->getUnderlyingBuffer(),
|
||||
&expectedIgilEventPool, sizeof(IGIL_EventPool)));
|
||||
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
typedef DeviceQueueTest DeviceQueueStackBuffer;
|
||||
|
||||
TEST_F(DeviceQueueStackBuffer, allocateResourcesZeroesStackBufferAndQueueStorage) {
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
EXPECT_THAT(deviceQueue->getQueueStorageBuffer()->getUnderlyingBuffer(), MemoryZeroed(deviceQueue->getQueueStorageBuffer()->getUnderlyingBufferSize()));
|
||||
EXPECT_THAT(deviceQueue->getStackBuffer()->getUnderlyingBuffer(), MemoryZeroed(deviceQueue->getStackBuffer()->getUnderlyingBufferSize()));
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueStackBuffer, initAllocation) {
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
auto maxEnqueue = deviceQueue->getQueueSize() / sizeof(IGIL_CommandHeader);
|
||||
//stack can hold at most 3 full loads of commands
|
||||
auto expectedStackSize = maxEnqueue * sizeof(uint32_t) * 3;
|
||||
expectedStackSize = alignUp(expectedStackSize, MemoryConstants::pageSize);
|
||||
|
||||
ASSERT_NE(deviceQueue->getStackBuffer(), nullptr);
|
||||
EXPECT_EQ(deviceQueue->getStackBuffer()->getUnderlyingBufferSize(), expectedStackSize);
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
typedef DeviceQueueTest DeviceQueueStorageBuffer;
|
||||
|
||||
TEST_F(DeviceQueueStorageBuffer, initAllocation) {
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
auto expectedStorageSize = deviceQueue->getQueueBuffer()->getUnderlyingBufferSize() * 2;
|
||||
expectedStorageSize = alignUp(expectedStorageSize, MemoryConstants::pageSize);
|
||||
|
||||
ASSERT_NE(deviceQueue->getQueueStorageBuffer(), nullptr);
|
||||
EXPECT_EQ(deviceQueue->getQueueStorageBuffer()->getUnderlyingBufferSize(), expectedStorageSize);
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
typedef DeviceQueueTest DefaultDeviceQueue;
|
||||
|
||||
TEST_F(DefaultDeviceQueue, createOnlyOneDefaultDeviceQueueWhenSingleDeviceQueueIsSupported) {
|
||||
cl_queue_properties properties[] = {CL_QUEUE_PROPERTIES, CL_QUEUE_ON_DEVICE_DEFAULT, 0, 0, 0};
|
||||
|
||||
auto maxOnDeviceQueues = device->getDeviceInfo().maxOnDeviceQueues;
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = 1;
|
||||
|
||||
auto deviceQueue1 = createQueueObject(properties);
|
||||
ASSERT_NE(deviceQueue1, nullptr);
|
||||
|
||||
EXPECT_EQ(pContext->getDefaultDeviceQueue(), deviceQueue1);
|
||||
EXPECT_EQ(deviceQueue1->getReference(), 1);
|
||||
|
||||
auto deviceQueue2 = createQueueObject(properties);
|
||||
ASSERT_NE(deviceQueue2, nullptr);
|
||||
|
||||
EXPECT_EQ(deviceQueue2, deviceQueue1);
|
||||
|
||||
EXPECT_EQ(pContext->getDefaultDeviceQueue(), deviceQueue1);
|
||||
EXPECT_EQ(deviceQueue1->getReference(), 2);
|
||||
|
||||
delete deviceQueue1;
|
||||
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = maxOnDeviceQueues;
|
||||
}
|
||||
|
||||
TEST_F(DefaultDeviceQueue, createOnlyOneDefaultDeviceQueueWhenMultipleDeviceQueuesAreSupported) {
|
||||
cl_queue_properties properties[] = {CL_QUEUE_PROPERTIES, CL_QUEUE_ON_DEVICE_DEFAULT, 0, 0, 0};
|
||||
|
||||
auto maxOnDeviceQueues = device->getDeviceInfo().maxOnDeviceQueues;
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = 2;
|
||||
|
||||
auto deviceQueue1 = createQueueObject(properties);
|
||||
ASSERT_NE(deviceQueue1, nullptr);
|
||||
|
||||
EXPECT_EQ(pContext->getDefaultDeviceQueue(), deviceQueue1);
|
||||
EXPECT_EQ(deviceQueue1->getReference(), 1);
|
||||
|
||||
auto deviceQueue2 = createQueueObject(properties);
|
||||
ASSERT_NE(deviceQueue2, nullptr);
|
||||
|
||||
EXPECT_EQ(deviceQueue2, deviceQueue1);
|
||||
|
||||
EXPECT_EQ(pContext->getDefaultDeviceQueue(), deviceQueue1);
|
||||
EXPECT_EQ(deviceQueue1->getReference(), 2);
|
||||
|
||||
delete deviceQueue1;
|
||||
|
||||
const_cast<DeviceInfo *>(&device->getDeviceInfo())->maxOnDeviceQueues = maxOnDeviceQueues;
|
||||
}
|
||||
|
||||
typedef DeviceQueueTest DeviceQueueEventPool;
|
||||
|
||||
TEST_F(DeviceQueueEventPool, poolBufferSize) {
|
||||
auto &deviceInfo = device->getDeviceInfo();
|
||||
|
||||
// number of events + event pool representation
|
||||
auto expectedSize = static_cast<uint32_t>(deviceInfo.maxOnDeviceEvents * sizeof(IGIL_DeviceEvent) +
|
||||
sizeof(IGIL_EventPool));
|
||||
expectedSize = alignUp(expectedSize, MemoryConstants::pageSize);
|
||||
|
||||
auto deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
ASSERT_NE(deviceQueue->getEventPoolBuffer(), nullptr);
|
||||
EXPECT_EQ(deviceQueue->getEventPoolBuffer()->getUnderlyingBufferSize(), expectedSize);
|
||||
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueTest, sizeOfDshBuffer) {
|
||||
deviceQueue = createQueueObject();
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
|
||||
ASSERT_NE(deviceQueue->getDshBuffer(), nullptr);
|
||||
auto dshBufferSize = deviceQueue->getDshBuffer()->getUnderlyingBufferSize();
|
||||
|
||||
EXPECT_LE(761856u, dshBufferSize);
|
||||
delete deviceQueue;
|
||||
}
|
||||
|
||||
TEST_F(DeviceQueueTest, dispatchScheduler) {
|
||||
DeviceQueue devQueue;
|
||||
MockContext context;
|
||||
MockProgram program;
|
||||
CommandQueue cmdQ(nullptr, nullptr, 0);
|
||||
KernelInfo info;
|
||||
MockSchedulerKernel *kernel = new MockSchedulerKernel(&program, info, *device);
|
||||
devQueue.dispatchScheduler(cmdQ, *kernel);
|
||||
delete kernel;
|
||||
}
|
||||
|
||||
class DeviceQueueUnderTest : public DeviceQueue {
|
||||
public:
|
||||
DeviceQueueUnderTest() : DeviceQueue(){};
|
||||
|
||||
void verifyConstructor() {
|
||||
EXPECT_EQ(nullptr, context);
|
||||
EXPECT_EQ(nullptr, device);
|
||||
EXPECT_EQ(0u, commandQueueProperties);
|
||||
EXPECT_EQ(0u, queueSize);
|
||||
EXPECT_EQ(nullptr, queueBuffer);
|
||||
EXPECT_EQ(nullptr, eventPoolBuffer);
|
||||
EXPECT_EQ(nullptr, slbBuffer);
|
||||
EXPECT_EQ(nullptr, stackBuffer);
|
||||
EXPECT_EQ(nullptr, queueStorageBuffer);
|
||||
EXPECT_EQ(nullptr, dshBuffer);
|
||||
EXPECT_EQ(nullptr, debugQueue);
|
||||
EXPECT_EQ(nullptr, debugData);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(DeviceQueue, GivenDeviceQueueWhenCreatedThenProperlyInitialized) {
|
||||
DeviceQueueUnderTest deviceQueue;
|
||||
deviceQueue.verifyConstructor();
|
||||
}
|
||||
126
unit_tests/device_queue/get_device_queue_info_tests.cpp
Normal file
126
unit_tests/device_queue/get_device_queue_info_tests.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "runtime/context/context.h"
|
||||
#include "unit_tests/fixtures/device_host_queue_fixture.h"
|
||||
|
||||
using namespace OCLRT;
|
||||
using namespace DeviceHostQueue;
|
||||
|
||||
class GetDeviceQueueInfoTest : public DeviceHostQueueFixture<DeviceQueue> {
|
||||
public:
|
||||
using BaseClass = DeviceHostQueueFixture<DeviceQueue>;
|
||||
|
||||
void SetUp() override {
|
||||
BaseClass::SetUp();
|
||||
deviceQueue = createQueueObject(deviceQueueProperties::allProperties);
|
||||
ASSERT_NE(deviceQueue, nullptr);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
if (deviceQueue)
|
||||
delete deviceQueue;
|
||||
BaseClass::TearDown();
|
||||
}
|
||||
|
||||
DeviceQueue *deviceQueue;
|
||||
};
|
||||
|
||||
TEST_F(GetDeviceQueueInfoTest, context) {
|
||||
cl_context contextReturned = nullptr;
|
||||
|
||||
retVal = deviceQueue->getCommandQueueInfo(
|
||||
CL_QUEUE_CONTEXT,
|
||||
sizeof(contextReturned),
|
||||
&contextReturned,
|
||||
nullptr);
|
||||
ASSERT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ((cl_context)pContext, contextReturned);
|
||||
}
|
||||
|
||||
TEST_F(GetDeviceQueueInfoTest, device) {
|
||||
cl_device_id deviceExpected = devices[0];
|
||||
cl_device_id deviceIdReturned = nullptr;
|
||||
|
||||
retVal = deviceQueue->getCommandQueueInfo(
|
||||
CL_QUEUE_DEVICE,
|
||||
sizeof(deviceIdReturned),
|
||||
&deviceIdReturned,
|
||||
nullptr);
|
||||
ASSERT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(deviceExpected, deviceIdReturned);
|
||||
}
|
||||
|
||||
TEST_F(GetDeviceQueueInfoTest, queueProperties) {
|
||||
cl_command_queue_properties propertiesReturned = 0;
|
||||
|
||||
retVal = deviceQueue->getCommandQueueInfo(
|
||||
CL_QUEUE_PROPERTIES,
|
||||
sizeof(propertiesReturned),
|
||||
&propertiesReturned,
|
||||
nullptr);
|
||||
ASSERT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(deviceQueueProperties::allProperties[1], propertiesReturned);
|
||||
}
|
||||
|
||||
TEST_F(GetDeviceQueueInfoTest, queueSize) {
|
||||
cl_uint queueSizeReturned = 0;
|
||||
|
||||
retVal = deviceQueue->getCommandQueueInfo(
|
||||
CL_QUEUE_SIZE,
|
||||
sizeof(queueSizeReturned),
|
||||
&queueSizeReturned,
|
||||
nullptr);
|
||||
ASSERT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(deviceQueue->getQueueSize(), queueSizeReturned);
|
||||
}
|
||||
|
||||
// OCL 2.1
|
||||
TEST_F(GetDeviceQueueInfoTest, queueDeviceDefault) {
|
||||
cl_command_queue commandQueueReturned = nullptr;
|
||||
|
||||
retVal = deviceQueue->getCommandQueueInfo(
|
||||
CL_QUEUE_DEVICE_DEFAULT,
|
||||
sizeof(commandQueueReturned),
|
||||
&commandQueueReturned,
|
||||
nullptr);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
// 1 device queue is supported which is default
|
||||
EXPECT_EQ(deviceQueue, commandQueueReturned);
|
||||
}
|
||||
|
||||
TEST_F(GetDeviceQueueInfoTest, profiling) {
|
||||
EXPECT_TRUE(deviceQueue->isProfilingEnabled());
|
||||
}
|
||||
|
||||
TEST_F(GetDeviceQueueInfoTest, invalidParameter) {
|
||||
uint32_t tempValue = 0;
|
||||
|
||||
retVal = deviceQueue->getCommandQueueInfo(
|
||||
static_cast<cl_command_queue_info>(0),
|
||||
sizeof(tempValue),
|
||||
&tempValue,
|
||||
nullptr);
|
||||
EXPECT_EQ(tempValue, 0u);
|
||||
EXPECT_EQ(CL_INVALID_VALUE, retVal);
|
||||
}
|
||||
Reference in New Issue
Block a user