L0 Debug- Create generic topologyMap interface

Move Linux DebugSession thread conversion functions up to
DebugSessionImp to allow reuse in windows implementation

Signed-off-by: Yates, Brandon <brandon.yates@intel.com>
This commit is contained in:
Yates, Brandon
2022-10-04 19:26:23 +00:00
committed by Compute-Runtime-Automation
parent 453cd97c14
commit 44894c1fdf
15 changed files with 310 additions and 247 deletions

View File

@@ -7,6 +7,7 @@
#pragma once
#include "shared/source/debugger/debugger_l0.h"
#include "shared/source/helpers/topology_map.h"
#include "shared/source/os_interface/os_thread.h"
#include "level_zero/tools/source/debug/eu_thread.h"
@@ -73,6 +74,8 @@ struct DebugSession : _zet_debug_session_handle_t {
static void printBitmask(uint8_t *bitmask, size_t bitmaskSize);
MOCKABLE_VIRTUAL const NEO::TopologyMap &getTopologyMap();
virtual uint32_t getDeviceIndexFromApiThread(ze_device_thread_t thread);
virtual ze_device_thread_t convertToPhysicalWithinDevice(ze_device_thread_t thread, uint32_t deviceIndex);
virtual EuThread::ThreadId convertToThreadId(ze_device_thread_t thread);

View File

@@ -21,6 +21,10 @@ namespace L0 {
DebugSession::DebugSession(const zet_debug_config_t &config, Device *device) : connectedDevice(device) {
}
const NEO::TopologyMap &DebugSession::getTopologyMap() {
return connectedDevice->getOsInterface().getDriverModel()->getTopologyMap();
};
void DebugSession::createEuThreads() {
if (connectedDevice) {
@@ -62,60 +66,74 @@ void DebugSession::createEuThreads() {
}
uint32_t DebugSession::getDeviceIndexFromApiThread(ze_device_thread_t thread) {
auto &hwInfo = connectedDevice->getHwInfo();
auto deviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices());
auto deviceBitfield = connectedDevice->getNEODevice()->getDeviceBitfield();
uint32_t deviceIndex = Math::log2(static_cast<uint32_t>(deviceBitfield.to_ulong()));
auto deviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices());
const auto &topologyMap = getTopologyMap();
if (connectedDevice->getNEODevice()->isSubDevice()) {
deviceIndex = Math::log2(static_cast<uint32_t>(deviceBitfield.to_ulong()));
} else {
if (thread.slice != UINT32_MAX) {
deviceIndex = thread.slice / hwInfo.gtSystemInfo.SliceCount;
} else if (deviceCount > 1) {
return deviceIndex;
}
if (deviceCount > 1) {
if (thread.slice == UINT32_MAX) {
deviceIndex = UINT32_MAX;
} else {
uint32_t sliceId = thread.slice;
for (uint32_t i = 0; i < topologyMap.size(); i++) {
if (deviceBitfield.test(i)) {
if (sliceId < topologyMap.at(i).sliceIndices.size()) {
deviceIndex = i;
}
sliceId = sliceId - static_cast<uint32_t>(topologyMap.at(i).sliceIndices.size());
}
}
}
}
return deviceIndex;
}
ze_device_thread_t DebugSession::convertToPhysicalWithinDevice(ze_device_thread_t thread, uint32_t deviceIndex) {
auto &hwInfo = connectedDevice->getHwInfo();
auto deviceImp = static_cast<DeviceImp *>(connectedDevice);
const auto &topologyMap = getTopologyMap();
// set slice for single slice config to allow subslice remapping
auto mapping = topologyMap.find(deviceIndex);
if (thread.slice == UINT32_MAX && mapping != topologyMap.end() && mapping->second.sliceIndices.size() == 1) {
thread.slice = 0;
}
if (thread.slice != UINT32_MAX) {
thread.slice = thread.slice % hwInfo.gtSystemInfo.SliceCount;
if (thread.subslice != UINT32_MAX) {
deviceImp->toPhysicalSliceId(topologyMap, thread.slice, thread.subslice, deviceIndex);
} else {
uint32_t dummy = 0;
deviceImp->toPhysicalSliceId(topologyMap, thread.slice, dummy, deviceIndex);
}
}
return thread;
}
EuThread::ThreadId DebugSession::convertToThreadId(ze_device_thread_t thread) {
auto &hwInfo = connectedDevice->getHwInfo();
auto deviceBitfield = connectedDevice->getNEODevice()->getDeviceBitfield();
UNRECOVERABLE_IF(!isSingleThread(thread));
auto deviceImp = static_cast<DeviceImp *>(connectedDevice);
UNRECOVERABLE_IF(!DebugSession::isSingleThread(thread));
uint32_t deviceIndex = 0;
if (connectedDevice->getNEODevice()->isSubDevice()) {
deviceIndex = Math::log2(static_cast<uint32_t>(deviceBitfield.to_ulong()));
} else {
deviceIndex = thread.slice / hwInfo.gtSystemInfo.SliceCount;
thread.slice = thread.slice % hwInfo.gtSystemInfo.SliceCount;
}
deviceImp->toPhysicalSliceId(getTopologyMap(), thread.slice, thread.subslice, deviceIndex);
EuThread::ThreadId threadId(deviceIndex, thread.slice, thread.subslice, thread.eu, thread.thread);
return threadId;
}
ze_device_thread_t DebugSession::convertToApi(EuThread::ThreadId threadId) {
auto &hwInfo = connectedDevice->getHwInfo();
auto deviceImp = static_cast<DeviceImp *>(connectedDevice);
ze_device_thread_t thread = {static_cast<uint32_t>(threadId.slice), static_cast<uint32_t>(threadId.subslice), static_cast<uint32_t>(threadId.eu), static_cast<uint32_t>(threadId.thread)};
deviceImp->toApiSliceId(getTopologyMap(), thread.slice, thread.subslice, threadId.tileIndex);
if (!connectedDevice->getNEODevice()->isSubDevice()) {
thread.slice = thread.slice + static_cast<uint32_t>(threadId.tileIndex * hwInfo.gtSystemInfo.SliceCount);
}
return thread;
}

View File

@@ -1835,78 +1835,6 @@ uint64_t DebugSessionLinux::getContextStateSaveAreaGpuVa(uint64_t memoryHandle)
return bindInfo->second.gpuVa;
}
uint32_t DebugSessionLinux::getDeviceIndexFromApiThread(ze_device_thread_t thread) {
auto deviceBitfield = connectedDevice->getNEODevice()->getDeviceBitfield();
uint32_t deviceIndex = Math::log2(static_cast<uint32_t>(deviceBitfield.to_ulong()));
auto deviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices());
const auto &topologyMap = DrmHelper::getTopologyMap(connectedDevice);
if (connectedDevice->getNEODevice()->isSubDevice()) {
return deviceIndex;
}
if (deviceCount > 1) {
if (thread.slice == UINT32_MAX) {
deviceIndex = UINT32_MAX;
} else {
uint32_t sliceId = thread.slice;
for (uint32_t i = 0; i < topologyMap.size(); i++) {
if (deviceBitfield.test(i)) {
if (sliceId < topologyMap.at(i).sliceIndices.size()) {
deviceIndex = i;
}
sliceId = sliceId - static_cast<uint32_t>(topologyMap.at(i).sliceIndices.size());
}
}
}
}
return deviceIndex;
}
ze_device_thread_t DebugSessionLinux::convertToPhysicalWithinDevice(ze_device_thread_t thread, uint32_t deviceIndex) {
auto deviceImp = static_cast<DeviceImp *>(connectedDevice);
const auto &topologyMap = DrmHelper::getTopologyMap(connectedDevice);
// set slice for single slice config to allow subslice remapping
auto mapping = topologyMap.find(deviceIndex);
if (thread.slice == UINT32_MAX && mapping != topologyMap.end() && mapping->second.sliceIndices.size() == 1) {
thread.slice = 0;
}
if (thread.slice != UINT32_MAX) {
if (thread.subslice != UINT32_MAX) {
deviceImp->toPhysicalSliceId(topologyMap, thread.slice, thread.subslice, deviceIndex);
} else {
uint32_t dummy = 0;
deviceImp->toPhysicalSliceId(topologyMap, thread.slice, dummy, deviceIndex);
}
}
return thread;
}
EuThread::ThreadId DebugSessionLinux::convertToThreadId(ze_device_thread_t thread) {
auto deviceImp = static_cast<DeviceImp *>(connectedDevice);
UNRECOVERABLE_IF(!DebugSession::isSingleThread(thread));
uint32_t deviceIndex = 0;
deviceImp->toPhysicalSliceId(DrmHelper::getTopologyMap(connectedDevice), thread.slice, thread.subslice, deviceIndex);
EuThread::ThreadId threadId(deviceIndex, thread.slice, thread.subslice, thread.eu, thread.thread);
return threadId;
}
ze_device_thread_t DebugSessionLinux::convertToApi(EuThread::ThreadId threadId) {
auto deviceImp = static_cast<DeviceImp *>(connectedDevice);
ze_device_thread_t thread = {static_cast<uint32_t>(threadId.slice), static_cast<uint32_t>(threadId.subslice), static_cast<uint32_t>(threadId.eu), static_cast<uint32_t>(threadId.thread)};
deviceImp->toApiSliceId(DrmHelper::getTopologyMap(connectedDevice), thread.slice, thread.subslice, threadId.tileIndex);
return thread;
}
void TileDebugSessionLinux::readStateSaveAreaHeader() {
const auto header = rootDebugSession->getStateSaveAreaHeader();

View File

@@ -43,11 +43,6 @@ struct DebugSessionLinux : DebugSessionImp {
ze_result_t writeMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) override;
ze_result_t acknowledgeEvent(const zet_debug_event_t *event) override;
uint32_t getDeviceIndexFromApiThread(ze_device_thread_t thread) override;
ze_device_thread_t convertToPhysicalWithinDevice(ze_device_thread_t thread, uint32_t deviceIndex) override;
EuThread::ThreadId convertToThreadId(ze_device_thread_t thread) override;
ze_device_thread_t convertToApi(EuThread::ThreadId threadId) override;
struct IoctlHandler {
MOCKABLE_VIRTUAL ~IoctlHandler() = default;
MOCKABLE_VIRTUAL int ioctl(int fd, unsigned long request, void *arg) {

View File

@@ -35,9 +35,4 @@ const NEO::EngineClassInstance *DrmHelper::getEngineInstance(Device *device, uin
return engineInfo->getEngineInstance(tile, engineType);
}
const NEO::TopologyMap &DrmHelper::getTopologyMap(Device *device) {
auto drm = device->getOsInterface().getDriverModel()->as<NEO::Drm>();
return drm->getTopologyMap();
}
} // namespace L0

View File

@@ -24,7 +24,6 @@ struct DrmHelper {
static int getErrno(Device *device);
static uint32_t getEngineTileIndex(Device *device, const NEO::EngineClassInstance &engine);
static const NEO::EngineClassInstance *getEngineInstance(Device *device, uint32_t tile, aub_stream::EngineType engineType);
static const NEO::TopologyMap &getTopologyMap(Device *device);
};
} // namespace L0

View File

@@ -68,6 +68,9 @@ struct MockDebugSession : public L0::DebugSessionImp {
MockDebugSession(const zet_debug_config_t &config, L0::Device *device) : MockDebugSession(config, device, true) {}
MockDebugSession(const zet_debug_config_t &config, L0::Device *device, bool rootAttach) : DebugSessionImp(config, device) {
if (device) {
topologyMap = DebugSessionMock::buildMockTopology(device);
}
setAttachMode(rootAttach);
if (rootAttach) {
createEuThreads();
@@ -298,6 +301,12 @@ struct MockDebugSession : public L0::DebugSessionImp {
return L0::DebugSessionImp::getTimeDifferenceMilliseconds(time);
}
const NEO::TopologyMap &getTopologyMap() override {
return this->topologyMap;
}
NEO::TopologyMap topologyMap;
uint32_t interruptImpCalled = 0;
uint32_t resumeImpCalled = 0;
uint32_t resumeAccidentallyStoppedCalled = 0;

View File

@@ -329,8 +329,12 @@ TEST(DebugSession, givenApiThreadAndSingleTileWhenConvertingThenCorrectValuesRet
convertedThread = debugSession->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(0u, deviceIndex);
if (hwInfo.gtSystemInfo.SliceCount == 1) {
EXPECT_EQ(convertedThread.slice, 0u);
} else {
EXPECT_EQ(convertedThread.slice, thread.slice);
}
}
TEST(DebugSession, givenApiThreadAndSingleTileWhenGettingDeviceIndexThenCorrectIndexIsReturned) {
auto hwInfo = *NEO::defaultHwInfo.get();
@@ -498,6 +502,202 @@ TEST(DebugSession, GivenLogsDisabledWhenPrintBitmaskCalledThenBitmaskIsNotPrinte
EXPECT_EQ(0u, output.size());
}
TEST(DebugSession, WhenConvertingThreadIdsThenDeviceFunctionsAreCalled) {
auto hwInfo = *NEO::defaultHwInfo.get();
NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
Mock<L0::DeviceImp> deviceImp(neoDevice, neoDevice->getExecutionEnvironment());
auto sessionMock = std::make_unique<DebugSessionMock>(zet_debug_config_t{0x1234}, &deviceImp);
ASSERT_NE(nullptr, sessionMock);
ze_device_thread_t thread = {0, 0, 0, 0};
auto threadID = sessionMock->convertToThreadId(thread);
EXPECT_EQ(0u, threadID.tileIndex);
EXPECT_EQ(0u, threadID.slice);
EXPECT_EQ(0u, threadID.subslice);
EXPECT_EQ(0u, threadID.eu);
EXPECT_EQ(0u, threadID.thread);
auto apiThread = sessionMock->convertToApi(threadID);
EXPECT_EQ(0u, apiThread.slice);
EXPECT_EQ(0u, apiThread.subslice);
EXPECT_EQ(0u, apiThread.eu);
EXPECT_EQ(0u, apiThread.thread);
uint32_t deviceIndex = 1;
auto physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(0u, physicalThread.slice);
EXPECT_EQ(0u, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
thread.slice = UINT32_MAX;
physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(uint32_t(UINT32_MAX), physicalThread.slice);
EXPECT_EQ(0u, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
thread.slice = 0;
thread.subslice = UINT32_MAX;
thread.eu = 1;
thread.thread = 3;
physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(0u, physicalThread.slice);
EXPECT_EQ(uint32_t(UINT32_MAX), physicalThread.subslice);
EXPECT_EQ(1u, physicalThread.eu);
EXPECT_EQ(3u, physicalThread.thread);
}
TEST(DebugSessionTest, WhenConvertingThreadIDsForDeviceWithSingleSliceThenSubsliceIsCorrectlyRemapped) {
auto hwInfo = *NEO::defaultHwInfo.get();
hwInfo.gtSystemInfo.SliceCount = 2;
hwInfo.gtSystemInfo.SubSliceCount = 8;
NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
Mock<L0::DeviceImp> deviceImp(neoDevice, neoDevice->getExecutionEnvironment());
auto sessionMock = std::make_unique<DebugSessionMock>(zet_debug_config_t{0x1234}, &deviceImp);
ASSERT_NE(nullptr, sessionMock);
//fuse off first slice
sessionMock->topologyMap[0].sliceIndices.erase(sessionMock->topologyMap[0].sliceIndices.begin());
hwInfo.gtSystemInfo.SliceCount = 1;
sessionMock->topologyMap[0].subsliceIndices.push_back(2);
sessionMock->topologyMap[0].subsliceIndices.push_back(3);
ze_device_thread_t thread = {UINT32_MAX, 1, 0, 0};
uint32_t deviceIndex = 0;
auto physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, physicalThread.slice);
EXPECT_EQ(3u, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
thread.slice = 0;
physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, physicalThread.slice);
EXPECT_EQ(3u, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
}
TEST(DebugSessionTest, WhenConvertingThreadIDsForDeviceWithMultipleSlicesThenSubsliceIsNotRemapped) {
auto hwInfo = *NEO::defaultHwInfo.get();
hwInfo.gtSystemInfo.SliceCount = 8;
hwInfo.gtSystemInfo.SubSliceCount = 8;
NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
Mock<L0::DeviceImp> deviceImp(neoDevice, neoDevice->getExecutionEnvironment());
auto sessionMock = std::make_unique<DebugSessionMock>(zet_debug_config_t{0x1234}, &deviceImp);
ASSERT_NE(nullptr, sessionMock);
//fuse off first slice
sessionMock->topologyMap[0].sliceIndices.erase(sessionMock->topologyMap[0].sliceIndices.begin());
hwInfo.gtSystemInfo.SliceCount = 7;
ze_device_thread_t thread = {UINT32_MAX, 1, 0, 0};
uint32_t deviceIndex = 0;
auto physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(UINT32_MAX, physicalThread.slice);
EXPECT_EQ(thread.subslice, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
thread.slice = 0;
physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, physicalThread.slice);
EXPECT_EQ(thread.subslice, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
}
struct AffinityMaskMultipleSubdevices : MultipleDevicesWithCustomHwInfo {
void setUp() {
DebugManager.flags.ZE_AFFINITY_MASK.set("0.0,0.1,0.3");
MultipleDevicesWithCustomHwInfo::numSubDevices = 4;
MultipleDevicesWithCustomHwInfo::setUp();
}
void tearDown() {
MultipleDevicesWithCustomHwInfo::tearDown();
}
DebugManagerStateRestore restorer;
};
using AffinityMaskMultipleSubdevicesTest = Test<AffinityMaskMultipleSubdevices>;
TEST_F(AffinityMaskMultipleSubdevicesTest, givenApiThreadAndMultipleTilesWhenConvertingToPhysicalThenCorrectValuesReturned) {
L0::Device *device = driverHandle->devices[0];
auto deviceImp = static_cast<DeviceImp *>(device);
auto debugSession = std::make_unique<DebugSessionMock>(zet_debug_config_t{0x1234}, deviceImp);
ASSERT_NE(nullptr, debugSession);
ze_device_thread_t thread = {2 * sliceCount - 1, 0, 0, 0};
uint32_t deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(1u, deviceIndex);
auto convertedThread = debugSession->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(sliceCount - 1, convertedThread.slice);
EXPECT_EQ(thread.subslice, convertedThread.subslice);
EXPECT_EQ(thread.eu, convertedThread.eu);
EXPECT_EQ(thread.thread, convertedThread.thread);
thread = {3 * sliceCount - 1, 0, 0, 0};
deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(3u, deviceIndex);
convertedThread = debugSession->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(3u, deviceIndex);
EXPECT_EQ(sliceCount - 1, convertedThread.slice);
EXPECT_EQ(thread.subslice, convertedThread.subslice);
EXPECT_EQ(thread.eu, convertedThread.eu);
EXPECT_EQ(thread.thread, convertedThread.thread);
thread = {sliceCount - 1, 0, 0, 0};
deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(0u, deviceIndex);
convertedThread = debugSession->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(0u, deviceIndex);
EXPECT_EQ(sliceCount - 1, convertedThread.slice);
EXPECT_EQ(thread.subslice, convertedThread.subslice);
EXPECT_EQ(thread.eu, convertedThread.eu);
EXPECT_EQ(thread.thread, convertedThread.thread);
thread.slice = UINT32_MAX;
deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(UINT32_MAX, deviceIndex);
}
using DebugSessionMultiTile = Test<MultipleDevicesWithCustomHwInfo>;
TEST_F(DebugSessionMultiTile, givenApiThreadAndMultipleTilesWhenConvertingToPhysicalThenCorrectValueReturned) {

View File

@@ -93,7 +93,7 @@ TEST(IoctlHandler, GivenHandlerWhenMmapAndMunmapCalledThenRedirectedToSysCall) {
NEO::SysCalls::munmapFuncCalled = 0;
}
TEST(DebugSessionTest, GivenDebugSessionWhenExtractingCpuVaFromUuidThenCorrectCpuVaReturned) {
TEST(DebugSessionLinuxTest, GivenDebugSessionWhenExtractingCpuVaFromUuidThenCorrectCpuVaReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;
@@ -112,69 +112,7 @@ TEST(DebugSessionTest, GivenDebugSessionWhenExtractingCpuVaFromUuidThenCorrectCp
EXPECT_EQ(epxectedVa, va);
}
TEST(DebugSessionTest, WhenConvertingThreadIdsThenDeviceFunctionsAreCalled) {
auto hwInfo = *NEO::defaultHwInfo.get();
NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
auto mockDrm = new DrmQueryMock(*neoDevice->executionEnvironment->rootDeviceEnvironments[0]);
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface);
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mockDrm));
Mock<L0::DeviceImp> deviceImp(neoDevice, neoDevice->getExecutionEnvironment());
auto sessionMock = std::make_unique<MockDebugSessionLinux>(zet_debug_config_t{0x1234}, &deviceImp, 10);
ASSERT_NE(nullptr, sessionMock);
ze_device_thread_t thread = {0, 0, 0, 0};
auto threadID = sessionMock->convertToThreadId(thread);
EXPECT_EQ(0u, threadID.tileIndex);
EXPECT_EQ(0u, threadID.slice);
EXPECT_EQ(0u, threadID.subslice);
EXPECT_EQ(0u, threadID.eu);
EXPECT_EQ(0u, threadID.thread);
auto apiThread = sessionMock->convertToApi(threadID);
EXPECT_EQ(0u, apiThread.slice);
EXPECT_EQ(0u, apiThread.subslice);
EXPECT_EQ(0u, apiThread.eu);
EXPECT_EQ(0u, apiThread.thread);
uint32_t deviceIndex = 1;
auto physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(0u, physicalThread.slice);
EXPECT_EQ(0u, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
thread.slice = UINT32_MAX;
physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(uint32_t(UINT32_MAX), physicalThread.slice);
EXPECT_EQ(0u, physicalThread.subslice);
EXPECT_EQ(0u, physicalThread.eu);
EXPECT_EQ(0u, physicalThread.thread);
thread.slice = 0;
thread.subslice = UINT32_MAX;
thread.eu = 1;
thread.thread = 3;
physicalThread = sessionMock->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(0u, physicalThread.slice);
EXPECT_EQ(uint32_t(UINT32_MAX), physicalThread.subslice);
EXPECT_EQ(1u, physicalThread.eu);
EXPECT_EQ(3u, physicalThread.thread);
}
TEST(DebugSessionTest, WhenConvertingThreadIDsForDeviceWithSingleSliceThenSubsliceIsCorrectlyRemapped) {
TEST(DebugSessionLinuxTest, WhenConvertingThreadIDsForDeviceWithSingleSliceThenSubsliceIsCorrectlyRemapped) {
auto hwInfo = *NEO::defaultHwInfo.get();
hwInfo.gtSystemInfo.SliceCount = 1;
@@ -219,7 +157,7 @@ TEST(DebugSessionTest, WhenConvertingThreadIDsForDeviceWithSingleSliceThenSubsli
EXPECT_EQ(0u, physicalThread.thread);
}
TEST(DebugSessionTest, WhenConvertingThreadIDsForDeviceWithMultipleSlicesThenSubsliceIsNotRemapped) {
TEST(DebugSessionLinuxTest, WhenConvertingThreadIDsForDeviceWithMultipleSlicesThenSubsliceIsNotRemapped) {
auto hwInfo = *NEO::defaultHwInfo.get();
hwInfo.gtSystemInfo.SliceCount = 8;
@@ -264,7 +202,7 @@ TEST(DebugSessionTest, WhenConvertingThreadIDsForDeviceWithMultipleSlicesThenSub
EXPECT_EQ(0u, physicalThread.thread);
}
TEST(DebugSessionTest, GivenDeviceWithSingleSliceWhenCallingAreRequestedThreadsStoppedForSliceAllThenCorrectValuesAreReturned) {
TEST(DebugSessionLinuxTest, GivenDeviceWithSingleSliceWhenCallingAreRequestedThreadsStoppedForSliceAllThenCorrectValuesAreReturned) {
auto hwInfo = *NEO::defaultHwInfo.get();
hwInfo.gtSystemInfo.SliceCount = 1;
@@ -303,7 +241,7 @@ TEST(DebugSessionTest, GivenDeviceWithSingleSliceWhenCallingAreRequestedThreadsS
EXPECT_TRUE(stopped);
}
TEST(DebugSessionTest, WhenEnqueueApiEventCalledThenEventPushed) {
TEST(DebugSessionLinuxTest, WhenEnqueueApiEventCalledThenEventPushed) {
auto sessionMock = std::make_unique<MockDebugSessionLinux>(zet_debug_config_t{0x1234}, nullptr, 10);
sessionMock->clientHandle = MockDebugSessionLinux::mockClientHandle;
zet_debug_event_t debugEvent = {};
@@ -313,7 +251,7 @@ TEST(DebugSessionTest, WhenEnqueueApiEventCalledThenEventPushed) {
EXPECT_EQ(1u, sessionMock->apiEvents.size());
}
TEST(DebugSessionTest, GivenLogsEnabledWhenPrintContextVmsCalledThenMapIsPrinted) {
TEST(DebugSessionLinuxTest, GivenLogsEnabledWhenPrintContextVmsCalledThenMapIsPrinted) {
DebugManagerStateRestore restorer;
NEO::DebugManager.flags.DebuggerLogBitmask.set(255);
@@ -343,7 +281,7 @@ TEST(DebugSessionTest, GivenLogsEnabledWhenPrintContextVmsCalledThenMapIsPrinted
EXPECT_TRUE(hasSubstr(map, std::string("Context = 1 : 2")));
}
TEST(DebugSessionTest, GivenLogsDisabledWhenPrintContextVmsCalledThenMapIsiNotPrinted) {
TEST(DebugSessionLinuxTest, GivenLogsDisabledWhenPrintContextVmsCalledThenMapIsiNotPrinted) {
DebugManagerStateRestore restorer;
NEO::DebugManager.flags.DebuggerLogBitmask.set(0);
@@ -371,7 +309,7 @@ TEST(DebugSessionTest, GivenLogsDisabledWhenPrintContextVmsCalledThenMapIsiNotPr
EXPECT_TRUE(map.empty());
}
TEST(DebugSessionTest, GivenNullptrEventWhenReadingEventThenErrorNullptrReturned) {
TEST(DebugSessionLinuxTest, GivenNullptrEventWhenReadingEventThenErrorNullptrReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;
@@ -382,7 +320,7 @@ TEST(DebugSessionTest, GivenNullptrEventWhenReadingEventThenErrorNullptrReturned
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NULL_POINTER, result);
}
TEST(DebugSessionTest, GivenRootDebugSessionWhenCreateTileSessionCalledThenSessionIsCreated) {
TEST(DebugSessionLinuxTest, GivenRootDebugSessionWhenCreateTileSessionCalledThenSessionIsCreated) {
auto hwInfo = *NEO::defaultHwInfo.get();
NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
@@ -404,7 +342,7 @@ TEST(DebugSessionTest, GivenRootDebugSessionWhenCreateTileSessionCalledThenSessi
EXPECT_NE(nullptr, tileSession);
}
TEST(DebugSessionTest, GivenRootLinuxSessionWhenCallingTileSepcificFunctionsThenUnrecoverableIsCalled) {
TEST(DebugSessionLinuxTest, GivenRootLinuxSessionWhenCallingTileSepcificFunctionsThenUnrecoverableIsCalled) {
auto hwInfo = *NEO::defaultHwInfo.get();
NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
@@ -7358,7 +7296,7 @@ TEST_F(DebugApiLinuxMultiDeviceVmBindTest, givenSingleMemoryIsaWhenWritingAndRea
EXPECT_EQ(1, handler->preadCalled);
}
struct AffinityMaskMultipleSubdevices : DebugApiLinuxMultiDeviceFixture {
struct AffinityMaskMultipleSubdevicesLinux : DebugApiLinuxMultiDeviceFixture {
void setUp() {
DebugManager.flags.ZE_AFFINITY_MASK.set("0.0,0.1,0.3");
MultipleDevicesWithCustomHwInfo::numSubDevices = 4;
@@ -7371,58 +7309,9 @@ struct AffinityMaskMultipleSubdevices : DebugApiLinuxMultiDeviceFixture {
DebugManagerStateRestore restorer;
};
using AffinityMaskMultipleSubdevicesTest = Test<AffinityMaskMultipleSubdevices>;
using AffinityMaskMultipleSubdevicesTestLinux = Test<AffinityMaskMultipleSubdevicesLinux>;
TEST_F(AffinityMaskMultipleSubdevicesTest, givenApiThreadAndMultipleTilesWhenConvertingToPhysicalThenCorrectValuesReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto debugSession = std::make_unique<MockDebugSessionLinux>(config, deviceImp, 10);
ze_device_thread_t thread = {2 * sliceCount - 1, 0, 0, 0};
uint32_t deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(1u, deviceIndex);
auto convertedThread = debugSession->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(1u, deviceIndex);
EXPECT_EQ(sliceCount - 1, convertedThread.slice);
EXPECT_EQ(thread.subslice, convertedThread.subslice);
EXPECT_EQ(thread.eu, convertedThread.eu);
EXPECT_EQ(thread.thread, convertedThread.thread);
thread = {3 * sliceCount - 1, 0, 0, 0};
deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(3u, deviceIndex);
convertedThread = debugSession->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(3u, deviceIndex);
EXPECT_EQ(sliceCount - 1, convertedThread.slice);
EXPECT_EQ(thread.subslice, convertedThread.subslice);
EXPECT_EQ(thread.eu, convertedThread.eu);
EXPECT_EQ(thread.thread, convertedThread.thread);
thread = {sliceCount - 1, 0, 0, 0};
deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(0u, deviceIndex);
convertedThread = debugSession->convertToPhysicalWithinDevice(thread, deviceIndex);
EXPECT_EQ(0u, deviceIndex);
EXPECT_EQ(sliceCount - 1, convertedThread.slice);
EXPECT_EQ(thread.subslice, convertedThread.subslice);
EXPECT_EQ(thread.eu, convertedThread.eu);
EXPECT_EQ(thread.thread, convertedThread.thread);
thread.slice = UINT32_MAX;
deviceIndex = debugSession->getDeviceIndexFromApiThread(thread);
EXPECT_EQ(UINT32_MAX, deviceIndex);
}
TEST_F(AffinityMaskMultipleSubdevicesTest, GivenEventWithAckFlagAndTileNotWithinBitfieldWhenHandlingEventForISAThenIsaIsNotStoredInMapAndEventIsAcked) {
TEST_F(AffinityMaskMultipleSubdevicesTestLinux, GivenEventWithAckFlagAndTileNotWithinBitfieldWhenHandlingEventForISAThenIsaIsNotStoredInMapAndEventIsAcked) {
uint64_t isaGpuVa = 0x345000;
uint64_t isaSize = 0x2000;
uint64_t vmBindIsaData[sizeof(prelim_drm_i915_debug_event_vm_bind) / sizeof(uint64_t) + 3 * sizeof(typeOfUUID)];
@@ -7456,7 +7345,7 @@ TEST_F(AffinityMaskMultipleSubdevicesTest, GivenEventWithAckFlagAndTileNotWithin
EXPECT_EQ(vmBindIsa->base.seqno, handler->debugEventAcked.seqno);
}
TEST_F(AffinityMaskMultipleSubdevicesTest, GivenAttEventForTileNotWithinBitfieldWhenHandlingEventThenEventIsSkipped) {
TEST_F(AffinityMaskMultipleSubdevicesTestLinux, GivenAttEventForTileNotWithinBitfieldWhenHandlingEventThenEventIsSkipped) {
auto debugSession = std::make_unique<MockDebugSessionLinux>(zet_debug_config_t{1234}, deviceImp, 10);
uint64_t ctxHandle = 2;

View File

@@ -8,6 +8,7 @@
#pragma once
#include "shared/source/os_interface/os_interface.h"
#include "level_zero/core/source/device/device_imp.h"
#include "level_zero/tools/source/debug/debug_session.h"
namespace L0 {
@@ -35,11 +36,40 @@ struct DebugSessionMock : public L0::DebugSession {
using L0::DebugSession::getSingleThreadsForDevice;
using L0::DebugSession::isBindlessSystemRoutine;
DebugSessionMock(const zet_debug_config_t &config, L0::Device *device) : DebugSession(config, device), config(config){};
DebugSessionMock(const zet_debug_config_t &config, L0::Device *device) : DebugSession(config, device), config(config) {
topologyMap = buildMockTopology(device);
}
bool closeConnection() override {
closeConnectionCalled = true;
return true;
}
static NEO::TopologyMap buildMockTopology(L0::Device *device) {
NEO::TopologyMap topologyMap;
auto &hwInfo = device->getHwInfo();
uint32_t tileCount;
if (hwInfo.gtSystemInfo.MultiTileArchInfo.IsValid) {
tileCount = hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount;
} else {
tileCount = 1;
}
for (uint32_t deviceIdx = 0; deviceIdx < tileCount; deviceIdx++) {
NEO::TopologyMapping mapping;
for (uint32_t i = 0; i < hwInfo.gtSystemInfo.SliceCount; i++) {
mapping.sliceIndices.push_back(static_cast<int>(i));
}
if (hwInfo.gtSystemInfo.SliceCount == 1) {
for (uint32_t i = 0; i < hwInfo.gtSystemInfo.SubSliceCount; i++) {
mapping.subsliceIndices.push_back(static_cast<int>(i));
}
}
topologyMap[deviceIdx] = mapping;
}
return topologyMap;
}
ze_result_t initialize() override {
if (config.pid == 0) {
return ZE_RESULT_ERROR_UNKNOWN;
@@ -91,6 +121,11 @@ struct DebugSessionMock : public L0::DebugSession {
void setAttachMode(bool isRootAttach) override {}
const NEO::TopologyMap &getTopologyMap() override {
return this->topologyMap;
}
NEO::TopologyMap topologyMap;
zet_debug_config_t config;
bool asyncThreadStarted = false;
bool closeConnectionCalled = false;

View File

@@ -762,10 +762,6 @@ const std::vector<int> &Drm::getSliceMappings(uint32_t deviceIndex) {
return topologyMap[deviceIndex].sliceIndices;
}
const TopologyMap &Drm::getTopologyMap() {
return topologyMap;
}
int Drm::waitHandle(uint32_t waitHandle, int64_t timeout) {
UNRECOVERABLE_IF(isVmBindAvailable());

View File

@@ -9,7 +9,6 @@
#include "shared/source/gmm_helper/gmm_lib.h"
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/common_types.h"
#include "shared/source/helpers/topology_map.h"
#include "shared/source/memory_manager/definitions/engine_limits.h"
#include "shared/source/os_interface/driver_info.h"
#include "shared/source/os_interface/linux/cache_info.h"
@@ -229,7 +228,6 @@ class Drm : public DriverModel {
void setNewResourceBoundToVM(uint32_t vmHandleId);
const std::vector<int> &getSliceMappings(uint32_t deviceIndex);
const TopologyMap &getTopologyMap();
static std::vector<std::unique_ptr<HwDeviceId>> discoverDevices(ExecutionEnvironment &executionEnvironment);
static std::vector<std::unique_ptr<HwDeviceId>> discoverDevice(ExecutionEnvironment &executionEnvironment, std::string &osPciPath);
@@ -306,7 +304,6 @@ class Drm : public DriverModel {
ADAPTER_BDF adapterBDF{};
uint32_t pciDomain = 0;
TopologyMap topologyMap;
struct IoctlStatisticsEntry {
long long totalTime = 0;
uint64_t count = 0;

View File

@@ -9,6 +9,7 @@
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/helpers/driver_model_type.h"
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "shared/source/helpers/topology_map.h"
#include "shared/source/os_interface/driver_info.h"
#include <cstdint>
@@ -95,9 +96,13 @@ class DriverModel : public NonCopyableClass {
virtual void cleanup() {}
virtual bool isGpuHangDetected(OsContext &osContext) = 0;
const TopologyMap &getTopologyMap() {
return topologyMap;
};
protected:
DriverModelType driverModelType;
TopologyMap topologyMap;
bool skipResourceCleanupVar = false;
};

View File

@@ -221,10 +221,6 @@ bool Wddm::translateTopologyInfo(TopologyMapping &mapping) {
return (sliceCount && subSliceCount && euCount);
}
const TopologyMap &Wddm::getTopologyMap() {
return topologyMap;
}
bool Wddm::queryAdapterInfo() {
NTSTATUS status = STATUS_UNSUCCESSFUL;
ADAPTER_INFO_KMD adapterInfo = {};

View File

@@ -209,14 +209,12 @@ class Wddm : public DriverModel {
PhyicalDevicePciSpeedInfo getPciSpeedInfo() const override;
bool buildTopologyMapping();
const TopologyMap &getTopologyMap();
uint32_t getAdditionalAdapterInfoOptions() const {
return additionalAdapterInfoOptions;
}
protected:
TopologyMap topologyMap;
bool translateTopologyInfo(TopologyMapping &mapping);
Wddm(std::unique_ptr<HwDeviceIdWddm> &&hwDeviceId, RootDeviceEnvironment &rootDeviceEnvironment);