Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 98 additions & 8 deletions profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "core/common/message.h"
#include "xdp/profile/database/database.h"
#include "xdp/profile/database/static_info/aie_util.h"
#include "xdp/profile/plugin/aie_dtrace/util/aie_dtrace_util.h"
#include "xdp/profile/plugin/vp_base/profiling_runtime_config.h"

namespace xdp {
Expand All @@ -35,6 +36,21 @@ namespace xdp {
return metrics;
}

static constexpr const char* INPUT_PORTS_METRIC_SET = "input_ports";

bool settingsRequestL2L2Transfer(const std::vector<std::string>& metricsSettings)
{
for (const auto& setting : metricsSettings) {
std::vector<std::string> parts;
boost::split(parts, setting, boost::is_any_of(":"));
for (const auto& part : parts) {
if (part == INPUT_PORTS_METRIC_SET)
return true;
}
}
return false;
}

AieDtraceMetadata::AieDtraceMetadata(uint64_t deviceID, void* handle)
: deviceID(deviceID)
, handle(handle)
Expand All @@ -53,14 +69,6 @@ namespace xdp {
const bool usingBlob = profiling_runtime_config::has_control_instrumentation();
const auto& ci = profiling_runtime_config::control_instrumentation();

if (usingBlob) {
if (ci.mem_tile.has_value() && !ci.mem_tile->empty()) {
xrt_core::message::send(severity_level::info, "XRT",
"AIE dtrace: mem tile metric '" + *ci.mem_tile
+ "' from profiling_runtime_config will be supported in a follow-up.");
}
}

// Core (aie) tile metrics (e.g. compute_io_bound). Only used to enable the
// metric; the tiles themselves are fixed to the first column.
std::vector<std::string> aieMetricsSettings;
Expand Down Expand Up @@ -96,6 +104,86 @@ namespace xdp {

getConfigMetricsForInterfaceTiles(SHIM_MODULE_IDX, metricsSettings);

// Memory tile / L2-L2: blob and xrt.ini are separate config sources. If either
// mem_tile or memory_tile_input_ports is present and non-empty in control_instrumentation,
// the whole mem-tile L2-L2 config must come from the blob (both fields). Otherwise
// both tile_based_memory_tile_metrics and memory_tile_input_ports must be in xrt.ini.
const std::string memTileSettings =
xrt_core::config::get_aie_dtrace_settings_tile_based_memory_tile_metrics();
const bool iniL2L2Enabled = !memTileSettings.empty()
&& settingsRequestL2L2Transfer(getSettingsVector(memTileSettings));
const std::string iniPorts =
xrt_core::config::get_aie_dtrace_settings_memory_tile_input_ports();
const bool iniPortsSet = !iniPorts.empty();
const bool blobPortsSet = usingBlob && ci.memory_tile_input_ports.has_value()
&& !ci.memory_tile_input_ports->empty();
const bool memTileFieldFromBlob = usingBlob && ci.mem_tile.has_value()
&& !ci.mem_tile->empty();
const bool memTileUsesBlob = usingBlob && (memTileFieldFromBlob || blobPortsSet);

bool l2L2FromBlob = false;
if (memTileUsesBlob) {
if (memTileFieldFromBlob && *ci.mem_tile == INPUT_PORTS_METRIC_SET) {
l2L2TransferEnabled = true;
l2L2FromBlob = true;
xrt_core::message::send(severity_level::info, "XRT",
"AIE dtrace: enabling L2-L2 via mem_tile metric '" + *ci.mem_tile
+ "' from Debug.profiling_runtime_config.");
} else if (memTileFieldFromBlob) {
xrt_core::message::send(severity_level::info, "XRT",
"AIE dtrace: mem tile metric '" + *ci.mem_tile
+ "' from profiling_runtime_config will be supported in a follow-up.");
}
}
else {
l2L2TransferEnabled = iniL2L2Enabled;
}

if (blobPortsSet && !l2L2FromBlob) {
xrt_core::message::send(severity_level::error, "XRT",
"AIE dtrace: profiling_runtime_config.control_instrumentation.memory_tile_input_ports "
"is set but mem_tile is not 'input_ports'. Set "
"\"mem_tile\": \"input_ports\" under control_instrumentation to enable L2-L2.");
}

if (iniPortsSet && !iniL2L2Enabled && !memTileUsesBlob) {
xrt_core::message::send(severity_level::error, "XRT",
"AIE dtrace: AIE_dtrace_settings.memory_tile_input_ports is set but "
"tile_based_memory_tile_metrics does not include 'input_ports'. Add "
"tile_based_memory_tile_metrics=all:input_ports (or equivalent) to enable L2-L2.");
}

if (l2L2TransferEnabled) {
const std::string portsStr = profiling_runtime_config::resolveMemoryTileInputPorts();
const auto designPoints = aie::dtrace::parseL2L2DesignPoints(portsStr);
if (designPoints.empty()) {
if (portsStr.empty()) {
if (l2L2FromBlob) {
xrt_core::message::send(severity_level::error, "XRT",
"AIE dtrace: profiling_runtime_config.control_instrumentation.mem_tile is "
"'input_ports' but memory_tile_input_ports is missing or empty. Add design points "
"as a {column,row:port} list under control_instrumentation "
"(e.g. \"memory_tile_input_ports\": \"{1,1:2},{5,1:1},{5,1:2}\"). "
"L2-L2 counters will not be appended to the CT.");
} else {
xrt_core::message::send(severity_level::error, "XRT",
"AIE dtrace: AIE_dtrace_settings.tile_based_memory_tile_metrics includes "
"'input_ports' but memory_tile_input_ports is missing or empty. Add design points "
"as a {column,row:port} list in xrt.ini "
"(e.g. memory_tile_input_ports={1,1:2},{5,1:1},{5,1:2}). "
"L2-L2 counters will not be appended to the CT.");
}
} else {
xrt_core::message::send(severity_level::warning, "XRT",
"AIE dtrace: L2-L2 is enabled but memory_tile_input_ports is invalid "
"(expected {column,row:port} entries; column is partition-relative, "
"0 = partition start). "
"L2-L2 counters will not be appended to the CT.");
}
l2L2TransferEnabled = false;
}
}

xrt_core::message::send(severity_level::info, "XRT", "Finished parsing AIE dtrace metadata.");
}

Expand All @@ -105,6 +193,8 @@ namespace xdp {
const std::set<std::string> validSettings {
"tile_based_interface_tile_metrics",
"tile_based_aie_metrics",
"tile_based_memory_tile_metrics",
"memory_tile_input_ports",
"configure_aie_hardware",
"config_one_partition",
};
Expand Down
3 changes: 3 additions & 0 deletions profile/plugin/aie_dtrace/aie_dtrace_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class AieDtraceMetadata {
double clockFreqMhz = 0.0;
void* handle = nullptr;
bool configOnePartition = false;
bool l2L2TransferEnabled = false;

std::vector<std::map<tile_type, std::string>> configMetrics;
std::map<tile_type, uint8_t> configChannel0;
Expand Down Expand Up @@ -63,6 +64,8 @@ class AieDtraceMetadata {

bool isConfigOnePartition() const { return configOnePartition; }

bool isL2L2Enabled() const { return l2L2TransferEnabled; }

bool aieMetadataEmpty() { return metadataReader == nullptr; }

std::vector<std::string> getSettingsVector(std::string settingsString);
Expand Down
87 changes: 87 additions & 0 deletions profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "xdp/profile/plugin/aie_dtrace/util/aie_dtrace_util.h"

#include <map>
#include <regex>
#include "core/common/config_reader.h"
#include "core/common/message.h"

Expand All @@ -16,6 +18,30 @@ namespace xdp::aie::dtrace {
using severity_level = xrt_core::message::severity_level;

static constexpr unsigned int DEFAULT_COALESCE_RESULT_MEMORY_MB = 256;

void addPortCounterPair(std::vector<L2L2CounterPoint>& points,
uint8_t column,
uint8_t portIndex,
uint8_t runningCounter,
uint8_t stalledCounter)
{
L2L2CounterPoint running;
running.column = column;
running.row = MEM_TILE_ROW_START;
running.portIndex = portIndex;
running.counterNumber = runningCounter;
running.eventType = "running";
points.push_back(running);

L2L2CounterPoint stalled;
stalled.column = column;
stalled.row = MEM_TILE_ROW_START;
stalled.portIndex = portIndex;
stalled.counterNumber = stalledCounter;
stalled.eventType = "stalled";
points.push_back(stalled);
}

} // anonymous namespace

void
Expand Down Expand Up @@ -88,4 +114,65 @@ namespace xdp::aie::dtrace {
};
}

std::vector<L2L2InstrumentPoint> parseL2L2DesignPoints(const std::string& spec)
{
std::vector<L2L2InstrumentPoint> points;
if (spec.empty())
return points;

// Format: {column,row:port} — column is partition-relative (0 = partition
// start_col); row is accepted for readability only (ignored).
static const std::regex pointRegex(R"(\{\s*(\d+)\s*,\s*(\d+)\s*:\s*(\d+)\s*\})");
const auto begin = std::sregex_iterator(spec.begin(), spec.end(), pointRegex);
const auto end = std::sregex_iterator();
for (auto it = begin; it != end; ++it) {
try {
const unsigned long column = std::stoul((*it)[1].str());
const unsigned long dstPort = std::stoul((*it)[3].str());
if (column > 255 || (dstPort != 1 && dstPort != 2))
continue;

L2L2InstrumentPoint point;
point.column = static_cast<uint8_t>(column);
point.dstPort = static_cast<uint8_t>(dstPort);
points.push_back(point);
}
catch (const std::exception&) {
continue;
}
}
return points;
}

std::vector<L2L2CounterPoint> getL2L2CounterPoints(
uint32_t numCols,
const std::vector<L2L2InstrumentPoint>& instrumentPoints)
{
if (numCols == 0 || instrumentPoints.empty())
return {};

// Design-point columns are partition-relative (0 .. numCols-1). Counters and
// CT addresses use the same relative column as the rest of the CT writer.
std::vector<L2L2CounterPoint> points;
points.reserve(instrumentPoints.size() * 2);

// Assign counters 0-1 for the first dst path on a tile, 2-3 for the second.
std::map<uint8_t, uint8_t> nextCounterByColumn;
for (const auto& instrumentPoint : instrumentPoints) {
const uint32_t column = instrumentPoint.column;
if (column >= numCols)
continue;

uint8_t& nextCounter = nextCounterByColumn[instrumentPoint.column];
if (nextCounter >= L2L2_MAX_DST_PATHS_PER_COLUMN * 2)
continue;

addPortCounterPair(points, instrumentPoint.column, instrumentPoint.dstPort,
nextCounter, static_cast<uint8_t>(nextCounter + 1));
nextCounter = static_cast<uint8_t>(nextCounter + 2);
}

return points;
}

} // namespace xdp::aie::dtrace
34 changes: 34 additions & 0 deletions profile/plugin/aie_dtrace/util/aie_dtrace_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef AIE_DTRACE_UTIL_DOT_H
#define AIE_DTRACE_UTIL_DOT_H

#include <cstdint>
#include <map>
#include <string>
#include <vector>
Expand All @@ -17,6 +18,39 @@ namespace xdp::aie::dtrace {
// Shim bandwidth metric sets used for Debug.aie_dtrace (not part of standard aie_profile ini).
std::map<std::string, std::vector<XAie_Events>> getBandwidthInterfaceTileEventSets(int hwGen);

// ===========================L2L2 transfer metrics ==========================================

// Inter-stamp memtile halo dst paths; design points come from xrt.ini.
// Max dst halo paths per memtile column (4 perf counters, running+stalled per path).
static constexpr uint8_t L2L2_MAX_DST_PATHS_PER_COLUMN = 2;
// Memtile row 1 (absolute array row 1; row 0 = shim/interface tile).
static constexpr uint8_t MEM_TILE_ROW_START = 1;

struct L2L2InstrumentPoint {
uint8_t column = 0;
uint8_t dstPort = 1;
};

// One perf counter at a memtile dst halo path (running or stalled).
struct L2L2CounterPoint {
uint8_t column = 0;
uint8_t row = 0;
uint8_t portIndex = 1; // halo dst port (1 = from left neighbor, 2 = from right)
uint8_t counterNumber = 0; // memtile perf counter 0-3 on this tile
std::string eventType; // "running" or "stalled"
};

// Parses memory_tile_input_ports, e.g. "{1,1:2},{5,1:1},{5,1:2}".
// Column is partition-relative (0 = partition start_col); row is ignored.
std::vector<L2L2InstrumentPoint> parseL2L2DesignPoints(const std::string& spec);

// Builds running+stalled counter pairs from design points within the partition.
// Columns in instrumentPoints are partition-relative (0 .. numCols-1).
std::vector<L2L2CounterPoint> getL2L2CounterPoints(
uint32_t numCols,
const std::vector<L2L2InstrumentPoint>& instrumentPoints);

// ========================================================================================
// Apply JSON + coalesced dtrace_dump defaults when those keys are absent.
// Values already present in xrt.ini or the environment are left unchanged.
// Must run before XRT creates the first dtrace module (config keys lock on first read).
Expand Down
Loading
Loading