From faea8d117ea9101e71b2cbed76854fd69c132a65 Mon Sep 17 00:00:00 2001 From: predutta Date: Fri, 21 Aug 2026 18:02:41 -0700 Subject: [PATCH 01/11] merged l2-l2 transfers changes with universal designs Signed-off-by: predutta --- .../plugin/aie_dtrace/aie_dtrace_metadata.cpp | 48 +++++- .../plugin/aie_dtrace/aie_dtrace_metadata.h | 3 + .../aie_dtrace/util/aie_dtrace_util.cpp | 88 ++++++++++- .../plugin/aie_dtrace/util/aie_dtrace_util.h | 35 +++++ .../aie_dtrace/ve2/aie_dtrace_ct_writer.cpp | 148 +++++++++++++++++- .../aie_dtrace/ve2/aie_dtrace_ct_writer.h | 20 +++ .../plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp | 8 +- 7 files changed, 340 insertions(+), 10 deletions(-) diff --git a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp index 8353a898..2ff6044f 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp @@ -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 { @@ -35,6 +36,21 @@ namespace xdp { return metrics; } + static constexpr const char* L2L2_TRANSFER_METRIC_SET = "l2_l2_transfer"; + + bool settingsRequestL2L2Transfer(const std::vector& metricsSettings) + { + for (const auto& setting : metricsSettings) { + std::vector parts; + boost::split(parts, setting, boost::is_any_of(":")); + for (const auto& part : parts) { + if (part == L2L2_TRANSFER_METRIC_SET) + return true; + } + } + return false; + } + AieDtraceMetadata::AieDtraceMetadata(uint64_t deviceID, void* handle) : deviceID(deviceID) , handle(handle) @@ -55,9 +71,27 @@ namespace xdp { 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."); + if (*ci.mem_tile == L2L2_TRANSFER_METRIC_SET) { + l2L2TransferEnabled = 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 { + 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."); + } + } + } + + if (l2L2TransferEnabled) { + const auto designPoints = aie::dtrace::parseL2L2DesignPoints( + xrt_core::config::get_aie_dtrace_settings_l2_l2_design_points()); + if (designPoints.empty()) { + xrt_core::message::send(severity_level::warning, "XRT", + "AIE dtrace: L2-L2 is enabled but AIE_dtrace_settings.l2_l2_design_points is " + "empty or invalid (expected {column,row:port} entries). " + "L2-L2 counters will not be appended to the CT."); } } @@ -105,6 +139,8 @@ namespace xdp { const std::set validSettings { "tile_based_interface_tile_metrics", "tile_based_aie_metrics", + "tile_based_memory_tile_metrics", + "l2_l2_design_points", "configure_aie_hardware", "config_one_partition", }; @@ -113,6 +149,12 @@ namespace xdp { if (auto val = tree.get_optional("config_one_partition")) configOnePartition = *val; + l2L2TransferEnabled = false; + const std::string memTileSettings = + xrt_core::config::get_aie_dtrace_settings_tile_based_memory_tile_metrics(); + if (!memTileSettings.empty()) + l2L2TransferEnabled = settingsRequestL2L2Transfer(getSettingsVector(memTileSettings)); + for (ptree::iterator pos = tree.begin(); pos != tree.end(); pos++) { if (validSettings.find(pos->first) == validSettings.end()) { std::stringstream msg; diff --git a/profile/plugin/aie_dtrace/aie_dtrace_metadata.h b/profile/plugin/aie_dtrace/aie_dtrace_metadata.h index 520d44e6..23b5acad 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.h +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.h @@ -31,6 +31,7 @@ class AieDtraceMetadata { double clockFreqMhz = 0.0; void* handle = nullptr; bool configOnePartition = false; + bool l2L2TransferEnabled = false; std::vector> configMetrics; std::map configChannel0; @@ -63,6 +64,8 @@ class AieDtraceMetadata { bool isConfigOnePartition() const { return configOnePartition; } + bool isL2L2Enabled() const { return l2L2TransferEnabled; } + bool aieMetadataEmpty() { return metadataReader == nullptr; } std::vector getSettingsVector(std::string settingsString); diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp index 89749265..68b09e50 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp @@ -8,7 +8,9 @@ #include "core/common/config_reader.h" #include "core/common/message.h" +#include #include +#include namespace xdp::aie::dtrace { @@ -16,7 +18,31 @@ namespace xdp::aie::dtrace { using severity_level = xrt_core::message::severity_level; static constexpr unsigned int DEFAULT_COALESCE_RESULT_MEMORY_MB = 256; - } // anonymous namespace + + void addPortCounterPair(std::vector& 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); + } + + } // namespace void initDtraceOutputConfig() @@ -61,4 +87,64 @@ namespace xdp::aie::dtrace { }; } + std::vector parseL2L2DesignPoints(const std::string& spec) + { + std::vector points; + if (spec.empty()) + return points; + + // Format: {column,row:port} — row is accepted for INI 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(column); + point.dstPort = static_cast(dstPort); + points.push_back(point); + } + catch (const std::exception&) { + continue; + } + } + return points; + } + + std::vector getL2L2CounterPoints( + uint32_t startCol, + uint32_t numCols, + const std::vector& instrumentPoints) + { + if (numCols == 0 || instrumentPoints.empty()) + return {}; + + const uint32_t endCol = startCol + numCols; + std::vector 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 nextCounterByColumn; + for (const auto& instrumentPoint : instrumentPoints) { + const uint32_t column = instrumentPoint.column; + if (column < startCol || column >= endCol) + 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(nextCounter + 1)); + nextCounter = static_cast(nextCounter + 2); + } + + return points; + } + } // namespace xdp::aie::dtrace diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h index a8210658..7f5392fb 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h @@ -4,6 +4,7 @@ #ifndef AIE_DTRACE_UTIL_DOT_H #define AIE_DTRACE_UTIL_DOT_H +#include #include #include #include @@ -17,6 +18,40 @@ namespace xdp::aie::dtrace { // Shim bandwidth metric sets used for Debug.aie_dtrace (not part of standard aie_profile ini). std::map> 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 0 (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 AIE_dtrace_settings.l2_l2_design_points, e.g. "{1,1:2},{5,1:1},{5,1:2}". + // INI uses {column,row:port} for readability; row is ignored — counters use MEM_TILE_ROW_START. + std::vector parseL2L2DesignPoints(const std::string& spec); + + // Builds running+stalled counter pairs from xrt.ini design points within the partition. + std::vector getL2L2CounterPoints( + uint32_t startCol, + uint32_t numCols, + const std::vector& instrumentPoints); + + // ======================================================================================== + // Enable JSON dtrace_dump output with coalesced results by default. // Must run before XRT creates the first dtrace module (config keys lock on first read). void initDtraceOutputConfig(); diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp index e35383d4..fa47c47b 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -5,10 +5,12 @@ #include "xdp/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.h" #include "xdp/profile/plugin/aie_dtrace/aie_dtrace_metadata.h" +#include "xdp/profile/plugin/aie_dtrace/util/aie_dtrace_util.h" #include "xdp/profile/database/database.h" #include "xdp/profile/database/static_info/aie_constructs.h" #include "xdp/profile/database/static_info/aie_util.h" +#include "core/common/config_reader.h" #include "core/common/message.h" #include @@ -1059,9 +1061,15 @@ bool AieDtraceCTWriter::writeCounterCTFile( return false; } + const bool hasL2L2Counters = std::any_of(allCounters.begin(), allCounters.end(), + [](const CTCounterInfo& ctr) { return ctr.metricSet == "l2_l2_transfer"; }); + ctFile << "# Auto-generated CT file for AIE counter monitoring\n"; ctFile << "# Generated by XRT AIE Dtrace Plugin\n"; - ctFile << "# Hardware configuration is embedded in the begin block (write_reg)\n\n"; + ctFile << "# Hardware configuration is embedded in the begin block (write_reg)\n"; + if (hasL2L2Counters) + ctFile << "# Memtile L2-L2 inter-stamp halo counters when tile_based_memory_tile_metrics includes l2_l2_transfer\n"; + ctFile << "\n"; ctFile << "begin\n"; ctFile << "{\n"; @@ -1132,7 +1140,6 @@ bool AieDtraceCTWriter::writeCounterCTFile( else ctFile << "null"; - // Add event type for peak bandwidth metrics if (!ctr.eventType.empty()) { ctFile << ", \"event\": "; if (ctr.eventType == "running") @@ -1335,6 +1342,70 @@ void AieDtraceCTWriter::appendComputeIoBoundConfig( beginWrites.insert(beginWrites.end(), memoryWrites.begin(), memoryWrites.end()); } +//=============================================== L2-L2 transfers ================================================ + +void AieDtraceCTWriter::appendL2L2Config( + void* hwctx, + std::vector& counters, + std::vector& beginWrites) +{ + if (!metadata || !metadata->isL2L2Enabled()) + return; + + boost::property_tree::ptree aiePartitionPt = xdp::aie::getAIEPartitionInfo(hwctx); + const uint32_t numCols = aiePartitionPt.empty() ? 0 + : static_cast(aiePartitionPt.back().second.get("num_cols", 0)); + + const auto instrumentPoints = aie::dtrace::parseL2L2DesignPoints( + xrt_core::config::get_aie_dtrace_settings_l2_l2_design_points()); + if (instrumentPoints.empty()) + return; + + auto counterPoints = aie::dtrace::getL2L2CounterPoints( + partitionStartCol, numCols, instrumentPoints); + if (counterPoints.size() != instrumentPoints.size() * 2) { + std::stringstream l2Msg; + l2Msg << "AIE dtrace: L2-L2 design points are invalid for this partition (start_col=" + << static_cast(partitionStartCol) << ", num_cols=" << numCols + << "). Check l2_l2_design_points {column,row:dstPort} entries per memtile (max " + << static_cast(aie::dtrace::L2L2_MAX_DST_PATHS_PER_COLUMN) + << "). Skipping L2-L2 CT append."; + xrt_core::message::send(severity_level::warning, "XRT", l2Msg.str()); + return; + } + + std::map> pointsByColumn; + for (const auto& point : counterPoints) + pointsByColumn[point.column].push_back(point); + + for (const auto& entry : pointsByColumn) { + auto pcWrites = generateMemtilePerfCounterConfig(entry.first, entry.second); + beginWrites.insert(beginWrites.end(), pcWrites.begin(), pcWrites.end()); + } + + for (const auto& point : counterPoints) { + CTCounterInfo info; + info.column = point.column; + info.row = point.row; + info.counterNumber = point.counterNumber; + info.channel = point.portIndex; + info.module = "memory_tile"; + info.address = calculateCounterAddress(point.column, point.row, point.counterNumber, + "memory_tile"); + info.metricSet = "l2_l2_transfer"; + info.portDirection = "input"; + info.eventType = point.eventType; + counters.push_back(info); + } + + std::stringstream l2Msg; + l2Msg << "AIE dtrace: Appending " << counterPoints.size() + << " inter-stamp memtile L2-L2 counters to CT (start_col=" + << static_cast(partitionStartCol) << ", num_cols=" << numCols << ")"; + xrt_core::message::send(severity_level::info, "XRT", l2Msg.str()); +} +//============================================================================================================ + bool AieDtraceCTWriter::generateCT( const std::string& outputPath, void* hwctx, @@ -1362,14 +1433,17 @@ bool AieDtraceCTWriter::generateCT( // Both metric families can be emitted into the same CT file. Bandwidth counters live // on shim tiles (row 0); the compute_io_bound counters live on the core and memory - // modules of a single tile (col 0, first core row). filterCountersByColumn keys by - // column, so both land in the matching UC group and read distinct addresses. + // modules of a single tile (col 0, first core row). Memtile L2-L2 counters are appended + // when enabled. filterCountersByColumn keys by column, so all land in the matching UC + // group and read distinct addresses. if (includeBandwidth) appendBandwidthConfig(hwctx, bandwidthMetricSet, bandwidthChannel, allCounters, beginBlockWrites); if (includeComputeIoBound) appendComputeIoBoundConfig(allCounters, beginBlockWrites); + appendL2L2Config(hwctx, allCounters, beginBlockWrites); + if (allCounters.empty()) { xrt_core::message::send(severity_level::warning, "XRT", "AIE dtrace: No counters configured; CT file will not be generated."); @@ -1568,5 +1642,71 @@ std::vector AieDtraceCTWriter::generateComputeMemoryConfig( return writes; } +// ===========================L2L2 transfer metrics ========================================== +std::vector AieDtraceCTWriter::generateMemtilePerfCounterConfig( + uint8_t column, + const std::vector& counterPoints) +{ + std::vector writes; + if (counterPoints.empty()) + return writes; + + const uint8_t row = counterPoints.front().row; + uint64_t tileAddress = (static_cast(column) << columnShift) | + (static_cast(row) << rowShift); + + uint8_t counterEvents[4] = {0, 0, 0, 0}; + bool counterUsed[4] = {false, false, false, false}; + for (const auto& point : counterPoints) { + if (point.counterNumber > 3) + continue; + if (point.eventType == "stalled") + counterEvents[point.counterNumber] = + static_cast(PORT_STALLED_0_MEM_TILE_EVENT + (point.portIndex * 4)); + else + counterEvents[point.counterNumber] = + static_cast(PORT_RUNNING_0_MEM_TILE_EVENT + (point.portIndex * 4)); + counterUsed[point.counterNumber] = true; + } + + for (uint8_t ctr = 0; ctr < 4; ++ctr) { + if (!counterUsed[ctr]) + continue; + + CTRegisterWrite resetWrite; + resetWrite.address = tileAddress + MEM_TILE_BASE_OFFSET + (ctr * 4); + resetWrite.value = 0; + resetWrite.comment = "Reset memtile PerfCounter" + std::to_string(ctr) + + " @ col " + std::to_string(column); + writes.push_back(resetWrite); + } + + if (counterUsed[0] || counterUsed[1]) { + CTRegisterWrite ctrlWrite; + ctrlWrite.address = tileAddress + MEM_TILE_PERF_CTRL0_OFFSET; + ctrlWrite.value = (static_cast(counterEvents[0]) << 0) + | (static_cast(counterEvents[0]) << 8) + | (static_cast(counterEvents[1]) << 16) + | (static_cast(counterEvents[1]) << 24); + ctrlWrite.comment = "Memtile PerfCtrl0 @ col " + std::to_string(column) + + " (PORT_RUNNING/STALLED on dst halo ports)"; + writes.push_back(ctrlWrite); + } + + if (counterUsed[2] || counterUsed[3]) { + CTRegisterWrite ctrlWrite; + ctrlWrite.address = tileAddress + MEM_TILE_PERF_CTRL1_OFFSET; + ctrlWrite.value = (static_cast(counterEvents[2]) << 0) + | (static_cast(counterEvents[2]) << 8) + | (static_cast(counterEvents[3]) << 16) + | (static_cast(counterEvents[3]) << 24); + ctrlWrite.comment = "Memtile PerfCtrl1 @ col " + std::to_string(column) + + " (PORT_RUNNING/STALLED on dst halo ports)"; + writes.push_back(ctrlWrite); + } + + return writes; +} + } // namespace xdp diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.h b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.h index a31a9510..028a3f30 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.h +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.h @@ -13,6 +13,7 @@ #include #include "aiebu/aiebu_assembler.h" +#include "xdp/profile/plugin/aie_dtrace/util/aie_dtrace_util.h" namespace xdp { @@ -346,6 +347,16 @@ class AieDtraceCTWriter { void appendComputeIoBoundConfig(std::vector& counters, std::vector& beginWrites); + /** + * @brief Append memtile L2-L2 counters and begin-block writes from xrt.ini design points + * @param hwctx Hardware context handle for partition column bounds + * @param counters [in,out] Accumulated counter list + * @param beginWrites [in,out] Accumulated begin-block register writes + */ + void appendL2L2Config(void* hwctx, + std::vector& counters, + std::vector& beginWrites); + /** * @brief Generate the core module config for the compute_io_bound tile * @@ -399,6 +410,10 @@ class AieDtraceCTWriter { const std::vector& beginBlockWrites, const std::string& outputPath); + std::vector generateMemtilePerfCounterConfig( + uint8_t column, + const std::vector& counterPoints); + private: VPDatabase* db; std::shared_ptr metadata; @@ -418,8 +433,13 @@ class AieDtraceCTWriter { // Stream switch and performance counter configuration offsets static constexpr uint64_t STREAM_SWITCH_EVENT_PORT_SEL_OFFSET = 0x0003FF00; + static constexpr uint64_t MEM_TILE_PERF_CTRL0_OFFSET = 0x00091000; + static constexpr uint64_t MEM_TILE_PERF_CTRL1_OFFSET = 0x00091004; static constexpr uint64_t PERF_CTRL_OFFSET = 0x00031000; + static constexpr uint8_t PORT_RUNNING_0_MEM_TILE_EVENT = 80; // PORT_RUNNING_N = 80 + 4*N + static constexpr uint8_t PORT_STALLED_0_MEM_TILE_EVENT = 81; // PORT_STALLED_N = 81 + 4*N + // Core (aie) module offsets for the compute_io_bound metric (aie2ps). // Performance_Control0 (0x00037500) is deliberately never written: it holds counter // 0's start/stop events, and the driver's ECC scrubbing owns core counter 0 diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp index e557092d..28127831 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp @@ -144,7 +144,7 @@ namespace xdp { + std::to_string(bandwidthChannel) + ") from configuration"); } - if (!includeBandwidth && !includeComputeIoBound) { + if (!includeBandwidth && !includeComputeIoBound && !metadata->isL2L2Enabled()) { xrt_core::message::send(severity_level::info, "XRT", "AIE dtrace: No metrics configured; skipping CT generation."); return; @@ -161,10 +161,14 @@ namespace xdp { genMsg << "AIE dtrace: CT generated for kernel '" << kernel_name << "' ("; if (includeBandwidth) genMsg << "interface_tile=" << bandwidthMetricSet; - if (includeBandwidth && includeComputeIoBound) + if (includeBandwidth && (includeComputeIoBound || metadata->isL2L2Enabled())) genMsg << ", "; if (includeComputeIoBound) genMsg << "aie_tile=compute_io_bound (core tiles 0_0 and 0_1)"; + if (includeComputeIoBound && metadata->isL2L2Enabled()) + genMsg << ", "; + if (metadata->isL2L2Enabled()) + genMsg << "memtile=l2_l2_transfer"; genMsg << ")"; xrt_core::message::send(severity_level::debug, "XRT", genMsg.str()); From b794e58c42fd082abd1b9581705fd1507109c8cb Mon Sep 17 00:00:00 2001 From: predutta Date: Wed, 26 Aug 2026 18:30:48 -0600 Subject: [PATCH 02/11] Rename memtile L2-L2 xrt.ini settings to input_ports naming. Use memory_tile_input_ports for design-point lists and input_ports as the tile_based_memory_tile_metrics value, matching updated XRT getters. Co-authored-by: Cursor --- profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp | 12 ++++++------ profile/plugin/aie_dtrace/util/aie_dtrace_util.h | 2 +- .../plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp | 10 +++++----- profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp index 14fd9f8d..20d7cc77 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp @@ -36,7 +36,7 @@ namespace xdp { return metrics; } - static constexpr const char* L2L2_TRANSFER_METRIC_SET = "l2_l2_transfer"; + static constexpr const char* INPUT_PORTS_METRIC_SET = "input_ports"; bool settingsRequestL2L2Transfer(const std::vector& metricsSettings) { @@ -44,7 +44,7 @@ namespace xdp { std::vector parts; boost::split(parts, setting, boost::is_any_of(":")); for (const auto& part : parts) { - if (part == L2L2_TRANSFER_METRIC_SET) + if (part == INPUT_PORTS_METRIC_SET) return true; } } @@ -71,7 +71,7 @@ namespace xdp { if (usingBlob) { if (ci.mem_tile.has_value() && !ci.mem_tile->empty()) { - if (*ci.mem_tile == L2L2_TRANSFER_METRIC_SET) { + if (*ci.mem_tile == INPUT_PORTS_METRIC_SET) { l2L2TransferEnabled = true; xrt_core::message::send(severity_level::info, "XRT", "AIE dtrace: enabling L2-L2 via mem_tile metric '" + *ci.mem_tile @@ -86,10 +86,10 @@ namespace xdp { if (l2L2TransferEnabled) { const auto designPoints = aie::dtrace::parseL2L2DesignPoints( - xrt_core::config::get_aie_dtrace_settings_l2_l2_design_points()); + xrt_core::config::get_aie_dtrace_settings_memory_tile_input_ports()); if (designPoints.empty()) { xrt_core::message::send(severity_level::warning, "XRT", - "AIE dtrace: L2-L2 is enabled but AIE_dtrace_settings.l2_l2_design_points is " + "AIE dtrace: L2-L2 is enabled but AIE_dtrace_settings.memory_tile_input_ports is " "empty or invalid (expected {column,row:port} entries). " "L2-L2 counters will not be appended to the CT."); } @@ -140,7 +140,7 @@ namespace xdp { "tile_based_interface_tile_metrics", "tile_based_aie_metrics", "tile_based_memory_tile_metrics", - "l2_l2_design_points", + "memory_tile_input_ports", "configure_aie_hardware", "config_one_partition", }; diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h index 2133746c..cdfcc2a3 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h @@ -40,7 +40,7 @@ namespace xdp::aie::dtrace { std::string eventType; // "running" or "stalled" }; - // Parses AIE_dtrace_settings.l2_l2_design_points, e.g. "{1,1:2},{5,1:1},{5,1:2}". + // Parses AIE_dtrace_settings.memory_tile_input_ports, e.g. "{1,1:2},{5,1:1},{5,1:2}". // INI uses {column,row:port} for readability; row is ignored — counters use MEM_TILE_ROW_START. std::vector parseL2L2DesignPoints(const std::string& spec); diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp index be4887b4..c164cb53 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -1059,13 +1059,13 @@ bool AieDtraceCTWriter::writeCounterCTFile( } const bool hasL2L2Counters = std::any_of(allCounters.begin(), allCounters.end(), - [](const CTCounterInfo& ctr) { return ctr.metricSet == "l2_l2_transfer"; }); + [](const CTCounterInfo& ctr) { return ctr.metricSet == "input_ports"; }); ctFile << "# Auto-generated CT file for AIE counter monitoring\n"; ctFile << "# Generated by XRT AIE Dtrace Plugin\n"; ctFile << "# Hardware configuration is embedded in the begin block (write_reg)\n"; if (hasL2L2Counters) - ctFile << "# Memtile L2-L2 inter-stamp halo counters when tile_based_memory_tile_metrics includes l2_l2_transfer\n"; + ctFile << "# Memtile L2-L2 inter-stamp halo counters when tile_based_memory_tile_metrics includes input_ports\n"; ctFile << "\n"; ctFile << "begin\n"; @@ -1387,7 +1387,7 @@ void AieDtraceCTWriter::appendL2L2Config( : static_cast(aiePartitionPt.back().second.get("num_cols", 0)); const auto instrumentPoints = aie::dtrace::parseL2L2DesignPoints( - xrt_core::config::get_aie_dtrace_settings_l2_l2_design_points()); + xrt_core::config::get_aie_dtrace_settings_memory_tile_input_ports()); if (instrumentPoints.empty()) return; @@ -1397,7 +1397,7 @@ void AieDtraceCTWriter::appendL2L2Config( std::stringstream l2Msg; l2Msg << "AIE dtrace: L2-L2 design points are invalid for this partition (start_col=" << static_cast(partitionStartCol) << ", num_cols=" << numCols - << "). Check l2_l2_design_points {column,row:dstPort} entries per memtile (max " + << "). Check memory_tile_input_ports {column,row:dstPort} entries per memtile (max " << static_cast(aie::dtrace::L2L2_MAX_DST_PATHS_PER_COLUMN) << "). Skipping L2-L2 CT append."; xrt_core::message::send(severity_level::warning, "XRT", l2Msg.str()); @@ -1422,7 +1422,7 @@ void AieDtraceCTWriter::appendL2L2Config( info.module = "memory_tile"; info.address = calculateCounterAddress(point.column, point.row, point.counterNumber, "memory_tile"); - info.metricSet = "l2_l2_transfer"; + info.metricSet = "input_ports"; info.portDirection = "input"; info.eventType = point.eventType; counters.push_back(info); diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp index eeac8fb1..509147a8 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp @@ -163,7 +163,7 @@ namespace xdp { if (!coreMetricSet.empty() && metadata->isL2L2Enabled()) genMsg << ", "; if (metadata->isL2L2Enabled()) - genMsg << "memtile=l2_l2_transfer"; + genMsg << "memtile=input_ports"; genMsg << ")"; xrt_core::message::send(severity_level::debug, "XRT", genMsg.str()); From 9ff4d21f0a7d8e5e9724cef9f7e929f7f96d925a Mon Sep 17 00:00:00 2001 From: predutta Date: Thu, 3 Sep 2026 16:21:37 -0600 Subject: [PATCH 03/11] Add memory_tile_input_ports to control_instrumentation blob for L2-L2. Parse memory_tile_input_ports from profiling_runtime_config, resolve ports via blob when mem_tile is input_ports, and validate both enable and port fields for blob and xrt.ini flows with bidirectional error handling. Co-authored-by: Cursor --- .../plugin/aie_dtrace/aie_dtrace_metadata.cpp | 111 +++++++++++++----- .../aie_dtrace/ve2/aie_dtrace_ct_writer.cpp | 3 +- .../vp_base/profiling_runtime_config.cpp | 38 +++++- .../plugin/vp_base/profiling_runtime_config.h | 12 +- 4 files changed, 126 insertions(+), 38 deletions(-) diff --git a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp index 20d7cc77..52cf1c02 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp @@ -69,32 +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()) { - if (*ci.mem_tile == INPUT_PORTS_METRIC_SET) { - l2L2TransferEnabled = 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 { - 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."); - } - } - } - - if (l2L2TransferEnabled) { - const auto designPoints = aie::dtrace::parseL2L2DesignPoints( - xrt_core::config::get_aie_dtrace_settings_memory_tile_input_ports()); - if (designPoints.empty()) { - xrt_core::message::send(severity_level::warning, "XRT", - "AIE dtrace: L2-L2 is enabled but AIE_dtrace_settings.memory_tile_input_ports is " - "empty or invalid (expected {column,row:port} entries). " - "L2-L2 counters will not be appended to the CT."); - } - } - // 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 aieMetricsSettings; @@ -130,6 +104,85 @@ 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 appears 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). " + "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."); } @@ -149,12 +202,6 @@ namespace xdp { if (auto val = tree.get_optional("config_one_partition")) configOnePartition = *val; - l2L2TransferEnabled = false; - const std::string memTileSettings = - xrt_core::config::get_aie_dtrace_settings_tile_based_memory_tile_metrics(); - if (!memTileSettings.empty()) - l2L2TransferEnabled = settingsRequestL2L2Transfer(getSettingsVector(memTileSettings)); - for (ptree::iterator pos = tree.begin(); pos != tree.end(); pos++) { if (validSettings.find(pos->first) == validSettings.end()) { std::stringstream msg; diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp index c164cb53..adab64e3 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -12,6 +12,7 @@ #include "core/common/config_reader.h" #include "core/common/message.h" +#include "xdp/profile/plugin/vp_base/profiling_runtime_config.h" #include #include @@ -1387,7 +1388,7 @@ void AieDtraceCTWriter::appendL2L2Config( : static_cast(aiePartitionPt.back().second.get("num_cols", 0)); const auto instrumentPoints = aie::dtrace::parseL2L2DesignPoints( - xrt_core::config::get_aie_dtrace_settings_memory_tile_input_ports()); + profiling_runtime_config::resolveMemoryTileInputPorts()); if (instrumentPoints.empty()) return; diff --git a/profile/plugin/vp_base/profiling_runtime_config.cpp b/profile/plugin/vp_base/profiling_runtime_config.cpp index 5be86045..6daaa7e5 100644 --- a/profile/plugin/vp_base/profiling_runtime_config.cpp +++ b/profile/plugin/vp_base/profiling_runtime_config.cpp @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 +#// SPDX-License-Identifier: Apache-2.0 // Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved #define XDP_CORE_SOURCE @@ -77,7 +77,7 @@ namespace xdp::profiling_runtime_config { parse_control_instrumentation(const pt::ptree& ci_tree) { static const std::set known_keys{ - "aie_tile", "mem_tile", "interface_tile" + "aie_tile", "mem_tile", "interface_tile", "memory_tile_input_ports" }; control_instrumentation_t ci; @@ -101,6 +101,12 @@ namespace xdp::profiling_runtime_config { if (!value.empty()) info("profiling_runtime_config.control_instrumentation.interface_tile='" + value + "'"); } + else if (key == "memory_tile_input_ports") { + ci.memory_tile_input_ports = value; + if (!value.empty()) + info("profiling_runtime_config.control_instrumentation.memory_tile_input_ports='" + + value + "'"); + } else { std::stringstream msg; msg << "Unknown key 'profiling_runtime_config.control_instrumentation." @@ -198,7 +204,8 @@ namespace xdp::profiling_runtime_config { out.ci = parse_control_instrumentation(*ci_opt); out.has_ci = out.ci.aie_tile.has_value() || out.ci.mem_tile.has_value() - || out.ci.interface_tile.has_value(); + || out.ci.interface_tile.has_value() + || out.ci.memory_tile_input_ports.has_value(); } if (const auto et_opt = root.get_child_optional("event_trace")) { @@ -252,6 +259,31 @@ namespace xdp::profiling_runtime_config { return get_parsed().ci; } + std::string + resolveMemoryTileInputPorts() + { + static constexpr const char* INPUT_PORTS_METRIC_SET = "input_ports"; + + if (has_control_instrumentation()) { + const auto& ci = control_instrumentation(); + const bool memTileFieldFromBlob = ci.mem_tile.has_value() && !ci.mem_tile->empty(); + const bool blobPortsSet = ci.memory_tile_input_ports.has_value() + && !ci.memory_tile_input_ports->empty(); + const bool memTileUsesBlob = memTileFieldFromBlob || blobPortsSet; + + if (memTileFieldFromBlob && *ci.mem_tile == INPUT_PORTS_METRIC_SET) { + if (blobPortsSet) + return *ci.memory_tile_input_ports; + return {}; + } + + // Partial blob mem-tile config: do not fall back to xrt.ini ports. + if (memTileUsesBlob) + return {}; + } + return xrt_core::config::get_aie_dtrace_settings_memory_tile_input_ports(); + } + bool has_event_trace() { diff --git a/profile/plugin/vp_base/profiling_runtime_config.h b/profile/plugin/vp_base/profiling_runtime_config.h index f3685c06..7271b000 100644 --- a/profile/plugin/vp_base/profiling_runtime_config.h +++ b/profile/plugin/vp_base/profiling_runtime_config.h @@ -26,7 +26,8 @@ // load-time gate. // // Example blob: -// {"control_instrumentation":{"aie_tile":"func_stalls","mem_tile":"","interface_tile":"ddr_bandwidth"},"event_trace":{"tile_based_aie_tile_metrics":"all:functions"}} +// {"control_instrumentation":{"aie_tile":"func_stalls","mem_tile":"input_ports","interface_tile":"ddr_bandwidth", +// "memory_tile_input_ports":"{1,1:2},{5,1:1}"},"event_trace":{"tile_based_aie_tile_metrics":"all:functions"}} namespace xdp::profiling_runtime_config { @@ -34,6 +35,7 @@ namespace xdp::profiling_runtime_config { std::optional aie_tile; // maps to "core" module internally std::optional mem_tile; // maps to "mem_tile" module internally std::optional interface_tile; // maps to "shim" module internally + std::optional memory_tile_input_ports; // L2-L2 {column,row:port} list }; // Mirrors the AIE_trace_settings.* xrt.ini keys 1:1. When event_trace is @@ -106,13 +108,19 @@ namespace xdp::profiling_runtime_config { XDP_CORE_EXPORT bool is_set(); // True when is_set() and the blob contained a control_instrumentation object - // with at least one recognized key (aie_tile / mem_tile / interface_tile). + // with at least one recognized key (aie_tile / mem_tile / interface_tile / + // memory_tile_input_ports). XDP_CORE_EXPORT bool has_control_instrumentation(); // Returns the cached control_instrumentation view. Safe to call even when // has_control_instrumentation() is false (all members will be empty). XDP_CORE_EXPORT const control_instrumentation_t& control_instrumentation(); + // When control_instrumentation carries mem_tile or memory_tile_input_ports, + // ports come only from the blob (requires mem_tile "input_ports"). Otherwise + // AIE_dtrace_settings.memory_tile_input_ports from xrt.ini is used. + XDP_CORE_EXPORT std::string resolveMemoryTileInputPorts(); + // True when is_set() and the blob contained an "event_trace" object (even // if empty). Note this only reflects presence in the blob - it is NOT an // AIE trace enablement signal by itself; see aie_trace_enabled() in From 6db1bc157955f7f69160052f5cee5c4e5c350668 Mon Sep 17 00:00:00 2001 From: predutta Date: Thu, 3 Sep 2026 17:02:07 -0600 Subject: [PATCH 04/11] Treat memory_tile_input_ports columns as partition-relative. Design points use columns 0 .. num_cols-1 (0 = partition start_col), matching getShimTileColumns() and calculateCounterAddress(). Clarify startCol is for logging only and update L2-L2 validation messages. Co-authored-by: Cursor --- profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp | 3 ++- profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp | 9 ++++++--- profile/plugin/aie_dtrace/util/aie_dtrace_util.h | 7 ++++--- profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp | 3 ++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp index 52cf1c02..b57aec36 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp @@ -176,7 +176,8 @@ namespace xdp { } 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). " + "(expected {column,row:port} entries; column is partition-relative, " + "0 = partition start). " "L2-L2 counters will not be appended to the CT."); } l2L2TransferEnabled = false; diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp index 4244af28..447547f7 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp @@ -62,7 +62,8 @@ namespace xdp::aie::dtrace { if (spec.empty()) return points; - // Format: {column,row:port} — row is accepted for INI readability only (ignored). + // 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(); @@ -93,7 +94,8 @@ namespace xdp::aie::dtrace { if (numCols == 0 || instrumentPoints.empty()) return {}; - const uint32_t endCol = startCol + numCols; + // 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 points; points.reserve(instrumentPoints.size() * 2); @@ -101,7 +103,7 @@ namespace xdp::aie::dtrace { std::map nextCounterByColumn; for (const auto& instrumentPoint : instrumentPoints) { const uint32_t column = instrumentPoint.column; - if (column < startCol || column >= endCol) + if (column >= numCols) continue; uint8_t& nextCounter = nextCounterByColumn[instrumentPoint.column]; @@ -113,6 +115,7 @@ namespace xdp::aie::dtrace { nextCounter = static_cast(nextCounter + 2); } + (void)startCol; return points; } diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h index cdfcc2a3..5efbb89a 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h @@ -40,11 +40,12 @@ namespace xdp::aie::dtrace { std::string eventType; // "running" or "stalled" }; - // Parses AIE_dtrace_settings.memory_tile_input_ports, e.g. "{1,1:2},{5,1:1},{5,1:2}". - // INI uses {column,row:port} for readability; row is ignored — counters use MEM_TILE_ROW_START. + // 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 parseL2L2DesignPoints(const std::string& spec); - // Builds running+stalled counter pairs from xrt.ini design points within the partition. + // Builds running+stalled counter pairs from design points within the partition. + // startCol is reserved for diagnostics; columns in instrumentPoints are relative. std::vector getL2L2CounterPoints( uint32_t startCol, uint32_t numCols, diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp index 68ae5106..7bebb76e 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -1409,7 +1409,8 @@ void AieDtraceCTWriter::appendL2L2Config( std::stringstream l2Msg; l2Msg << "AIE dtrace: L2-L2 design points are invalid for this partition (start_col=" << static_cast(partitionStartCol) << ", num_cols=" << numCols - << "). Check memory_tile_input_ports {column,row:dstPort} entries per memtile (max " + << "). Check memory_tile_input_ports {column,row:dstPort} entries: column is " + << "partition-relative (0 .. num_cols-1; 0 = start_col), max " << static_cast(aie::dtrace::L2L2_MAX_DST_PATHS_PER_COLUMN) << "). Skipping L2-L2 CT append."; xrt_core::message::send(severity_level::warning, "XRT", l2Msg.str()); From a7c6189621ec430adad273bd2243d43f733d98e8 Mon Sep 17 00:00:00 2001 From: predutta Date: Thu, 3 Sep 2026 17:50:05 -0600 Subject: [PATCH 05/11] Fix SPDX header typo in profiling_runtime_config.cpp. Remove erroneous '#' prefix that broke the build. Co-authored-by: Cursor --- profile/plugin/vp_base/profiling_runtime_config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profile/plugin/vp_base/profiling_runtime_config.cpp b/profile/plugin/vp_base/profiling_runtime_config.cpp index 6daaa7e5..b1b7a217 100644 --- a/profile/plugin/vp_base/profiling_runtime_config.cpp +++ b/profile/plugin/vp_base/profiling_runtime_config.cpp @@ -1,4 +1,4 @@ -#// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: Apache-2.0 // Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved #define XDP_CORE_SOURCE From 851cf6156b8c38fa9e0eecedd2d3e908095ba3d1 Mon Sep 17 00:00:00 2001 From: Prerona Dutta <150398390+predutta@users.noreply.github.com> Date: Thu, 3 Sep 2026 19:27:30 -0700 Subject: [PATCH 06/11] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../aie_dtrace/ve2/aie_dtrace_ct_writer.cpp | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp index 7bebb76e..ceec2e30 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -1394,10 +1394,28 @@ void AieDtraceCTWriter::appendL2L2Config( if (!metadata || !metadata->isL2L2Enabled()) return; - boost::property_tree::ptree aiePartitionPt = xdp::aie::getAIEPartitionInfo(hwctx); - const uint32_t numCols = aiePartitionPt.empty() ? 0 - : static_cast(aiePartitionPt.back().second.get("num_cols", 0)); + if (!hwctx) { + xrt_core::message::send(severity_level::debug, "XRT", + "AIE dtrace: No hwctx provided for L2-L2 configuration"); + return; + } + boost::property_tree::ptree aiePartitionPt; + try { + aiePartitionPt = xdp::aie::getAIEPartitionInfo(hwctx); + } + catch (const std::exception& e) { + xrt_core::message::send(severity_level::warning, "XRT", + std::string("AIE dtrace: Error getting partition info for L2-L2: ") + e.what()); + return; + } + if (aiePartitionPt.empty()) + return; + + const uint32_t numCols = + static_cast(aiePartitionPt.back().second.get("num_cols", 0)); + if (numCols == 0) + return; const auto instrumentPoints = aie::dtrace::parseL2L2DesignPoints( profiling_runtime_config::resolveMemoryTileInputPorts()); if (instrumentPoints.empty()) From 8a2615e1a806662a8086a82d0ebeb107cbd02c38 Mon Sep 17 00:00:00 2001 From: predutta Date: Thu, 3 Sep 2026 20:29:30 -0600 Subject: [PATCH 07/11] Fix MEM_TILE_ROW_START comment in aie_dtrace_util.h. Clarify memtile counters use row 1, not row 0. Co-authored-by: Cursor --- profile/plugin/aie_dtrace/util/aie_dtrace_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h index 5efbb89a..d4b5979c 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h @@ -23,7 +23,7 @@ namespace xdp::aie::dtrace { // 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 0 (absolute array row 1; row 0 = shim/interface tile). + // Memtile row 1 (absolute array row 1; row 0 = shim/interface tile). static constexpr uint8_t MEM_TILE_ROW_START = 1; struct L2L2InstrumentPoint { From e47ad40369628740d40ed647c885b78a81b7672d Mon Sep 17 00:00:00 2001 From: predutta Date: Thu, 3 Sep 2026 20:36:45 -0600 Subject: [PATCH 08/11] Remove unused config_reader include from aie_dtrace_ct_writer. L2-L2 xrt.ini keys are read via profiling_runtime_config and metadata. Co-authored-by: Cursor --- profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp index ceec2e30..d8e924f5 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -10,7 +10,6 @@ #include "xdp/profile/database/static_info/aie_constructs.h" #include "xdp/profile/database/static_info/aie_util.h" -#include "core/common/config_reader.h" #include "core/common/message.h" #include "xdp/profile/plugin/vp_base/profiling_runtime_config.h" From 9f5c950733c0dd92b415788de195970a6db55cd1 Mon Sep 17 00:00:00 2001 From: Prerona Dutta <150398390+predutta@users.noreply.github.com> Date: Wed, 9 Sep 2026 10:33:40 -0700 Subject: [PATCH 09/11] Update comment for memory tile L2-L2 configuration Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp index b57aec36..d6e0872e 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp @@ -105,8 +105,8 @@ 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 appears in control_instrumentation, the - // whole mem-tile L2-L2 config must come from the blob (both fields). Otherwise + // 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(); From c2c9c0ef5d6fcbcc515da92490e76c77614ae167 Mon Sep 17 00:00:00 2001 From: predutta Date: Wed, 16 Sep 2026 12:41:03 -0600 Subject: [PATCH 10/11] Remove unused startCol from getL2L2CounterPoints. L2-L2 columns are partition-relative; partition start_col is only used in CT writer logs. Signed-off-by: predutta Co-authored-by: Cursor --- profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp | 2 -- profile/plugin/aie_dtrace/util/aie_dtrace_util.h | 3 +-- profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp | 3 +-- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp index 447547f7..c6ee38de 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp @@ -87,7 +87,6 @@ namespace xdp::aie::dtrace { } std::vector getL2L2CounterPoints( - uint32_t startCol, uint32_t numCols, const std::vector& instrumentPoints) { @@ -115,7 +114,6 @@ namespace xdp::aie::dtrace { nextCounter = static_cast(nextCounter + 2); } - (void)startCol; return points; } diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h index d4b5979c..b50eb3b7 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.h +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.h @@ -45,9 +45,8 @@ namespace xdp::aie::dtrace { std::vector parseL2L2DesignPoints(const std::string& spec); // Builds running+stalled counter pairs from design points within the partition. - // startCol is reserved for diagnostics; columns in instrumentPoints are relative. + // Columns in instrumentPoints are partition-relative (0 .. numCols-1). std::vector getL2L2CounterPoints( - uint32_t startCol, uint32_t numCols, const std::vector& instrumentPoints); diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp index d8e924f5..fca0e9d0 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -1420,8 +1420,7 @@ void AieDtraceCTWriter::appendL2L2Config( if (instrumentPoints.empty()) return; - auto counterPoints = aie::dtrace::getL2L2CounterPoints( - partitionStartCol, numCols, instrumentPoints); + auto counterPoints = aie::dtrace::getL2L2CounterPoints(numCols, instrumentPoints); if (counterPoints.size() != instrumentPoints.size() * 2) { std::stringstream l2Msg; l2Msg << "AIE dtrace: L2-L2 design points are invalid for this partition (start_col=" From e41ccbb6388678780c90054fb46017fc5f6c7f92 Mon Sep 17 00:00:00 2001 From: predutta Date: Wed, 16 Sep 2026 13:55:37 -0600 Subject: [PATCH 11/11] Fix anonymous namespace merge in aie_dtrace_util.cpp. Keep initDtraceOutputConfig helpers and addPortCounterPair in one block after master merge. Signed-off-by: predutta Co-authored-by: Cursor --- profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp index 5e8190ed..4aee0fe7 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp @@ -15,6 +15,9 @@ namespace xdp::aie::dtrace { namespace { + using severity_level = xrt_core::message::severity_level; + + static constexpr unsigned int DEFAULT_COALESCE_RESULT_MEMORY_MB = 256; void addPortCounterPair(std::vector& points, uint8_t column, @@ -39,10 +42,6 @@ namespace xdp::aie::dtrace { points.push_back(stalled); } - } // namespace - using severity_level = xrt_core::message::severity_level; - - static constexpr unsigned int DEFAULT_COALESCE_RESULT_MEMORY_MB = 256; } // anonymous namespace void