From 1444d98575ccfb38613dc0f0d38de38f4268b674 Mon Sep 17 00:00:00 2001 From: Mateusz Hoppe Date: Mon, 16 Mar 2020 13:34:33 +0100 Subject: [PATCH] Debugger support in L0 fixes Related-To: NEO-4404 Change-Id: I733b3018606b243989d9ba382da9d06bedbae799 Signed-off-by: Mateusz Hoppe --- level_zero/core/source/cmdqueue.h | 1 + level_zero/core/source/cmdqueue_hw.inl | 25 +++++++++++++++++-- level_zero/core/source/device.h | 1 + level_zero/core/source/device_imp.cpp | 18 ++++++++++++- level_zero/core/source/device_imp.h | 6 ++++- level_zero/core/source/kernel_imp.cpp | 15 +++++++++++ level_zero/core/source/kernel_imp.h | 1 + level_zero/core/source/module.h | 1 + level_zero/core/source/module_imp.cpp | 4 +++ level_zero/core/source/module_imp.h | 2 ++ .../source_level_debugger_device_tests.cpp | 11 +------- shared/test/unit_test/mocks/CMakeLists.txt | 1 + shared/test/unit_test/mocks/mock_os_library.h | 20 +++++++++++++++ 13 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 shared/test/unit_test/mocks/mock_os_library.h diff --git a/level_zero/core/source/cmdqueue.h b/level_zero/core/source/cmdqueue.h index f5812fa008..ad548e0348 100644 --- a/level_zero/core/source/cmdqueue.h +++ b/level_zero/core/source/cmdqueue.h @@ -57,6 +57,7 @@ struct CommandQueue : _ze_command_queue_handle_t { protected: std::atomic commandQueuePerThreadScratchSize; NEO::PreemptionMode commandQueuePreemptionMode = NEO::PreemptionMode::Initial; + bool commandQueueDebugCmdsProgrammed = false; }; using CommandQueueAllocatorFn = CommandQueue *(*)(Device *device, NEO::CommandStreamReceiver *csr, diff --git a/level_zero/core/source/cmdqueue_hw.inl b/level_zero/core/source/cmdqueue_hw.inl index a64c984f1d..2511c4065e 100644 --- a/level_zero/core/source/cmdqueue_hw.inl +++ b/level_zero/core/source/cmdqueue_hw.inl @@ -64,6 +64,7 @@ ze_result_t CommandQueueHw::executeCommandLists( size_t spaceForResidency = 0; size_t preemptionSize = 0u; + size_t debuggerCmdsSize = 0; constexpr size_t residencyContainerSpaceForPreemption = 2; constexpr size_t residencyContainerSpaceForFence = 1; constexpr size_t residencyContainerSpaceForTagWrite = 1; @@ -78,6 +79,11 @@ ze_result_t CommandQueueHw::executeCommandLists( NEO::PreemptionHelper::getRequiredStateSipCmdSize(*neoDevice); statePreemption = devicePreemption; } + + if (!commandQueueDebugCmdsProgrammed) { + debuggerCmdsSize += NEO::PreambleHelper::getKernelDebuggingCommandsSize(neoDevice->isDebuggerActive()); + } + if (devicePreemption == NEO::PreemptionMode::MidThread) { spaceForResidency += residencyContainerSpaceForPreemption; } @@ -147,7 +153,7 @@ ze_result_t CommandQueueHw::executeCommandLists( linearStreamSizeEstimate += NEO::MemorySynchronizationCommands::getSizeForPipeControlWithPostSyncOperation(device->getHwInfo()); - linearStreamSizeEstimate += preemptionSize; + linearStreamSizeEstimate += preemptionSize + debuggerCmdsSize; size_t alignedSize = alignUp(linearStreamSizeEstimate, minCmdBufferPtrAlign); size_t padding = alignedSize - linearStreamSizeEstimate; @@ -157,6 +163,12 @@ ze_result_t CommandQueueHw::executeCommandLists( if (!gpgpuEnabled) { programPipelineSelect(child); } + + if (!commandQueueDebugCmdsProgrammed && neoDevice->isDebuggerActive()) { + NEO::PreambleHelper::programKernelDebugging(&child); + commandQueueDebugCmdsProgrammed = true; + } + if (frontEndStateDirty) { programFrontEnd(scratchSpaceController->getScratchPatchAddress(), child); } @@ -175,12 +187,21 @@ ze_result_t CommandQueueHw::executeCommandLists( statePreemption = commandQueuePreemptionMode; } + const bool sipKernelUsed = devicePreemption == NEO::PreemptionMode::MidThread || + neoDevice->isDebuggerActive(); if (devicePreemption == NEO::PreemptionMode::MidThread) { residencyContainer.push_back(csr->getPreemptionAllocation()); - auto sipIsa = neoDevice->getBuiltIns()->getSipKernel(NEO::SipKernelType::Csr, *neoDevice).getSipAllocation(); + } + + if (sipKernelUsed) { + auto sipIsa = NEO::SipKernel::getSipKernelAllocation(*neoDevice); residencyContainer.push_back(sipIsa); } + if (neoDevice->isDebuggerActive()) { + residencyContainer.push_back(device->getDebugSurface()); + } + for (auto i = 0u; i < numCommandLists; ++i) { auto commandList = CommandList::fromHandle(phCommandLists[i]); auto cmdBufferAllocations = commandList->commandContainer.getCmdBufferAllocations(); diff --git a/level_zero/core/source/device.h b/level_zero/core/source/device.h index 15ce0d3647..2b4cbeaa17 100644 --- a/level_zero/core/source/device.h +++ b/level_zero/core/source/device.h @@ -115,6 +115,7 @@ struct Device : _ze_device_handle_t { NEO::SourceLevelDebugger *getSourceLevelDebugger() { return getNEODevice() ? reinterpret_cast(getNEODevice()->getDebugger()) : nullptr; } + virtual NEO::GraphicsAllocation *getDebugSurface() const = 0; }; } // namespace L0 diff --git a/level_zero/core/source/device_imp.cpp b/level_zero/core/source/device_imp.cpp index 26dcdb5232..8cab0503fa 100644 --- a/level_zero/core/source/device_imp.cpp +++ b/level_zero/core/source/device_imp.cpp @@ -7,6 +7,7 @@ #include "level_zero/core/source/device_imp.h" +#include "shared/source/built_ins/sip.h" #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/device/sub_device.h" #include "shared/source/execution_environment/execution_environment.h" @@ -577,6 +578,19 @@ Device *Device::create(DriverHandle *driverHandle, NEO::Device *neoDevice) { device->getSourceLevelDebugger()->notifyNewDevice(osInterface ? osInterface->getDeviceHandle() : 0); } + if (neoDevice->getDeviceInfo().debuggerActive) { + auto osInterface = neoDevice->getRootDeviceEnvironment().osInterface.get(); + + auto debugSurface = device->getDriverHandle()->getMemoryManager()->allocateGraphicsMemoryWithProperties( + {device->getRootDeviceIndex(), + NEO::SipKernel::maxDbgSurfaceSize, + NEO::GraphicsAllocation::AllocationType::INTERNAL_HOST_MEMORY}); + device->setDebugSurface(debugSurface); + + device->getSourceLevelDebugger() + ->notifyNewDevice(osInterface ? osInterface->getDeviceHandle() : 0); + } + return device; } @@ -591,8 +605,10 @@ DeviceImp::~DeviceImp() { metricContext.reset(); builtins.reset(); - if (neoDevice->getDeviceInfo().debuggerActive && getSourceLevelDebugger()) { + if (neoDevice->getDeviceInfo().debuggerActive) { getSourceLevelDebugger()->notifyDeviceDestruction(); + this->driverHandle->getMemoryManager()->freeGraphicsMemory(this->debugSurface); + this->debugSurface = nullptr; } if (neoDevice) { diff --git a/level_zero/core/source/device_imp.h b/level_zero/core/source/device_imp.h index 4b6b22f245..c7a89673ba 100644 --- a/level_zero/core/source/device_imp.h +++ b/level_zero/core/source/device_imp.h @@ -77,7 +77,8 @@ struct DeviceImp : public Device { NEO::Device *getNEODevice() override; void activateMetricGroups() override; void processAdditionalKernelProperties(NEO::HwHelper &hwHelper, ze_device_kernel_properties_t *pKernelProperties); - + NEO::GraphicsAllocation *getDebugSurface() const override { return debugSurface; } + void setDebugSurface(NEO::GraphicsAllocation *debugSurface) { this->debugSurface = debugSurface; }; ~DeviceImp() override; NEO::Device *neoDevice = nullptr; @@ -90,6 +91,9 @@ struct DeviceImp : public Device { std::vector subDevices; DriverHandle *driverHandle = nullptr; CommandList *pageFaultCommandList = nullptr; + + protected: + NEO::GraphicsAllocation *debugSurface = nullptr; }; } // namespace L0 diff --git a/level_zero/core/source/kernel_imp.cpp b/level_zero/core/source/kernel_imp.cpp index a787a5e788..8ec4a20308 100644 --- a/level_zero/core/source/kernel_imp.cpp +++ b/level_zero/core/source/kernel_imp.cpp @@ -608,6 +608,8 @@ ze_result_t KernelImp::initialize(const ze_kernel_desc_t *desc) { this->createPrintfBuffer(); + this->setDebugSurface(); + for (auto &alloc : kernelImmData->getResidencyContainer()) { residencyContainer.push_back(alloc); } @@ -629,6 +631,19 @@ void KernelImp::printPrintfOutput() { PrintfHandler::printOutput(kernelImmData, this->printfBuffer, module->getDevice()); } +void KernelImp::setDebugSurface() { + auto device = module->getDevice(); + if (module->isDebugEnabled() && device->getNEODevice()->isDebuggerActive()) { + + auto surfaceStateHeapRef = ArrayRef(surfaceStateHeapData.get(), surfaceStateHeapDataSize); + + patchWithImplicitSurface(ArrayRef(), surfaceStateHeapRef, + 0, + *device->getDebugSurface(), this->getImmutableData()->getDescriptor().payloadMappings.implicitArgs.systemThreadSurfaceAddress, + *device->getNEODevice()); + } +} + void KernelImp::patchWorkgroupSizeInCrossThreadData(uint32_t x, uint32_t y, uint32_t z) { const NEO::KernelDescriptor &desc = kernelImmData->getDescriptor(); auto dst = ArrayRef(crossThreadData.get(), crossThreadDataSize); diff --git a/level_zero/core/source/kernel_imp.h b/level_zero/core/source/kernel_imp.h index 0be8ef1490..757a444c19 100644 --- a/level_zero/core/source/kernel_imp.h +++ b/level_zero/core/source/kernel_imp.h @@ -139,6 +139,7 @@ struct KernelImp : Kernel { void patchWorkgroupSizeInCrossThreadData(uint32_t x, uint32_t y, uint32_t z); void createPrintfBuffer(); + void setDebugSurface(); const KernelImmutableData *kernelImmData = nullptr; Module *module = nullptr; diff --git a/level_zero/core/source/module.h b/level_zero/core/source/module.h index 7e848a0672..9f88cd808b 100644 --- a/level_zero/core/source/module.h +++ b/level_zero/core/source/module.h @@ -39,6 +39,7 @@ struct Module : _ze_module_handle_t { virtual const KernelImmutableData *getKernelImmutableData(const char *functionName) const = 0; virtual const std::vector> &getKernelImmutableDataVector() const = 0; virtual uint32_t getMaxGroupSize() const = 0; + virtual bool isDebugEnabled() const = 0; Module() = default; Module(const Module &) = delete; diff --git a/level_zero/core/source/module_imp.cpp b/level_zero/core/source/module_imp.cpp index 07c90f1273..bbf91ad300 100644 --- a/level_zero/core/source/module_imp.cpp +++ b/level_zero/core/source/module_imp.cpp @@ -525,6 +525,10 @@ ze_result_t ModuleImp::getKernelNames(uint32_t *pCount, const char **pNames) { return ZE_RESULT_SUCCESS; } +bool ModuleImp::isDebugEnabled() const { + return this->translationUnit->debugDataSize > 0; +} + bool moveBuildOption(std::string &dstOptionsSet, std::string &srcOptionSet, ConstStringRef dstOptionName, ConstStringRef srcOptionName) { auto optInSrcPos = srcOptionSet.find(srcOptionName.begin()); if (std::string::npos == optInSrcPos) { diff --git a/level_zero/core/source/module_imp.h b/level_zero/core/source/module_imp.h index 30c876e90b..ad5f977f2d 100644 --- a/level_zero/core/source/module_imp.h +++ b/level_zero/core/source/module_imp.h @@ -61,6 +61,8 @@ struct ModuleImp : public Module { bool initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice); + bool isDebugEnabled() const override; + protected: ModuleImp() = default; diff --git a/opencl/test/unit_test/source_level_debugger/source_level_debugger_device_tests.cpp b/opencl/test/unit_test/source_level_debugger/source_level_debugger_device_tests.cpp index 1d966e5999..ce8bd9d18f 100644 --- a/opencl/test/unit_test/source_level_debugger/source_level_debugger_device_tests.cpp +++ b/opencl/test/unit_test/source_level_debugger/source_level_debugger_device_tests.cpp @@ -7,6 +7,7 @@ #include "shared/source/source_level_debugger/source_level_debugger.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" +#include "shared/test/unit_test/mocks/mock_os_library.h" #include "opencl/source/platform/platform.h" #include "opencl/test/unit_test/fixtures/device_fixture.h" @@ -18,16 +19,6 @@ using PreambleTest = ::testing::Test; using namespace NEO; -class MockOsLibrary : public OsLibrary { - public: - void *getProcAddress(const std::string &procName) override { - return nullptr; - } - bool isLoaded() override { - return false; - } -}; - class MockDeviceWithDebuggerActive : public MockDevice { public: MockDeviceWithDebuggerActive(ExecutionEnvironment *executionEnvironment, uint32_t deviceIndex) : MockDevice(executionEnvironment, deviceIndex) {} diff --git a/shared/test/unit_test/mocks/CMakeLists.txt b/shared/test/unit_test/mocks/CMakeLists.txt index 411b6817d0..bf10f0314b 100644 --- a/shared/test/unit_test/mocks/CMakeLists.txt +++ b/shared/test/unit_test/mocks/CMakeLists.txt @@ -9,6 +9,7 @@ set(NEO_CORE_tests_mocks ${CMAKE_CURRENT_SOURCE_DIR}/mock_direct_submission_hw.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_dispatch_kernel_encoder_interface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_dispatch_kernel_encoder_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_os_library.h ) set_property(GLOBAL PROPERTY NEO_CORE_tests_mocks ${NEO_CORE_tests_mocks}) diff --git a/shared/test/unit_test/mocks/mock_os_library.h b/shared/test/unit_test/mocks/mock_os_library.h new file mode 100644 index 0000000000..38e84d8957 --- /dev/null +++ b/shared/test/unit_test/mocks/mock_os_library.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/os_interface/os_library.h" + +class MockOsLibrary : public NEO::OsLibrary { + public: + void *getProcAddress(const std::string &procName) override { + return nullptr; + } + bool isLoaded() override { + return false; + } +};