diff --git a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp index 0013e511..c25bf14a 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.cpp @@ -88,12 +88,15 @@ namespace xdp { "tile_based_interface_tile_metrics", "configure_aie_hardware", "config_one_partition", + "l2_l2_transfer_metrics", }; auto tree = xrt_core::config::detail::get_ptree_value("AIE_dtrace_settings"); if (auto val = tree.get_optional("config_one_partition")) configOnePartition = *val; + l2L2TransferEnabled = xrt_core::config::get_aie_dtrace_settings_l2_l2_transfer_metrics(); + 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 f75f99c6..7928b9e8 100644 --- a/profile/plugin/aie_dtrace/aie_dtrace_metadata.h +++ b/profile/plugin/aie_dtrace/aie_dtrace_metadata.h @@ -24,6 +24,7 @@ class AieDtraceMetadata { double clockFreqMhz = 0.0; void* handle = nullptr; bool configOnePartition = false; + bool l2L2TransferEnabled = false; std::vector> configMetrics; std::map configChannel0; @@ -49,6 +50,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 93352107..fd44401d 100644 --- a/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp +++ b/profile/plugin/aie_dtrace/util/aie_dtrace_util.cpp @@ -7,6 +7,33 @@ namespace xdp::aie::dtrace { + 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 + std::map> getBandwidthInterfaceTileEventSets(int hwGen) { @@ -26,4 +53,31 @@ namespace xdp::aie::dtrace { }; } + std::vector getL2L2CounterPoints(uint32_t numCols) + { + if (numCols != L2L2_BASELINE_NUM_COLS) + return {}; + + std::vector points; + points.reserve(L2L2_BASELINE_NUM_COUNTERS); + + // Stamp 0 edge (col 1): one dst path -> ctr 0,1 -> PerfCtrl0 only + addPortCounterPair(points, 1, 2, 0, 1); + + // Stamps 1-4 middle (cols 5, 9, 13, 17): two dst paths -> ctr 0-3 -> PerfCtrl0 + PerfCtrl1 + addPortCounterPair(points, 5, 1, 0, 1); + addPortCounterPair(points, 5, 2, 2, 3); + addPortCounterPair(points, 9, 1, 0, 1); + addPortCounterPair(points, 9, 2, 2, 3); + addPortCounterPair(points, 13, 1, 0, 1); + addPortCounterPair(points, 13, 2, 2, 3); + addPortCounterPair(points, 17, 1, 0, 1); + addPortCounterPair(points, 17, 2, 2, 3); + + // Stamp 5 edge (col 21): one dst path -> ctr 0,1 -> PerfCtrl0 only + addPortCounterPair(points, 21, 1, 0, 1); + + 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 2a49a334..97cc3885 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,29 @@ 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 ========================================== + + // Fixed baseline overlay: 1x6x4x4 (6 stamps, 4 cols/stamp, 24 partition columns). + // Inter-stamp memtile halo dst paths only (AIESW-27919 Type B). + static constexpr uint32_t L2L2_BASELINE_NUM_COLS = 24; + static constexpr uint32_t L2L2_BASELINE_NUM_COUNTERS = 20; + // AIE memtile starting row index on the 1x6x4x4 baseline (row 0 = shim/interface tile). + static constexpr uint8_t MEM_TILE_ROW_START = 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" + }; + + // Returns the fixed 20-counter baseline table when numCols == L2L2_BASELINE_NUM_COLS; else empty. + std::vector getL2L2CounterPoints(uint32_t numCols); + + // ======================================================================================== + } // namespace xdp::aie::dtrace #endif 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 a5f313fa..9e6db570 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ct_writer.cpp @@ -1043,7 +1043,9 @@ bool AieDtraceCTWriter::writeBandwidthCTFile( const std::vector& asmFileInfoList, const std::vector& allCounters, const std::vector& beginBlockWrites, - const std::string& outputPath) + const std::string& outputPath, + const std::vector& l2l2BeginBlockWrites, + const std::vector& allL2l2Counters) { std::ofstream ctFile(outputPath); @@ -1057,7 +1059,10 @@ bool AieDtraceCTWriter::writeBandwidthCTFile( ctFile << "# Auto-generated CT file for AIE bandwidth monitoring\n"; ctFile << "# Generated by XRT AIE Dtrace Plugin (simplified bandwidth mode)\n"; ctFile << "# Fixed 4 counters per shim tile: S2MM ch0,ch1 + MM2S ch0,ch1\n"; - ctFile << "# Post-processing filters by metric: read_bandwidth, write_bandwidth, ddr_bandwidth\n\n"; + ctFile << "# Post-processing filters by metric: read_bandwidth, write_bandwidth, ddr_bandwidth\n"; + if (!allL2l2Counters.empty()) + ctFile << "# Memtile L2-L2 inter-stamp halo counters appended when l2_l2_transfer_metrics=true\n"; + ctFile << "\n"; ctFile << "begin\n"; ctFile << "{\n"; @@ -1075,6 +1080,18 @@ bool AieDtraceCTWriter::writeBandwidthCTFile( ctFile << "\n"; } + if (!l2l2BeginBlockWrites.empty()) { + ctFile << " # Hardware configuration for memtile L2-L2 counters (counter reset + perf ctrl)\n"; + for (const auto& write : l2l2BeginBlockWrites) { + if (!write.comment.empty()) + ctFile << " # " << write.comment << "\n"; + ctFile << " write_reg(" << formatAddress(write.address) + << ", 0x" << std::hex << std::setfill('0') << std::setw(8) + << write.value << std::dec << ")\n"; + } + ctFile << "\n"; + } + ctFile << "@blockopen\n"; ctFile << "# COUNTER_METADATA_BEGIN\n"; ctFile << "# {\n"; @@ -1128,13 +1145,41 @@ bool AieDtraceCTWriter::writeBandwidthCTFile( ctFile << "\n"; } + if (!allL2l2Counters.empty()) { + if (!metaGroups.empty()) + ctFile << ",\n"; + ctFile << "# \"l2_l2\": [\n"; + for (size_t i = 0; i < allL2l2Counters.size(); ++i) { + const auto& ctr = allL2l2Counters[i]; + ctFile << "# {\"col\": " << static_cast(ctr.column) + << ", \"row\": " << static_cast(ctr.row) + << ", \"ctr\": " << static_cast(ctr.counterNumber) + << ", \"module\": \"" << ctr.module << "\""; + if (!ctr.eventType.empty()) { + ctFile << ", \"event\": "; + if (ctr.eventType == "running") + ctFile << "\"r\""; + else if (ctr.eventType == "stalled") + ctFile << "\"s\""; + else + ctFile << "\"" << ctr.eventType << "\""; + } + ctFile << "}"; + if (i + 1 < allL2l2Counters.size()) + ctFile << ","; + ctFile << "\n"; + } + ctFile << "# ]\n"; + } + ctFile << "# }\n"; ctFile << "# COUNTER_METADATA_END\n"; ctFile << "@blockclose\n"; ctFile << "}\n\n"; for (const auto& asmFileInfo : asmFileInfoList) { - if (asmFileInfo.timestamps.empty() || asmFileInfo.counters.empty()) + if (asmFileInfo.timestamps.empty() + || (asmFileInfo.counters.empty() && asmFileInfo.l2l2Counters.empty())) continue; std::string basename = fs::path(asmFileInfo.filename).filename().string(); @@ -1161,6 +1206,11 @@ bool AieDtraceCTWriter::writeBandwidthCTFile( ctFile << " _ = read_reg(" << formatAddress(ctr.address) << ")\n"; } + for (size_t i = 0; i < asmFileInfo.l2l2Counters.size(); i++) { + const auto& ctr = asmFileInfo.l2l2Counters[i]; + ctFile << " _ = read_reg(" << formatAddress(ctr.address) << ")\n"; + } + ctFile << "}\n\n"; } @@ -1173,7 +1223,10 @@ bool AieDtraceCTWriter::writeBandwidthCTFile( std::stringstream msg; msg << "Generated bandwidth CT file: " << outputPath - << " (" << allCounters.size() << " counters)"; + << " (" << allCounters.size() << " shim counters"; + if (!allL2l2Counters.empty()) + msg << ", " << allL2l2Counters.size() << " memtile L2-L2 counters"; + msg << ")"; xrt_core::message::send(severity_level::info, "XRT", msg.str()); return true; @@ -1254,8 +1307,58 @@ bool AieDtraceCTWriter::generateBandwidthCT( extendLastUcToMaxConfiguredColumn(asmFileInfoList, allCounters); + // ========================================= L2-L2 transfer metrics ========================================== + std::vector allL2l2Counters; + std::vector l2l2BeginBlockWrites; + if (metadata && metadata->isL2L2Enabled()) { + 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)); + + auto counterPoints = aie::dtrace::getL2L2CounterPoints(numCols); + if (counterPoints.empty()) { + std::stringstream l2Msg; + l2Msg << "AIE dtrace: L2-L2 counters require the 1x6x4x4 baseline (" + << aie::dtrace::L2L2_BASELINE_NUM_COLS << " columns); partition has " + << numCols << " columns. Skipping L2-L2 CT append."; + xrt_core::message::send(severity_level::warning, "XRT", l2Msg.str()); + } else { + 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); + l2l2BeginBlockWrites.insert(l2l2BeginBlockWrites.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 = 0; + 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; + allL2l2Counters.push_back(info); + } + + std::stringstream l2Msg; + l2Msg << "AIE dtrace: Appending " << allL2l2Counters.size() + << " inter-stamp memtile L2-L2 counters to bandwidth CT (num_cols=" << numCols << ")"; + xrt_core::message::send(severity_level::info, "XRT", l2Msg.str()); + } + } + // ========================================= L2-L2 transfer metrics ========================================== + for (auto& asmFileInfo : asmFileInfoList) { asmFileInfo.counters = filterCountersByColumn(allCounters, asmFileInfo.colStart, asmFileInfo.colEnd); + asmFileInfo.l2l2Counters = filterCountersByColumn(allL2l2Counters, asmFileInfo.colStart, asmFileInfo.colEnd); } std::vector beginBlockWrites; @@ -1269,7 +1372,81 @@ bool AieDtraceCTWriter::generateBandwidthCT( beginBlockWrites.insert(beginBlockWrites.end(), pcWrites.begin(), pcWrites.end()); } - return writeBandwidthCTFile(asmFileInfoList, allCounters, beginBlockWrites, outputPath); + return writeBandwidthCTFile(asmFileInfoList, allCounters, beginBlockWrites, outputPath, + l2l2BeginBlockWrites, allL2l2Counters); +} + +// ===========================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); + + xrt_core::message::send(severity_level::debug, "XRT", + "AIE dtrace L2-L2: memtile perf config col=" + std::to_string(column) + + " row=" + std::to_string(+row) + + " tileAddr=" + formatAddress(tileAddress)); + + 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); + } + + // Outer stamps use counters 0-1 only (PerfCtrl0); inner stamps use 0-3 (PerfCtrl0 + PerfCtrl1). + 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); + } + + // Inner stamps only: counters 2-3 and PerfCtrl1 @ 0x91004. + 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 d353b165..f5ae8d60 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 { @@ -57,7 +58,8 @@ struct ASMFileInfo { uint32_t opLocMinCol = UINT32_MAX; uint32_t opLocMaxCol = 0; std::vector timestamps; // SAVE_TIMESTAMPS lines - std::vector counters; // Filtered counters for this ASM + std::vector counters; // Filtered shim counters for this ASM + std::vector l2l2Counters; // Filtered memtile L2-L2 counters for this ASM }; /** @@ -300,7 +302,13 @@ class AieDtraceCTWriter { bool writeBandwidthCTFile(const std::vector& asmFileInfoList, const std::vector& allCounters, const std::vector& beginBlockWrites, - const std::string& outputPath); + const std::string& outputPath, + const std::vector& l2l2BeginBlockWrites = {}, + const std::vector& allL2l2Counters = {}); + + std::vector generateMemtilePerfCounterConfig( + uint8_t column, + const std::vector& counterPoints); private: VPDatabase* db; @@ -320,8 +328,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 + // Bandwidth monitoring constants static constexpr uint8_t NUM_BANDWIDTH_COUNTERS = 4; static constexpr uint8_t SHIM_ROW = 0; diff --git a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp index cfab9211..3cf587d2 100644 --- a/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp +++ b/profile/plugin/aie_dtrace/ve2/aie_dtrace_ve2.cpp @@ -134,8 +134,9 @@ namespace xdp { if (!ctWriter.generateBandwidthCT(outputPath, hwctx, it->second, bandwidthMetricSet, bandwidthChannel)) return; + const std::string ctMode = metadata->isL2L2Enabled() ? "bandwidth+L2-L2" : "bandwidth"; xrt_core::message::send(severity_level::debug, "XRT", - "AIE dtrace: Bandwidth CT generated for kernel '" + kernel_name + "AIE dtrace: " + ctMode + " CT generated for kernel '" + kernel_name + "' with metric set '" + bandwidthMetricSet + "'"); auto* run_impl = static_cast(run_impl_ptr);