mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 06:49:52 +08:00
Add software tags
Related-To: NEO-344 Signed-off-by: Konstanty Misiak <konstanty.misiak@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
d1f95a0ff8
commit
88a1593913
@@ -36,6 +36,8 @@ DECLARE_DEBUG_VARIABLE(bool, AUBDumpAllocsOnEnqueueSVMMemcpyOnly, false, "Force
|
||||
DECLARE_DEBUG_VARIABLE(bool, AUBDumpForceAllToLocalMemory, false, "Force placing every allocation in local memory address space")
|
||||
|
||||
/*DEBUG FLAGS*/
|
||||
DECLARE_DEBUG_VARIABLE(bool, EnableSWTags, false, "Enable software tagging in batch buffer")
|
||||
DECLARE_DEBUG_VARIABLE(bool, DumpSWTagsBXML, false, "Dump software tags BXML into a file")
|
||||
DECLARE_DEBUG_VARIABLE(bool, DisableTimestampPacketOptimizations, false, "Allocate new allocation per node + dont reuse old nodes")
|
||||
DECLARE_DEBUG_VARIABLE(bool, DisableCachingForStatefulBufferAccess, false, "Disable caching for stateful buffer access")
|
||||
DECLARE_DEBUG_VARIABLE(bool, EnableDebugBreak, true, "Enable DEBUG_BREAKs")
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/source/os_interface/os_time.h"
|
||||
#include "shared/source/source_level_debugger/source_level_debugger.h"
|
||||
#include "shared/source/utilities/software_tags_manager.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
@@ -34,6 +35,7 @@ Device::Device(ExecutionEnvironment *executionEnvironment)
|
||||
|
||||
Device::~Device() {
|
||||
DEBUG_BREAK_IF(nullptr == executionEnvironment->memoryManager.get());
|
||||
|
||||
if (performanceCounters) {
|
||||
performanceCounters->shutdown();
|
||||
}
|
||||
@@ -99,6 +101,10 @@ bool Device::createDeviceImpl() {
|
||||
}
|
||||
}
|
||||
|
||||
if (DebugManager.flags.EnableSWTags.get() && !getRootDeviceEnvironment().tagsManager->isInitialized()) {
|
||||
getRootDeviceEnvironment().tagsManager->initialize(*this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "shared/source/helpers/bindless_heaps_helper.h"
|
||||
#include "shared/source/helpers/hw_helper.h"
|
||||
#include "shared/source/memory_manager/memory_manager.h"
|
||||
#include "shared/source/utilities/software_tags_manager.h"
|
||||
|
||||
namespace NEO {
|
||||
extern CommandStreamReceiver *createCommandStream(ExecutionEnvironment &executionEnvironment,
|
||||
@@ -24,6 +25,10 @@ extern CommandStreamReceiver *createCommandStream(ExecutionEnvironment &executio
|
||||
RootDevice::RootDevice(ExecutionEnvironment *executionEnvironment, uint32_t rootDeviceIndex) : Device(executionEnvironment), rootDeviceIndex(rootDeviceIndex) {}
|
||||
|
||||
RootDevice::~RootDevice() {
|
||||
if (getRootDeviceEnvironment().tagsManager) {
|
||||
getRootDeviceEnvironment().tagsManager->shutdown();
|
||||
}
|
||||
|
||||
for (auto subdevice : subdevices) {
|
||||
if (subdevice) {
|
||||
delete subdevice;
|
||||
@@ -94,6 +99,7 @@ bool RootDevice::createDeviceImpl() {
|
||||
if (ApiSpecificConfig::getBindlessConfiguration()) {
|
||||
this->executionEnvironment->rootDeviceEnvironments[getRootDeviceIndex()]->createBindlessHeapsHelper(getMemoryManager(), getNumAvailableDevices() > 1, rootDeviceIndex);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,16 @@
|
||||
#include "shared/source/memory_manager/memory_manager.h"
|
||||
#include "shared/source/memory_manager/memory_operations_handler.h"
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/source/utilities/software_tags_manager.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
RootDeviceEnvironment::RootDeviceEnvironment(ExecutionEnvironment &executionEnvironment) : executionEnvironment(executionEnvironment) {
|
||||
hwInfo = std::make_unique<HardwareInfo>();
|
||||
|
||||
if (DebugManager.flags.EnableSWTags.get()) {
|
||||
tagsManager = std::make_unique<SWTagsManager>();
|
||||
}
|
||||
}
|
||||
|
||||
RootDeviceEnvironment::~RootDeviceEnvironment() = default;
|
||||
|
||||
@@ -28,6 +28,7 @@ class HwDeviceId;
|
||||
class MemoryManager;
|
||||
class MemoryOperationsHandler;
|
||||
class OSInterface;
|
||||
class SWTagsManager;
|
||||
struct HardwareInfo;
|
||||
|
||||
constexpr uint32_t allSubDevicesActive = std::numeric_limits<uint32_t>::max();
|
||||
@@ -67,6 +68,7 @@ struct RootDeviceEnvironment {
|
||||
std::unique_ptr<CompilerInterface> compilerInterface;
|
||||
std::unique_ptr<BuiltIns> builtins;
|
||||
std::unique_ptr<Debugger> debugger;
|
||||
std::unique_ptr<SWTagsManager> tagsManager;
|
||||
ExecutionEnvironment &executionEnvironment;
|
||||
|
||||
uint32_t deviceAffinityMask = allSubDevicesActive;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019-2020 Intel Corporation
|
||||
# Copyright (C) 2019-2021 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
@@ -28,6 +28,10 @@ set(NEO_CORE_UTILITIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/perf_profiler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/range.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/reference_tracked_object.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/software_tags.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/software_tags.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spinlock.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/stackvec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tag_allocator.h
|
||||
|
||||
153
shared/source/utilities/software_tags.cpp
Normal file
153
shared/source/utilities/software_tags.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/utilities/software_tags.h"
|
||||
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/helpers/file_io.h"
|
||||
|
||||
namespace NEO {
|
||||
namespace SWTags {
|
||||
|
||||
void BXMLHeapInfo::bxml(std::ostream &os) {
|
||||
os << "<Structure Name=\"SWTAG_BXML_HEAP_INFO\" Source=\"Driver\" Project=\"All\">\n";
|
||||
os << " <Description>BXML heap info. This will always be at offset 0.</Description>\n";
|
||||
os << " <DWord Name=\"0\">\n";
|
||||
os << " <BitField HighBit=\"31\" LowBit=\"0\" Name=\"MagicNumber\" Format=\"U32\">\n";
|
||||
os << " <Description>This is the target of the MI_STORE_DATA_IMM that specifies where the heap exists. This value will always be 0xDEB06D0C.</Description>\n";
|
||||
os << " <ValidValue Value=\"DEB06D0Ch\" IsDefault=\"true\" Name=\"SWTAG_MAGIC_NUMBER\" />\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
os << " <DWord Name=\"1\">\n";
|
||||
os << " <BitField HighBit=\"31\" LowBit=\"0\" Name=\"HeapSize\" Format=\"U32\">\n";
|
||||
os << " <Description>Specifies the size in DWORDs of the BXML buffer allocated by the UMD driver.</Description>\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
os << " <DWord Name=\"2\">\n";
|
||||
os << " <BitField HighBit=\"31\" LowBit=\"0\" Name=\"Component\" Format=\"U32\">\n";
|
||||
os << " <Description>Specifies the component type.</Description>\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
os << "</Structure>\n";
|
||||
}
|
||||
|
||||
void SWTagHeapInfo::bxml(std::ostream &os) {
|
||||
os << "<Structure Name=\"SWTAG_HEAP_INFO\" Source=\"Driver\" Project=\"All\">\n";
|
||||
os << " <Description>Software tag heap info. This will always be at offset 0.</Description>\n";
|
||||
os << " <DWord Name=\"0\">\n";
|
||||
os << " <BitField HighBit=\"31\" LowBit=\"0\" Name=\"MagicNumber\" Format=\"U32\">\n";
|
||||
os << " <Description>This is the target of the MI_STORE_DATA_IMM that specifies where the heap exists. This value will always be 0xDEB06DD1.</Description>\n";
|
||||
os << " <ValidValue Value=\"DEB06DD1h\" IsDefault=\"true\" Name=\"SWTAG_MAGIC_NUMBER\"/>\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
os << " <DWord Name=\"1\">\n";
|
||||
os << " <BitField HighBit=\"31\" LowBit=\"0\" Name=\"HeapSize\" Format=\"U32\">\n";
|
||||
os << " <Description>Specifies the size in DWORDs of the tag heap allocated by the UMD driver. Maximum value is 1MB.</Description>\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
os << " <DWord Name=\"2\">\n";
|
||||
os << " <BitField HighBit=\"31\" LowBit=\"0\" Name=\"Component\" Format=\"U32\">\n";
|
||||
os << " <Description>Specifies the component type.</Description>\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
os << "</Structure>\n";
|
||||
}
|
||||
|
||||
uint32_t BaseTag::getMarkerNoopID(OpCode opcode) {
|
||||
MarkerNoopID id;
|
||||
id.OpCode = static_cast<uint32_t>(opcode);
|
||||
id.Reserved = 0;
|
||||
return id.value;
|
||||
}
|
||||
|
||||
uint32_t BaseTag::getOffsetNoopID(uint32_t offset) {
|
||||
OffsetNoopID id;
|
||||
id.Offset = offset / sizeof(uint32_t);
|
||||
id.SubTag = 0;
|
||||
id.MagicBit = 1;
|
||||
id.Reserved = 0;
|
||||
return id.value;
|
||||
}
|
||||
|
||||
void BaseTag::bxml(std::ostream &os, OpCode opcode, size_t size, const char *name) {
|
||||
os << " <DWord Name=\"0\">\n";
|
||||
os << " <BitField Name=\"DriverDebug\" HighBit=\"31\" LowBit=\"31\" Format=\"OpCode\">\n";
|
||||
os << " <Description>Specifies this is a SW driver debug tag.</Description>\n";
|
||||
os << " <ValidValue Value=\"1\" IsDefault=\"true\" Name=\"DRIVER_DEBUG\" />\n";
|
||||
os << " </BitField>\n";
|
||||
os << " <BitField Name=\"Component\" HighBit=\"30\" LowBit=\"24\" Format=\"OpCode\">\n";
|
||||
os << " <Description>Specifies the component type.</Description>\n";
|
||||
os << " <ValidValue Value=\"1h\" IsDefault=\"true\" Name=\"COMMON\" />\n";
|
||||
os << " </BitField>\n";
|
||||
os << " <BitField Name=\"OpCode\" HighBit=\"23\" LowBit=\"0\" Format=\"OpCode\">\n";
|
||||
os << " <Description>Specifies the opcode.</Description>\n";
|
||||
os << " <ValidValue Value=\"" << static_cast<uint32_t>(opcode) << "\" IsDefault=\"true\" Name=\"" << name << "\" />\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
os << " <DWord Name=\"1\">\n";
|
||||
os << " <BitField Name=\"DWORDCount\" HighBit=\"31\" LowBit=\"0\" Format=\"=n\">\n";
|
||||
os << " <Description>Specifies the tag size in DWORDs (TotalSize - 2)</Description>\n";
|
||||
os << " <ValidValue Value=\"" << static_cast<uint32_t>(size / sizeof(uint32_t) - 2) << "\" IsDefault=\"true\" Name=\"DWORD_COUNT_n\" />\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </DWord>\n";
|
||||
}
|
||||
|
||||
void KernelNameTag::bxml(std::ostream &os) {
|
||||
os << "<Instruction Name=\"KernelName\" Source=\"Driver\" Project=\"All\" LengthBias=\"2\">\n";
|
||||
os << " <Description>Name of the kernel.</Description>\n";
|
||||
|
||||
BaseTag::bxml(os, OpCode::KernelName, sizeof(KernelNameTag), "KERNEL_NAME");
|
||||
|
||||
unsigned int stringDWORDSize = KENEL_NAME_STR_LENGTH / sizeof(uint32_t);
|
||||
os << " <Dword Name=\"2.." << 2 + stringDWORDSize << "\">\n";
|
||||
os << " <BitField Name=\"KernelName\" HighBit=\"" << 32 * stringDWORDSize - 1 << "\" LowBit=\"0\" Format=\"string\">\n";
|
||||
os << " <Description>Name of the kernel.</Description>\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </Dword>\n";
|
||||
|
||||
os << "</Instruction>\n";
|
||||
}
|
||||
|
||||
void PipeControlReasonTag::bxml(std::ostream &os) {
|
||||
os << "<Instruction Name=\"PipeControlReason\" Source=\"Driver\" Project=\"All\" LengthBias=\"2\">\n";
|
||||
os << " <Description>Reason for why the PIPE_CONTROL was inserted.</Description>\n";
|
||||
|
||||
BaseTag::bxml(os, OpCode::PipeControlReason, sizeof(PipeControlReasonTag), "PIPE_CONTROL_REASON");
|
||||
|
||||
unsigned int stringDWORDSize = REASON_STR_LENGTH / sizeof(uint32_t);
|
||||
os << " <Dword Name=\"2.." << 2 + stringDWORDSize << "\">\n";
|
||||
os << " <BitField Name=\"PipeControlReason\" HighBit=\"" << 32 * stringDWORDSize - 1 << "\" LowBit=\"0\" Format=\"string\">\n";
|
||||
os << " <Description>Reason of the PIPE_CONTROL.</Description>\n";
|
||||
os << " </BitField>\n";
|
||||
os << " </Dword>\n";
|
||||
|
||||
os << "</Instruction>\n";
|
||||
}
|
||||
|
||||
SWTagBXML::SWTagBXML() {
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
ss << "<BSpec>\n";
|
||||
|
||||
BXMLHeapInfo::bxml(ss);
|
||||
SWTagHeapInfo::bxml(ss);
|
||||
|
||||
KernelNameTag::bxml(ss);
|
||||
PipeControlReasonTag::bxml(ss);
|
||||
|
||||
ss << "</BSpec>";
|
||||
|
||||
str = ss.str();
|
||||
|
||||
if (DebugManager.flags.DumpSWTagsBXML.get()) {
|
||||
writeDataToFile("swtagsbxml_dump.xml", str.c_str(), str.size());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SWTags
|
||||
} // namespace NEO
|
||||
120
shared/source/utilities/software_tags.h
Normal file
120
shared/source/utilities/software_tags.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/helpers/string.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace NEO {
|
||||
namespace SWTags {
|
||||
|
||||
enum class OpCode : uint32_t {
|
||||
Unknown,
|
||||
KernelName,
|
||||
PipeControlReason
|
||||
};
|
||||
|
||||
enum class Component : uint32_t {
|
||||
COMMON = 1
|
||||
};
|
||||
|
||||
struct BXMLHeapInfo {
|
||||
const uint32_t magicNumber = 0xDEB06D0C;
|
||||
const uint32_t heapSize;
|
||||
const uint32_t component = static_cast<uint32_t>(Component::COMMON);
|
||||
|
||||
BXMLHeapInfo(size_t size) : heapSize(static_cast<uint32_t>(size)) {}
|
||||
|
||||
static void bxml(std::ostream &os);
|
||||
};
|
||||
|
||||
struct SWTagHeapInfo {
|
||||
const uint32_t magicNumber = 0xDEB06DD1;
|
||||
const uint32_t heapSize;
|
||||
const uint32_t component = static_cast<uint32_t>(Component::COMMON);
|
||||
|
||||
SWTagHeapInfo(size_t size) : heapSize(static_cast<uint32_t>(size)) {}
|
||||
|
||||
static void bxml(std::ostream &os);
|
||||
};
|
||||
|
||||
struct BaseTag {
|
||||
public:
|
||||
BaseTag(OpCode code, size_t size) : opcode(static_cast<uint32_t>(code)),
|
||||
reserved(0),
|
||||
component(static_cast<uint32_t>(Component::COMMON)),
|
||||
driverDebug(1),
|
||||
DWORDCount(static_cast<uint32_t>(size / sizeof(uint32_t) - 2)) {}
|
||||
|
||||
OpCode getOpCode() const { return static_cast<OpCode>(opcode); }
|
||||
static uint32_t getMarkerNoopID(OpCode opcode);
|
||||
static uint32_t getOffsetNoopID(uint32_t offset);
|
||||
static void bxml(std::ostream &os, OpCode opcode, size_t size, const char *name);
|
||||
|
||||
protected:
|
||||
union MarkerNoopID {
|
||||
struct {
|
||||
uint32_t OpCode : 20;
|
||||
uint32_t Reserved : 12;
|
||||
};
|
||||
uint32_t value;
|
||||
};
|
||||
union OffsetNoopID {
|
||||
struct {
|
||||
uint32_t Offset : 20;
|
||||
uint32_t SubTag : 1;
|
||||
uint32_t MagicBit : 1;
|
||||
uint32_t Reserved : 10;
|
||||
};
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
const uint32_t opcode : 20;
|
||||
const uint32_t reserved : 4;
|
||||
const uint32_t component : 7;
|
||||
const uint32_t driverDebug : 1; // always 0x1
|
||||
const uint32_t DWORDCount;
|
||||
};
|
||||
|
||||
struct KernelNameTag : public BaseTag {
|
||||
public:
|
||||
KernelNameTag(const char *name)
|
||||
: BaseTag(OpCode::KernelName, sizeof(KernelNameTag)) {
|
||||
strcpy_s(kernelName, KENEL_NAME_STR_LENGTH, name);
|
||||
}
|
||||
|
||||
static void bxml(std::ostream &os);
|
||||
|
||||
private:
|
||||
static constexpr unsigned int KENEL_NAME_STR_LENGTH = sizeof(uint32_t) * 16; // Dword aligned
|
||||
char kernelName[KENEL_NAME_STR_LENGTH] = {};
|
||||
};
|
||||
|
||||
struct PipeControlReasonTag : public BaseTag {
|
||||
public:
|
||||
PipeControlReasonTag(const char *reason)
|
||||
: BaseTag(OpCode::PipeControlReason, sizeof(PipeControlReasonTag)) {
|
||||
strcpy_s(reasonString, REASON_STR_LENGTH, reason);
|
||||
}
|
||||
|
||||
static void bxml(std::ostream &os);
|
||||
|
||||
private:
|
||||
static constexpr unsigned int REASON_STR_LENGTH = sizeof(uint32_t) * 32; // Dword aligned
|
||||
char reasonString[REASON_STR_LENGTH] = {};
|
||||
};
|
||||
|
||||
struct SWTagBXML {
|
||||
SWTagBXML();
|
||||
|
||||
std::string str;
|
||||
};
|
||||
|
||||
} // namespace SWTags
|
||||
} // namespace NEO
|
||||
56
shared/source/utilities/software_tags_manager.cpp
Normal file
56
shared/source/utilities/software_tags_manager.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/utilities/software_tags_manager.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
void SWTagsManager::initialize(Device &device) {
|
||||
UNRECOVERABLE_IF(initialized);
|
||||
memoryManager = device.getMemoryManager();
|
||||
allocateBXMLHeap(device);
|
||||
allocateSWTagHeap(device);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void SWTagsManager::shutdown() {
|
||||
UNRECOVERABLE_IF(!initialized);
|
||||
memoryManager->freeGraphicsMemory(bxmlHeap);
|
||||
memoryManager->freeGraphicsMemory(tagHeap);
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void SWTagsManager::allocateBXMLHeap(Device &device) {
|
||||
SWTags::SWTagBXML tagBXML;
|
||||
size_t heapSizeInBytes = sizeof(SWTags::BXMLHeapInfo) + tagBXML.str.size() + 1;
|
||||
|
||||
const AllocationProperties properties{
|
||||
device.getRootDeviceIndex(),
|
||||
heapSizeInBytes,
|
||||
GraphicsAllocation::AllocationType::LINEAR_STREAM,
|
||||
device.getDeviceBitfield()};
|
||||
bxmlHeap = memoryManager->allocateGraphicsMemoryWithProperties(properties);
|
||||
|
||||
SWTags::BXMLHeapInfo bxmlHeapInfo(heapSizeInBytes / sizeof(uint32_t));
|
||||
MemoryTransferHelper::transferMemoryToAllocation(false, device, bxmlHeap, 0, &bxmlHeapInfo, sizeof(bxmlHeapInfo));
|
||||
MemoryTransferHelper::transferMemoryToAllocation(false, device, bxmlHeap, sizeof(bxmlHeapInfo), tagBXML.str.c_str(), heapSizeInBytes - sizeof(bxmlHeapInfo));
|
||||
}
|
||||
|
||||
void SWTagsManager::allocateSWTagHeap(Device &device) {
|
||||
const AllocationProperties properties{
|
||||
device.getRootDeviceIndex(),
|
||||
MAX_TAG_HEAP_SIZE,
|
||||
GraphicsAllocation::AllocationType::LINEAR_STREAM,
|
||||
device.getDeviceBitfield()};
|
||||
tagHeap = memoryManager->allocateGraphicsMemoryWithProperties(properties);
|
||||
|
||||
SWTags::SWTagHeapInfo tagHeapInfo(MAX_TAG_HEAP_SIZE / sizeof(uint32_t));
|
||||
MemoryTransferHelper::transferMemoryToAllocation(false, device, tagHeap, 0, &tagHeapInfo, sizeof(tagHeapInfo));
|
||||
currentHeapOffset += sizeof(tagHeapInfo);
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
122
shared/source/utilities/software_tags_manager.h
Normal file
122
shared/source/utilities/software_tags_manager.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/memory_manager/memory_manager.h"
|
||||
#include "shared/source/utilities/software_tags.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
class Device;
|
||||
class GraphicsAllocation;
|
||||
class LinearStream;
|
||||
|
||||
class SWTagsManager {
|
||||
public:
|
||||
SWTagsManager() = default;
|
||||
|
||||
void initialize(Device &device);
|
||||
void shutdown();
|
||||
bool isInitialized() const { return initialized; }
|
||||
|
||||
GraphicsAllocation *getBXMLHeapAllocation() { return bxmlHeap; }
|
||||
GraphicsAllocation *getSWTagHeapAllocation() { return tagHeap; }
|
||||
|
||||
template <typename GfxFamily>
|
||||
void insertBXMLHeapAddress(LinearStream &cmdStream);
|
||||
template <typename GfxFamily>
|
||||
void insertSWTagHeapAddress(LinearStream &cmdStream);
|
||||
template <typename GfxFamily, typename Tag, typename... Params>
|
||||
void insertTag(LinearStream &cmdStream, Device &device, Params... params);
|
||||
|
||||
template <typename GfxFamily>
|
||||
static size_t estimateSpaceForSWTags();
|
||||
|
||||
static const unsigned int MAX_TAG_COUNT = 20;
|
||||
static const unsigned int MAX_TAG_HEAP_SIZE = 1024;
|
||||
|
||||
private:
|
||||
void allocateBXMLHeap(Device &device);
|
||||
void allocateSWTagHeap(Device &device);
|
||||
|
||||
MemoryManager *memoryManager;
|
||||
GraphicsAllocation *tagHeap = nullptr;
|
||||
GraphicsAllocation *bxmlHeap = nullptr;
|
||||
unsigned int currentHeapOffset = 0;
|
||||
unsigned int currentTagCount = 0;
|
||||
bool initialized = false;
|
||||
};
|
||||
|
||||
template <typename GfxFamily>
|
||||
void SWTagsManager::insertBXMLHeapAddress(LinearStream &cmdStream) {
|
||||
using MI_STORE_DATA_IMM = typename GfxFamily::MI_STORE_DATA_IMM;
|
||||
|
||||
auto ptr = reinterpret_cast<SWTags::BXMLHeapInfo *>(memoryManager->lockResource(bxmlHeap));
|
||||
MI_STORE_DATA_IMM storeDataImm = GfxFamily::cmdInitStoreDataImm;
|
||||
storeDataImm.setAddress(bxmlHeap->getGpuAddress());
|
||||
storeDataImm.setDwordLength(MI_STORE_DATA_IMM::DWORD_LENGTH::DWORD_LENGTH_STORE_DWORD);
|
||||
storeDataImm.setDataDword0(ptr->magicNumber);
|
||||
memoryManager->unlockResource(bxmlHeap);
|
||||
|
||||
auto sdiSpace = cmdStream.getSpaceForCmd<MI_STORE_DATA_IMM>();
|
||||
*sdiSpace = storeDataImm;
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
void SWTagsManager::insertSWTagHeapAddress(LinearStream &cmdStream) {
|
||||
using MI_STORE_DATA_IMM = typename GfxFamily::MI_STORE_DATA_IMM;
|
||||
|
||||
auto ptr = reinterpret_cast<SWTags::BXMLHeapInfo *>(memoryManager->lockResource(tagHeap));
|
||||
MI_STORE_DATA_IMM storeDataImm = GfxFamily::cmdInitStoreDataImm;
|
||||
storeDataImm.setAddress(tagHeap->getGpuAddress());
|
||||
storeDataImm.setDwordLength(MI_STORE_DATA_IMM::DWORD_LENGTH::DWORD_LENGTH_STORE_DWORD);
|
||||
storeDataImm.setDataDword0(ptr->magicNumber);
|
||||
memoryManager->unlockResource(tagHeap);
|
||||
|
||||
auto sdiSpace = cmdStream.getSpaceForCmd<MI_STORE_DATA_IMM>();
|
||||
*sdiSpace = storeDataImm;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Tag, typename... Params>
|
||||
void SWTagsManager::insertTag(LinearStream &cmdStream, Device &device, Params... params) {
|
||||
using MI_NOOP = typename GfxFamily::MI_NOOP;
|
||||
|
||||
unsigned int tagSize = sizeof(Tag);
|
||||
|
||||
if (currentTagCount >= MAX_TAG_COUNT || currentHeapOffset + tagSize > MAX_TAG_HEAP_SIZE) {
|
||||
return;
|
||||
}
|
||||
++currentTagCount;
|
||||
|
||||
Tag tag(std::forward<Params>(params)...);
|
||||
|
||||
MemoryTransferHelper::transferMemoryToAllocation(false, device, tagHeap, currentHeapOffset, &tag, tagSize);
|
||||
|
||||
MI_NOOP marker = GfxFamily::cmdInitNoop;
|
||||
marker.setIdentificationNumber(tag.getMarkerNoopID(tag.getOpCode()));
|
||||
marker.setIdentificationNumberRegisterWriteEnable(true);
|
||||
|
||||
MI_NOOP offset = GfxFamily::cmdInitNoop;
|
||||
offset.setIdentificationNumber(tag.getOffsetNoopID(currentHeapOffset));
|
||||
currentHeapOffset += tagSize;
|
||||
|
||||
MI_NOOP *pNoop = cmdStream.getSpaceForCmd<MI_NOOP>();
|
||||
*pNoop = marker;
|
||||
pNoop = cmdStream.getSpaceForCmd<MI_NOOP>();
|
||||
*pNoop = offset;
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
size_t SWTagsManager::estimateSpaceForSWTags() {
|
||||
using MI_STORE_DATA_IMM = typename GfxFamily::MI_STORE_DATA_IMM;
|
||||
using MI_NOOP = typename GfxFamily::MI_NOOP;
|
||||
|
||||
return 2 * sizeof(MI_STORE_DATA_IMM) + 2 * MAX_TAG_COUNT * sizeof(MI_NOOP);
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
@@ -18,6 +18,7 @@ target_sources(${TARGET_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/numeric_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/perf_profiler_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/reference_tracked_object_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spinlock_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/timer_util_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vec_tests.cpp
|
||||
|
||||
256
shared/test/unit_test/utilities/software_tags_manager_tests.cpp
Normal file
256
shared/test/unit_test/utilities/software_tags_manager_tests.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/helpers/file_io.h"
|
||||
#include "shared/source/utilities/software_tags_manager.h"
|
||||
#include "shared/test/common/fixtures/device_fixture.h"
|
||||
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
||||
|
||||
#include "test.h"
|
||||
|
||||
using namespace NEO;
|
||||
using namespace SWTags;
|
||||
|
||||
constexpr static uint32_t testOpCode = 42;
|
||||
|
||||
struct TestTag : public BaseTag {
|
||||
TestTag() : BaseTag(static_cast<OpCode>(testOpCode), sizeof(TestTag)) {}
|
||||
|
||||
char testString[5] = "Test";
|
||||
bool testBool = true;
|
||||
uint16_t testWord = 42;
|
||||
uint32_t testDword = 42;
|
||||
};
|
||||
|
||||
struct VeryLargeTag : public BaseTag {
|
||||
VeryLargeTag() : BaseTag(static_cast<OpCode>(testOpCode), sizeof(VeryLargeTag)) {}
|
||||
|
||||
char largeBuffer[1025] = {};
|
||||
};
|
||||
|
||||
struct SoftwareTagsManagerTests : public DeviceFixture, public ::testing::Test {
|
||||
void SetUp() override {
|
||||
DebugManager.flags.EnableSWTags.set(true);
|
||||
DeviceFixture::SetUp();
|
||||
|
||||
tagsManager = pDevice->getRootDeviceEnvironment().tagsManager.get();
|
||||
|
||||
ASSERT_TRUE(tagsManager->isInitialized());
|
||||
ASSERT_NE(nullptr, tagsManager->getBXMLHeapAllocation());
|
||||
ASSERT_NE(nullptr, tagsManager->getSWTagHeapAllocation());
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
DeviceFixture::TearDown();
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
void initializeTestCmdStream() {
|
||||
const AllocationProperties properties{
|
||||
pDevice->getRootDeviceIndex(),
|
||||
SWTagsManager::estimateSpaceForSWTags<GfxFamily>(),
|
||||
GraphicsAllocation::AllocationType::LINEAR_STREAM,
|
||||
pDevice->getDeviceBitfield()};
|
||||
|
||||
GraphicsAllocation *allocation = pDevice->getMemoryManager()->allocateGraphicsMemoryWithProperties(properties);
|
||||
testCmdStream = std::make_unique<LinearStream>(allocation);
|
||||
}
|
||||
|
||||
void freeTestCmdStream() {
|
||||
pDevice->getMemoryManager()->freeGraphicsMemory(testCmdStream->getGraphicsAllocation());
|
||||
}
|
||||
|
||||
SWTagsManager *tagsManager;
|
||||
std::unique_ptr<LinearStream> testCmdStream;
|
||||
DebugManagerStateRestore dbgRestorer;
|
||||
};
|
||||
|
||||
TEST_F(SoftwareTagsManagerTests, whenSWTagsMangerIsInitializedThenHeapAllocationsAreCorrect) {
|
||||
auto memoryMgr = pDevice->getMemoryManager();
|
||||
SWTagBXML bxml;
|
||||
BXMLHeapInfo bxmlInfo((sizeof(BXMLHeapInfo) + bxml.str.size() + 1) / sizeof(uint32_t));
|
||||
SWTagHeapInfo tagInfo(SWTagsManager::MAX_TAG_HEAP_SIZE / sizeof(uint32_t));
|
||||
auto bxmlHeap = tagsManager->getBXMLHeapAllocation();
|
||||
auto tagHeap = tagsManager->getSWTagHeapAllocation();
|
||||
|
||||
auto ptr = memoryMgr->lockResource(bxmlHeap);
|
||||
auto pBxmlInfo = reinterpret_cast<BXMLHeapInfo *>(ptr);
|
||||
|
||||
EXPECT_EQ(bxmlInfo.component, pBxmlInfo->component);
|
||||
EXPECT_EQ(bxmlInfo.heapSize, pBxmlInfo->heapSize);
|
||||
EXPECT_EQ(bxmlInfo.magicNumber, pBxmlInfo->magicNumber);
|
||||
EXPECT_EQ(0, memcmp(bxml.str.c_str(), ptrOffset(ptr, sizeof(BXMLHeapInfo)), bxml.str.size()));
|
||||
|
||||
memoryMgr->unlockResource(bxmlHeap);
|
||||
|
||||
ptr = memoryMgr->lockResource(tagHeap);
|
||||
auto pTagInfo = reinterpret_cast<SWTagHeapInfo *>(ptr);
|
||||
|
||||
EXPECT_EQ(tagInfo.component, pTagInfo->component);
|
||||
EXPECT_EQ(tagInfo.heapSize, pTagInfo->heapSize);
|
||||
EXPECT_EQ(tagInfo.magicNumber, pTagInfo->magicNumber);
|
||||
|
||||
memoryMgr->unlockResource(tagHeap);
|
||||
}
|
||||
|
||||
HWTEST_F(SoftwareTagsManagerTests, whenHeapsAddressesAreInsertedThenCmdStreamHasCorrectContents) {
|
||||
using MI_STORE_DATA_IMM = typename FamilyType::MI_STORE_DATA_IMM;
|
||||
|
||||
initializeTestCmdStream<FamilyType>();
|
||||
|
||||
tagsManager->insertBXMLHeapAddress<FamilyType>(*testCmdStream.get());
|
||||
tagsManager->insertSWTagHeapAddress<FamilyType>(*testCmdStream.get());
|
||||
|
||||
EXPECT_EQ(testCmdStream->getUsed(), 2 * sizeof(MI_STORE_DATA_IMM));
|
||||
|
||||
void *bufferBase = testCmdStream->getCpuBase();
|
||||
auto sdi1 = reinterpret_cast<MI_STORE_DATA_IMM *>(bufferBase);
|
||||
auto sdi2 = reinterpret_cast<MI_STORE_DATA_IMM *>(ptrOffset(bufferBase, sizeof(MI_STORE_DATA_IMM)));
|
||||
auto bxmlHeap = tagsManager->getBXMLHeapAllocation();
|
||||
auto tagHeap = tagsManager->getSWTagHeapAllocation();
|
||||
|
||||
EXPECT_EQ(sdi1->getAddress(), bxmlHeap->getGpuAddress());
|
||||
EXPECT_EQ(sdi2->getAddress(), tagHeap->getGpuAddress());
|
||||
|
||||
freeTestCmdStream();
|
||||
}
|
||||
|
||||
HWTEST_F(SoftwareTagsManagerTests, whenTestTagIsInsertedThenItIsSuccessful) {
|
||||
using MI_NOOP = typename FamilyType::MI_NOOP;
|
||||
|
||||
initializeTestCmdStream<FamilyType>();
|
||||
|
||||
tagsManager->insertTag<FamilyType, TestTag>(*testCmdStream.get(), *pDevice);
|
||||
|
||||
EXPECT_EQ(testCmdStream->getUsed(), 2 * sizeof(MI_NOOP));
|
||||
|
||||
void *bufferBase = testCmdStream->getCpuBase();
|
||||
auto marker_noop = reinterpret_cast<MI_NOOP *>(bufferBase);
|
||||
auto offset_noop = reinterpret_cast<MI_NOOP *>(ptrOffset(bufferBase, sizeof(MI_NOOP)));
|
||||
|
||||
EXPECT_EQ(BaseTag::getMarkerNoopID(static_cast<OpCode>(testOpCode)), marker_noop->getIdentificationNumber());
|
||||
EXPECT_EQ(true, marker_noop->getIdentificationNumberRegisterWriteEnable());
|
||||
|
||||
uint32_t firstTagOffset = sizeof(SWTagHeapInfo); // SWTagHeapInfo is always on offset 0, first tag is inserted immediately after.
|
||||
|
||||
EXPECT_EQ(BaseTag::getOffsetNoopID(firstTagOffset), offset_noop->getIdentificationNumber());
|
||||
EXPECT_EQ(false, offset_noop->getIdentificationNumberRegisterWriteEnable());
|
||||
|
||||
auto memoryMgr = pDevice->getMemoryManager();
|
||||
auto tagHeap = tagsManager->getSWTagHeapAllocation();
|
||||
|
||||
TestTag tag;
|
||||
auto ptr = memoryMgr->lockResource(tagHeap);
|
||||
auto pTag = reinterpret_cast<TestTag *>(ptrOffset(ptr, firstTagOffset));
|
||||
|
||||
EXPECT_EQ(0, strcmp(tag.testString, pTag->testString));
|
||||
EXPECT_EQ(tag.testBool, pTag->testBool);
|
||||
EXPECT_EQ(tag.testWord, pTag->testWord);
|
||||
EXPECT_EQ(tag.testDword, pTag->testDword);
|
||||
|
||||
memoryMgr->unlockResource(tagHeap);
|
||||
freeTestCmdStream();
|
||||
}
|
||||
|
||||
HWTEST_F(SoftwareTagsManagerTests, whenVeryLargeTagIsInsertedThenItIsNotSuccessful) {
|
||||
initializeTestCmdStream<FamilyType>();
|
||||
|
||||
tagsManager->insertTag<FamilyType, VeryLargeTag>(*testCmdStream.get(), *pDevice);
|
||||
|
||||
EXPECT_EQ(0u, testCmdStream->getUsed());
|
||||
|
||||
freeTestCmdStream();
|
||||
}
|
||||
|
||||
HWTEST_F(SoftwareTagsManagerTests, givenSoftwareManagerWithMaxTagsReachedWhenTagIsInsertedThenItIsNotSuccessful) {
|
||||
using MI_NOOP = typename FamilyType::MI_NOOP;
|
||||
|
||||
initializeTestCmdStream<FamilyType>();
|
||||
|
||||
EXPECT_TRUE(tagsManager->MAX_TAG_HEAP_SIZE > (tagsManager->MAX_TAG_COUNT + 1) * sizeof(TestTag));
|
||||
|
||||
for (unsigned int i = 0; i <= tagsManager->MAX_TAG_COUNT; ++i) {
|
||||
tagsManager->insertTag<FamilyType, TestTag>(*testCmdStream.get(), *pDevice);
|
||||
}
|
||||
|
||||
EXPECT_EQ(testCmdStream->getUsed(), tagsManager->MAX_TAG_COUNT * 2 * sizeof(MI_NOOP));
|
||||
|
||||
tagsManager->insertTag<FamilyType, TestTag>(*testCmdStream.get(), *pDevice);
|
||||
|
||||
EXPECT_EQ(testCmdStream->getUsed(), tagsManager->MAX_TAG_COUNT * 2 * sizeof(MI_NOOP));
|
||||
|
||||
freeTestCmdStream();
|
||||
}
|
||||
|
||||
TEST(SoftwareTagsManagerMultiDeviceTests, givenEnableSWTagsAndCreateMultipleSubDevicesWhenDeviceCreatedThenSWTagsManagerIsInitializedOnlyOnce) {
|
||||
DebugManagerStateRestore dbgRestorer;
|
||||
DebugManager.flags.EnableSWTags.set(true);
|
||||
DebugManager.flags.CreateMultipleSubDevices.set(2);
|
||||
VariableBackup<bool> mockDeviceFlagBackup(&MockDevice::createSingleDevice, false);
|
||||
|
||||
// This test checks if UNRECOVERABLE_IF(...) was not called
|
||||
MockDevice *device = nullptr;
|
||||
EXPECT_NO_THROW(device = MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
|
||||
EXPECT_NE(device, nullptr);
|
||||
|
||||
delete device;
|
||||
}
|
||||
|
||||
struct SoftwareTagsParametrizedTests : public ::testing::TestWithParam<SWTags::OpCode> {
|
||||
void SetUp() override {
|
||||
tagMap.emplace(OpCode::KernelName, std::make_unique<KernelNameTag>(""));
|
||||
tagMap.emplace(OpCode::PipeControlReason, std::make_unique<PipeControlReasonTag>(""));
|
||||
}
|
||||
|
||||
std::map<OpCode, std::unique_ptr<BaseTag>> tagMap;
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SoftwareTags,
|
||||
SoftwareTagsParametrizedTests,
|
||||
testing::Values(
|
||||
OpCode::KernelName,
|
||||
OpCode::PipeControlReason));
|
||||
|
||||
TEST_P(SoftwareTagsParametrizedTests, whenGetOpCodeIsCalledThenCorrectValueIsReturned) {
|
||||
auto opcode = GetParam();
|
||||
auto tag = tagMap.at(opcode).get();
|
||||
|
||||
EXPECT_EQ(opcode, tag->getOpCode());
|
||||
}
|
||||
|
||||
TEST(SoftwareTagsTests, whenGetMarkerNoopIDCalledThenCorectValueIsReturned) {
|
||||
uint32_t id = SWTags::BaseTag::getMarkerNoopID(static_cast<OpCode>(testOpCode));
|
||||
|
||||
EXPECT_EQ(testOpCode, id);
|
||||
}
|
||||
|
||||
TEST(SoftwareTagsTests, whenGetOffsetNoopIDCalledThenCorrectValueIsReturned) {
|
||||
uint32_t address1 = 0;
|
||||
uint32_t address2 = 1234;
|
||||
uint32_t id1 = BaseTag::getOffsetNoopID(address1);
|
||||
uint32_t id2 = BaseTag::getOffsetNoopID(address2);
|
||||
|
||||
EXPECT_EQ(static_cast<uint32_t>(1 << 21) | address1 / sizeof(uint32_t), id1);
|
||||
EXPECT_EQ(static_cast<uint32_t>(1 << 21) | address2 / sizeof(uint32_t), id2);
|
||||
}
|
||||
|
||||
TEST(SoftwareTagsBXMLTests, givenDumpSWTagsBXMLWhenConstructingBXMLThenAFileIsDumped) {
|
||||
DebugManagerStateRestore dbgRestorer;
|
||||
DebugManager.flags.DumpSWTagsBXML.set(true);
|
||||
|
||||
const char *filename = "swtagsbxml_dump.xml";
|
||||
SWTagBXML bxml;
|
||||
|
||||
size_t retSize;
|
||||
auto data = loadDataFromFile(filename, retSize);
|
||||
|
||||
EXPECT_EQ(retSize, bxml.str.size());
|
||||
EXPECT_EQ(0, strcmp(data.get(), bxml.str.c_str()));
|
||||
|
||||
writeDataToFile(filename, "", 1);
|
||||
}
|
||||
Reference in New Issue
Block a user