compute-runtime/level_zero/tools/source/debug/debug_session.cpp

207 lines
7.3 KiB
C++

/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/tools/source/debug/debug_session.h"
#include "shared/source/helpers/hw_info.h"
#include "level_zero/core/source/device/device_imp.h"
namespace L0 {
ze_device_thread_t DebugSession::convertToPhysical(ze_device_thread_t thread, uint32_t &deviceIndex) {
auto hwInfo = connectedDevice->getHwInfo();
auto deviceBitfield = connectedDevice->getNEODevice()->getDeviceBitfield();
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;
thread.slice = thread.slice % hwInfo.gtSystemInfo.SliceCount;
}
return thread;
}
EuThread::ThreadId DebugSession::convertToThreadId(ze_device_thread_t thread) {
auto hwInfo = connectedDevice->getHwInfo();
auto deviceBitfield = connectedDevice->getNEODevice()->getDeviceBitfield();
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;
}
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();
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)};
if (!connectedDevice->getNEODevice()->isSubDevice()) {
thread.slice = thread.slice + static_cast<uint32_t>(threadId.tileIndex * hwInfo.gtSystemInfo.SliceCount);
}
return thread;
}
DebugSession::DebugSession(const zet_debug_config_t &config, Device *device) : connectedDevice(device) {
if (connectedDevice) {
auto hwInfo = connectedDevice->getHwInfo();
const uint32_t numSubslicesPerSlice = hwInfo.gtSystemInfo.MaxSubSlicesSupported / hwInfo.gtSystemInfo.MaxSlicesSupported;
const uint32_t numEuPerSubslice = hwInfo.gtSystemInfo.MaxEuPerSubSlice;
const uint32_t numThreadsPerEu = (hwInfo.gtSystemInfo.ThreadCount / hwInfo.gtSystemInfo.EUCount);
uint32_t subDeviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices());
for (uint32_t tileIndex = 0; tileIndex < subDeviceCount; tileIndex++) {
for (uint32_t sliceID = 0; sliceID < hwInfo.gtSystemInfo.MaxSlicesSupported; sliceID++) {
for (uint32_t subsliceID = 0; subsliceID < numSubslicesPerSlice; subsliceID++) {
for (uint32_t euID = 0; euID < numEuPerSubslice; euID++) {
for (uint32_t threadID = 0; threadID < numThreadsPerEu; threadID++) {
EuThread::ThreadId thread = {tileIndex, sliceID, subsliceID, euID, threadID};
allThreads[uint64_t(thread)] = std::make_unique<EuThread>(thread);
}
}
}
}
}
}
}
std::vector<EuThread::ThreadId> DebugSession::getSingleThreadsForDevice(uint32_t deviceIndex, ze_device_thread_t physicalThread, const NEO::HardwareInfo &hwInfo) {
const uint32_t numSubslicesPerSlice = hwInfo.gtSystemInfo.MaxSubSlicesSupported / hwInfo.gtSystemInfo.MaxSlicesSupported;
const uint32_t numEuPerSubslice = hwInfo.gtSystemInfo.MaxEuPerSubSlice;
const uint32_t numThreadsPerEu = (hwInfo.gtSystemInfo.ThreadCount / hwInfo.gtSystemInfo.EUCount);
UNRECOVERABLE_IF(numThreadsPerEu > 8);
std::vector<EuThread::ThreadId> threads;
const uint32_t slice = physicalThread.slice;
const uint32_t subslice = physicalThread.subslice;
const uint32_t eu = physicalThread.eu;
const uint32_t thread = physicalThread.thread;
for (uint32_t sliceID = 0; sliceID < hwInfo.gtSystemInfo.MaxSlicesSupported; sliceID++) {
if (slice != UINT32_MAX) {
sliceID = slice;
}
for (uint32_t subsliceID = 0; subsliceID < numSubslicesPerSlice; subsliceID++) {
if (subslice != UINT32_MAX) {
subsliceID = subslice;
}
for (uint32_t euID = 0; euID < numEuPerSubslice; euID++) {
if (eu != UINT32_MAX) {
euID = eu;
}
for (uint32_t threadID = 0; threadID < numThreadsPerEu; threadID++) {
if (thread != UINT32_MAX) {
threadID = thread;
}
threads.push_back({deviceIndex, sliceID, subsliceID, euID, threadID});
if (thread != UINT32_MAX) {
break;
}
}
if (eu != UINT32_MAX) {
break;
}
}
if (subslice != UINT32_MAX) {
break;
}
}
if (slice != UINT32_MAX) {
break;
}
}
return threads;
}
bool DebugSession::areRequestedThreadsStopped(ze_device_thread_t thread) {
auto hwInfo = connectedDevice->getHwInfo();
uint32_t deviceIndex = 0;
auto physicalThread = convertToPhysical(thread, deviceIndex);
auto singleThreads = getSingleThreadsForDevice(deviceIndex, physicalThread, hwInfo);
bool requestedThreadsStopped = true;
for (auto &threadId : singleThreads) {
if (allThreads[threadId]->isStopped()) {
continue;
}
requestedThreadsStopped = false;
}
return requestedThreadsStopped;
}
ze_result_t DebugSession::sanityMemAccessThreadCheck(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc) {
if (DebugSession::isThreadAll(thread)) {
if (desc->type != ZET_DEBUG_MEMORY_SPACE_TYPE_DEFAULT) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
} else {
return ZE_RESULT_SUCCESS;
}
} else if (DebugSession::isSingleThread(thread)) {
if (desc->type != ZET_DEBUG_MEMORY_SPACE_TYPE_DEFAULT) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
if (!areRequestedThreadsStopped(thread)) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
} else {
return ZE_RESULT_SUCCESS;
}
}
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
void DebugSession::fillDevicesFromThread(ze_device_thread_t thread, std::vector<uint8_t> &devices) {
auto deviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices());
UNRECOVERABLE_IF(devices.size() < deviceCount);
uint32_t deviceIndex = 0;
convertToPhysical(thread, deviceIndex);
bool singleDevice = (thread.slice != UINT32_MAX && deviceCount > 1) || deviceCount == 1;
if (singleDevice) {
devices[deviceIndex] = 1;
} else {
for (uint32_t i = 0; i < deviceCount; i++) {
devices[i] = 1;
}
}
}
bool DebugSession::isBindlessSystemRoutine() {
if (debugArea.reserved1 &= 1) {
return true;
}
return false;
}
} // namespace L0