From 46a94649b1c8f92f1f5cc6b87dc3be9cfc763c43 Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Tue, 17 Dec 2024 23:53:23 +0530 Subject: [PATCH 1/9] Inital Telluride changes for trace Signed-off-by: parthash0804 --- src/runtime_src/core/common/config_reader.h | 9 + .../telluride/aie_trace_logger_telluride.h | 36 + .../telluride/aie_trace_offload_telluride.cpp | 578 ++++++++++ .../telluride/aie_trace_offload_telluride.h | 172 +++ .../xdp/profile/plugin/CMakeLists.txt | 6 +- .../profile/plugin/aie_trace/CMakeLists.txt | 24 +- .../telluride/aie_trace_telluride.cpp | 1015 +++++++++++++++++ .../aie_trace/telluride/aie_trace_telluride.h | 92 ++ 8 files changed, 1929 insertions(+), 3 deletions(-) create mode 100644 src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h create mode 100644 src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.cpp create mode 100644 src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h create mode 100755 src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.cpp create mode 100755 src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h diff --git a/src/runtime_src/core/common/config_reader.h b/src/runtime_src/core/common/config_reader.h index 863f0ff693..34f8191471 100644 --- a/src/runtime_src/core/common/config_reader.h +++ b/src/runtime_src/core/common/config_reader.h @@ -1025,6 +1025,15 @@ get_aie_trace_settings_enable_system_timeline() return value; } +inline bool +get_aie_trace_settings_sim_trace_time_s() +{ + static unsigned int value = detail::get_uint_value("AIE_trace_settings.sim_trace_time_s", 0); + return value; +} + + + }} // config,xrt_core #endif diff --git a/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h b/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h new file mode 100644 index 0000000000..370af45eec --- /dev/null +++ b/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2020 Xilinx, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may + * not use this file except in compliance with the License. A copy of the + * License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#ifndef XDP_PROFILE_AIE_TRACE_LOGGER_H +#define XDP_PROFILE_AIE_TRACE_LOGGER_H + +#include +#include + +namespace xdp { + +// Interface class +class AIETraceLogger +{ +public: + AIETraceLogger() {} + virtual ~AIETraceLogger() {} + + virtual void addAIETraceData(uint64_t strmIndex, void* buffer, uint64_t bufferSz, bool copy) = 0; +}; + +} +#endif diff --git a/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.cpp b/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.cpp new file mode 100644 index 0000000000..d82fc0ec75 --- /dev/null +++ b/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.cpp @@ -0,0 +1,578 @@ +/** + * Copyright (C) 2019-2022 Xilinx, Inc + * Copyright (C) 2022-2024 Advanced Micro Devices, Inc. - All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may + * not use this file except in compliance with the License. A copy of the + * License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#define XDP_PLUGIN_SOURCE + +#include + +#include "core/common/message.h" +#include "core/include/xrt/xrt_kernel.h" +#include "xdp/profile/database/database.h" +#include "xdp/profile/database/static_info/aie_constructs.h" +#include "xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h" +#include "xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h" +#include "xdp/profile/device/pl_device_intf.h" +#include "xdp/profile/plugin/aie_trace/x86/aie_trace_kernel_config.h" +#include + +/* + * XRT_X86_BUILD is set only for x86 builds + * Only compile this on edge+versal build + */ +// #if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) && ! defined (XDP_CLIENT_BUILD) +#include +#include "core/include/xrt.h" +// #include "core/edge/user/shim.h" +// #endif +#include "../../../../../../../../src/shim/shim.h" + +namespace xdp { + + +AIETraceOffload::AIETraceOffload + ( void* handle, uint64_t id + , PLDeviceIntf* dInt + , AIETraceLogger* logger + , bool isPlio + , uint64_t totalSize + , uint64_t numStrm + ) + : deviceHandle(handle) + , deviceId(id) + , deviceIntf(dInt) + , traceLogger(logger) + , isPLIO(isPlio) + , totalSz(totalSize) + , numStream(numStrm) + , traceContinuous(false) + , offloadIntervalUs(0) + , bufferInitialized(false) + , offloadStatus(AIEOffloadThreadStatus::IDLE) + , mEnCircularBuf(false) + , mCircularBufOverwrite(false) +{ + bufAllocSz = deviceIntf->getAlignedTraceBufSize(totalSz, static_cast(numStream)); + + // Select appropriate reader + if (isPLIO) + mReadTrace = std::bind(&AIETraceOffload::readTracePLIO, this, std::placeholders::_1); + else + mReadTrace = std::bind(&AIETraceOffload::readTraceGMIO, this, std::placeholders::_1); +} + +AIETraceOffload::~AIETraceOffload() +{ + stopOffload(); + if (offloadThread.joinable()) + offloadThread.join(); +} + +bool AIETraceOffload::setupPSKernel() { + + auto spdevice = xrt_core::get_userpf_device(deviceHandle); + auto device = xrt::device(spdevice); + auto uuid = device.get_xclbin_uuid(); + auto gmio_kernel = xrt::kernel(device, uuid.get(), "aie_trace_gmio"); + + std::size_t total_size = sizeof(xdp::built_in::GMIOConfiguration) + sizeof(xdp::built_in::GMIOBuffer[numStream-1]); + xdp::built_in::GMIOConfiguration* input_params = (xdp::built_in::GMIOConfiguration*)malloc(total_size); + input_params->bufAllocSz = bufAllocSz; + input_params->numStreams = numStream; + + xdp::built_in::GMIOBuffer hostBuffer[numStream]; + for (uint64_t i = 0; i < numStream; i ++) { + buffers[i].bufId = deviceIntf->allocTraceBuf(bufAllocSz, 0); + + if (!buffers[i].bufId) { + bufferInitialized = false; + return bufferInitialized; + } + + uint64_t bufAddr = deviceIntf->getTraceBufDeviceAddr(buffers[i].bufId); + + VPDatabase* db = VPDatabase::Instance(); + TraceGMIO* traceGMIO = (db->getStaticInfo()).getTraceGMIO(deviceId, i); + + hostBuffer[i].shimColumn = traceGMIO->shimColumn; + hostBuffer[i].burstLength = traceGMIO->burstLength; + hostBuffer[i].channelNumber = traceGMIO->channelNumber; + hostBuffer[i].physAddr = bufAddr; + input_params->gmioData[i] = hostBuffer[i]; + } + + const size_t DATA_SIZE = 4096; // Data size aligned to 4096, and won't be passed for 400 tiles + //Cast struct to uint8_t pointer and pass this data + uint8_t* temp = reinterpret_cast(input_params); + + auto in_bo = xrt::bo(device, DATA_SIZE, 2); + auto in_bo_map = in_bo.map(); + std::fill(in_bo_map, in_bo_map + 1024, 0); + + //copy the input configuration buffer to the buffer object. + std::memcpy(in_bo_map, temp, total_size); + + in_bo.sync(XCL_BO_SYNC_BO_TO_DEVICE, DATA_SIZE, 0); + auto run = gmio_kernel(in_bo); + run.wait(); + + std::string msg = "The aie_trace_gmio PS kernel was successfully scheduled."; + xrt_core::message::send(xrt_core::message::severity_level::info, "XRT", msg); + + free(input_params); + bufferInitialized = true; + return bufferInitialized; +} + +bool AIETraceOffload::initReadTrace() +{ + buffers.clear(); + buffers.resize(numStream); + + uint8_t memIndex = 0; + if (isPLIO) { + memIndex = deviceIntf->getAIETs2mmMemIndex(0); // all the AIE Ts2mm s will have same memory index selected + } else { + memIndex = 0; // for now + +#if defined (XRT_ENABLE_AIE) && defined (XRT_X86_BUILD) + bool success = setupPSKernel(); + return success; +#endif + +/* + * XRT_X86_BUILD is set only for x86 builds + * Only compile this on edge+versal build + */ +#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) + gmioDMAInsts.clear(); + gmioDMAInsts.resize(numStream); +#endif + } + + checkCircularBufferSupport(); + + for(uint64_t i = 0; i < numStream ; ++i) { + buffers[i].bufId = deviceIntf->allocTraceBuf(bufAllocSz, memIndex); + if (!buffers[i].bufId) { + bufferInitialized = false; + return bufferInitialized; + } + + // Data Mover will write input stream to this address + uint64_t bufAddr = deviceIntf->getTraceBufDeviceAddr(buffers[i].bufId); + std::cout<<"*******************************Inside telluride XDP***************************"<initAIETs2mm(bufAllocSz, bufAddr, i, mEnCircularBuf); + } else { + /* + * XRT_X86_BUILD is set only for x86 builds + * Only compile this on edge+versal build + */ +#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) + VPDatabase* db = VPDatabase::Instance(); + TraceGMIO* traceGMIO = (db->getStaticInfo()).getTraceGMIO(deviceId, i); + + auto drv = aiarm::shim::handleCheck(deviceHandle); + if(!drv) { + bufferInitialized = false; + return bufferInitialized; + } + auto aieObj = drv->get_aie_array(); + + XAie_DevInst* devInst = aieObj->get_dev(); + + gmioDMAInsts[i].gmioTileLoc = XAie_TileLoc(traceGMIO->shimColumn, 0); + + int driverStatus = XAIE_OK; + driverStatus = XAie_DmaDescInit(devInst, &(gmioDMAInsts[i].shimDmaInst), gmioDMAInsts[i].gmioTileLoc); + if(XAIE_OK != driverStatus) { + throw std::runtime_error("Initialization of DMA Descriptor failed while setting up SHIM DMA channel for GMIO Trace offload"); + } + + // channelNumber: (0-S2MM0,1-S2MM1,2-MM2S0,3-MM2S1) + // Enable shim DMA channel, need to start first so the status is correct + uint16_t channelNumber = (traceGMIO->channelNumber > 1) ? (traceGMIO->channelNumber - 2) : traceGMIO->channelNumber; + XAie_DmaDirection dir = (traceGMIO->channelNumber > 1) ? DMA_MM2S : DMA_S2MM; + + XAie_DmaChannelEnable(devInst, gmioDMAInsts[i].gmioTileLoc, channelNumber, dir); + + // Set AXI burst length + XAie_DmaSetAxi(&(gmioDMAInsts[i].shimDmaInst), 0, traceGMIO->burstLength, 0, 0, 0); + + XAie_MemInst memInst; + XAie_MemCacheProp prop = XAIE_MEM_CACHEABLE; + xclBufferExportHandle boExportHandle = deviceIntf->exportTraceBuf(buffers[i].bufId); + if(XRT_NULL_BO_EXPORT == boExportHandle) { + throw std::runtime_error("Unable to export BO while attaching to AIE Driver"); + } + XAie_MemAttach(devInst, &memInst, 0, 0, 0, prop, boExportHandle); + + char* vaddr = reinterpret_cast(mmap(NULL, bufAllocSz, PROT_READ | PROT_WRITE, MAP_SHARED, boExportHandle, 0)); + XAie_DmaSetAddrLen(&(gmioDMAInsts[i].shimDmaInst), (uint64_t)vaddr, bufAllocSz); + + XAie_DmaEnableBd(&(gmioDMAInsts[i].shimDmaInst)); + + // For trace, use bd# 0 for S2MM0, use bd# 4 for S2MM1 + int bdNum = channelNumber * 4; + // Write to shim DMA BD AxiMM registers + XAie_DmaWriteBd(devInst, &(gmioDMAInsts[i].shimDmaInst), gmioDMAInsts[i].gmioTileLoc, bdNum); + + // Enqueue BD + XAie_DmaChannelPushBdToQueue(devInst, gmioDMAInsts[i].gmioTileLoc, channelNumber, dir, bdNum); + +#endif + } + } + bufferInitialized = true; + return bufferInitialized; +} + +void AIETraceOffload::endReadTrace() +{ + // reset + for (uint64_t i = 0; i < numStream ; ++i) { + if (!buffers[i].bufId) + continue; + + if (isPLIO) { + deviceIntf->resetAIETs2mm(i); +// deviceIntf->freeTraceBuf(b.bufId); + } else { +/* + * XRT_NATIVE_BUILD is set only for x86 builds + * Only compile this on edge+versal build + */ +#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) + VPDatabase* db = VPDatabase::Instance(); + TraceGMIO* traceGMIO = (db->getStaticInfo()).getTraceGMIO(deviceId, i); + + auto drv = aiarm::shim::handleCheck(deviceHandle); + if (!drv) + return; + auto aieObj = drv->get_aie_array(); + XAie_DevInst* devInst = aieObj->get_dev(); + + // channelNumber: (0-S2MM0,1-S2MM1,2-MM2S0,3-MM2S1) + // Enable shim DMA channel, need to start first so the status is correct + uint16_t channelNumber = (traceGMIO->channelNumber > 1) ? (traceGMIO->channelNumber - 2) : traceGMIO->channelNumber; + XAie_DmaDirection dir = (traceGMIO->channelNumber > 1) ? DMA_MM2S : DMA_S2MM; + + XAie_DmaChannelDisable(devInst, gmioDMAInsts[i].gmioTileLoc, channelNumber, dir); +#endif + + } + deviceIntf->freeTraceBuf(buffers[i].bufId); + buffers[i].bufId = 0; + } + bufferInitialized = false; +} + +void AIETraceOffload::readTraceGMIO(bool final) +{ + // Keep it low to save bandwidth + constexpr uint64_t chunk_512k = 0x80000; + + for (uint64_t index = 0; index < numStream; ++index) { + auto& bd = buffers[index]; + if (bd.offloadDone) + continue; + + // read one chunk or till the end of buffer + auto chunkEnd = bd.offset + chunk_512k; + if (final || chunkEnd > bufAllocSz) + chunkEnd = bufAllocSz; + bd.usedSz = chunkEnd; + + bd.offset += syncAndLog(index); + } +} + +void AIETraceOffload::readTracePLIO(bool final) +{ + if (mCircularBufOverwrite) + return; + + for (uint64_t index = 0; index < numStream; ++index) { + auto& bd = buffers[index]; + + if (bd.offloadDone) + continue; + + uint64_t wordCount = deviceIntf->getWordCountAIETs2mm(index, final); + // AIE Trace packets are 4 words of 64 bit + wordCount -= wordCount % 4; + + uint64_t bytes_written = wordCount * TRACE_PACKET_SIZE; + uint64_t bytes_read = bd.usedSz + bd.rollover_count * bufAllocSz; + + // Offload cannot keep up with the DMA + // There is a slight chance that overwrite could occur + // during this check. In that case trace could be corrupt + if (bytes_written > bytes_read + bufAllocSz) { + // Don't read any more data + bd.offloadDone = true; + std::stringstream msg; + msg << AIE_TS2MM_WARN_MSG_CIRC_BUF_OVERWRITE << " Stream : " << index + 1 << std::endl; + xrt_core::message::send(xrt_core::message::severity_level::warning, "XRT", msg.str()); + debug_stream + << "Bytes Read : " << bytes_read + << " Bytes Written : " << bytes_written + << std::endl; + + // Fatal condition. Abort offload + mCircularBufOverwrite = true; + stopOffload(); + return; + } + + // Start Offload from previous offset + bd.offset = bd.usedSz; + if (bd.offset == bufAllocSz) { + bd.rollover_count++; + bd.offset = 0; + } + + // End Offload at this offset + // limit size to not cross circular buffer boundary + uint64_t circBufRolloverBytes = 0; + bd.usedSz = bytes_written - bd.rollover_count * bufAllocSz; + if (bd.usedSz > bufAllocSz) { + circBufRolloverBytes = bd.usedSz - bufAllocSz; + bd.usedSz = bufAllocSz; + } + + if (bd.offset != bd.usedSz) { + debug_stream + << "AIETraceOffload::config_s2mm_" << index << " " + << "Reading from 0x" + << std::hex << bd.offset << " to 0x" << bd.usedSz << std::dec + << " Bytes Read : " << bytes_read + << " Bytes Written : " << bytes_written + << " Rollovers : " << bd.rollover_count + << std::endl; + } + + if (!syncAndLog(index)) + continue; + + // Do another sync if we're crossing circular buffer boundary + if (mEnCircularBuf && circBufRolloverBytes) { + // Start from 0 + bd.rollover_count++; + bd.offset = 0; + // End at leftover bytes + bd.usedSz = circBufRolloverBytes; + + debug_stream + << "Circular buffer boundary read from 0x0 to 0x: " + << std::hex << circBufRolloverBytes << std::dec << std::endl; + + syncAndLog(index); + } + } +} + +uint64_t AIETraceOffload::syncAndLog(uint64_t index) +{ + auto& bd = buffers[index]; + + if (bd.offset >= bd.usedSz) + return 0; + + // Amount of newly written trace + uint64_t nBytes = bd.usedSz - bd.offset; + + // Sync to host + auto start = std::chrono::steady_clock::now(); + void* hostBuf = deviceIntf->syncTraceBuf(bd.bufId, bd.offset, nBytes); + auto end = std::chrono::steady_clock::now(); + debug_stream + << "ts2mm_" << index << " : bytes : " << nBytes << " " + << "sync: " << std::chrono::duration_cast(end - start).count() << "µs " + << std::hex << "from 0x" << bd.offset << " to 0x" + << bd.usedSz << std::dec << std::endl; + + if (!hostBuf) { + bd.offloadDone = true; + return 0; + } + + // Find amount of non-zero data in buffer + if (!isPLIO) + nBytes = searchWrittenBytes(hostBuf, nBytes); + + // check for full buffer + if ((bd.offset + nBytes >= bufAllocSz) && !mEnCircularBuf) { + bd.isFull = true; + bd.offloadDone = true; + } + + // Log nBytes of trace + traceLogger->addAIETraceData(index, hostBuf, nBytes, mEnCircularBuf); + return nBytes; +} + +bool AIETraceOffload::isTraceBufferFull() +{ + for (auto& buf: buffers) { + if (buf.isFull) + return true; + } + + return false; +} + +void AIETraceOffload::checkCircularBufferSupport() +{ + mEnCircularBuf = xrt_core::config::get_aie_trace_settings_reuse_buffer(); + if (!mEnCircularBuf) + return; + + // gmio not supported + if (!isPLIO) { + mEnCircularBuf = false; + xrt_core::message::send(xrt_core::message::severity_level::warning, "XRT", AIE_TRACE_WARN_REUSE_GMIO); + return; + } + + // old datamover not supported for PLIO + if (!deviceIntf->supportsCircBufAIE()) { + mEnCircularBuf = false; + return; + } + + // check for periodic offload + if (!continuousTrace()) { + mEnCircularBuf = false; + xrt_core::message::send(xrt_core::message::severity_level::warning, "XRT", AIE_TRACE_WARN_REUSE_PERIODIC); + return; + } + + // Warn if circular buffer settings not adequate + bool buffer_not_large_enough = (bufAllocSz < AIE_MIN_SIZE_CIRCULAR_BUF); + bool offload_not_fast_enough = (offloadIntervalUs > AIE_TRACE_REUSE_MAX_OFFLOAD_INT_US); + bool too_many_streams = (numStream > AIE_TRACE_REUSE_MAX_STREAMS); + + if (buffer_not_large_enough || offload_not_fast_enough || too_many_streams) { + std::stringstream msg; + msg << AIE_TRACE_BUF_REUSE_WARN + << "Requested Settings: " + << "buffer_size/stream : " << bufAllocSz << ", " + << "buffer_offload_interval_us : " << offloadIntervalUs << ", " + << "trace streams : " << numStream; + xrt_core::message::send(xrt_core::message::severity_level::warning, "XRT", msg.str()); + } + + xrt_core::message::send(xrt_core::message::severity_level::info, "XRT", AIE_TRACE_CIRC_BUF_EN); +} + +void AIETraceOffload::startOffload() +{ + if (offloadStatus == AIEOffloadThreadStatus::RUNNING) + return; + + std::lock_guard lock(statusLock); + offloadStatus = AIEOffloadThreadStatus::RUNNING; + + offloadThread = std::thread(&AIETraceOffload::continuousOffload, this); +} + +void AIETraceOffload::continuousOffload() +{ + if (!bufferInitialized && !initReadTrace()) { + offloadFinished(); + return; + } + + while (keepOffloading()) { + mReadTrace(false); + std::this_thread::sleep_for(std::chrono::microseconds(offloadIntervalUs)); + } + + uint64_t simTraceTimeS = xrt_core::config::get_aie_trace_settings_sim_trace_time_s(); + std::cout<<"******************************************** sleep provided in xrt.ini : "< lock(statusLock); + return (AIEOffloadThreadStatus::RUNNING == offloadStatus); +} + +void AIETraceOffload::stopOffload() +{ + std::lock_guard lock(statusLock); + if (AIEOffloadThreadStatus::STOPPED == offloadStatus) + return; + offloadStatus = AIEOffloadThreadStatus::STOPPING; +} + +void AIETraceOffload::offloadFinished() +{ + std::lock_guard lock(statusLock); + if (AIEOffloadThreadStatus::STOPPED == offloadStatus) + return; + offloadStatus = AIEOffloadThreadStatus::STOPPED; +} + +uint64_t AIETraceOffload::searchWrittenBytes(void* buf, uint64_t bytes) +{ + /* + * Look For trace boundary using binary search. + * Use Dword to be safe + */ + auto words = static_cast(buf); + uint64_t wordcount = bytes / TRACE_PACKET_SIZE; + + // indices + int64_t low = 0; + int64_t high = static_cast(wordcount) - 1; + + // Boundary at which trace ends and 0s begin + uint64_t boundary = wordcount; + + while (low <= high) { + int64_t mid = low + (high - low) / 2; + if (!words[mid]) { + boundary = mid; + high = mid - 1; + } else { + low = mid + 1; + } + } + + uint64_t written = boundary * TRACE_PACKET_SIZE; + + debug_stream + << "Found Boundary at 0x" << std::hex << written << std::dec << std::endl; + + return written; +} + +} + diff --git a/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h b/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h new file mode 100644 index 0000000000..3bd71a2f92 --- /dev/null +++ b/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h @@ -0,0 +1,172 @@ +/** + * Copyright (C) 2020-2022 Xilinx, Inc + * Copyright (C) 2022-2023 Advanced Micro Devices, Inc. - All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may + * not use this file except in compliance with the License. A copy of the + * License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#ifndef XDP_PROFILE_AIE_TRACE_OFFLOAD_H_ +#define XDP_PROFILE_AIE_TRACE_OFFLOAD_H_ + +#include "xdp/profile/device/tracedefs.h" + +/* + * XRT_NATIVE_BUILD is set only for x86 builds + * We can only include/compile aie specific headers, when compiling for edge+versal. + * + * AIE specific edge code that needs to be protected includes: + * 1. Header file inclusions + * 2. GMIO driver specific definitions + * 3. GMIO driver calls to configure shim DMA + * + * When XRT_NATIVE_BUILD is defined, the offloading structure is: + * 1. For PL offload, same as edge + * 2. For GMIO offload, ps kernel needs to be used to initialize and read data + */ + +#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) +#include "../../../../../../../../src/shim/aie/aie.h" +#endif + +namespace xdp { + +class PLDeviceIntf; +class AIETraceLogger; + +#define debug_stream \ +if(!m_debug); else std::cout + +struct AIETraceBufferInfo +{ + size_t bufId; +// uint64_t allocSz; // currently all the buffers are equal size + uint64_t usedSz; + uint64_t offset; + uint32_t rollover_count; + bool isFull; + bool offloadDone; + + AIETraceBufferInfo() + : bufId(0), + usedSz(0), + offset(0), + rollover_count(0), + isFull(false), + offloadDone(false) + {} +}; + +/* + * XRT_NATIVE_BUILD is set only for x86 builds + * Only compile this on edge+versal build + */ +#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) +struct AIETraceGmioDMAInst +{ + // C_RTS Shim DMA to where this GMIO object is mapped + XAie_DmaDesc shimDmaInst; + XAie_LocType gmioTileLoc; +}; +#endif + +enum class AIEOffloadThreadStatus { + IDLE, + RUNNING, + STOPPING, + STOPPED +}; + +class AIETraceOffload +{ + public: + AIETraceOffload(void* handle, uint64_t id, + PLDeviceIntf*, AIETraceLogger*, + bool isPlio, + uint64_t totalSize, + uint64_t numStrm + ); + + virtual ~AIETraceOffload(); + +public: + bool initReadTrace(); + void endReadTrace(); + bool isTraceBufferFull(); + void startOffload(); + void stopOffload(); + + inline AIETraceLogger* getAIETraceLogger() { return traceLogger; } + inline void setContinuousTrace() { traceContinuous = true; } + inline bool continuousTrace() { return traceContinuous; } + inline void setOffloadIntervalUs(uint64_t v) { offloadIntervalUs = v; } + + inline AIEOffloadThreadStatus getOffloadStatus() { + std::lock_guard lock(statusLock); + return offloadStatus; + }; + + void readTrace(bool final) {mReadTrace(final);}; + +private: + + void* deviceHandle; + uint64_t deviceId; + PLDeviceIntf* deviceIntf; + AIETraceLogger* traceLogger; + + bool isPLIO; + uint64_t totalSz; + uint64_t numStream; + uint64_t bufAllocSz; + std::vector buffers; + + //Internal use only + // Set this for verbose trace offload + bool m_debug = false; + +/* + * XRT_NATIVE_BUILD is set only for x86 builds + * Only compile this on edge+versal build + */ +#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) + std::vector gmioDMAInsts; +#endif + + // Continuous Trace Offload (For PLIO) + bool traceContinuous; + uint64_t offloadIntervalUs; + bool bufferInitialized; + std::mutex statusLock; + AIEOffloadThreadStatus offloadStatus; + std::thread offloadThread; + + //Circular Buffer Tracking + bool mEnCircularBuf; + bool mCircularBufOverwrite; + +private: + void readTracePLIO(bool final); + void readTraceGMIO(bool final); + bool setupPSKernel(); + void continuousOffload(); + bool keepOffloading(); + void offloadFinished(); + void checkCircularBufferSupport(); + uint64_t syncAndLog(uint64_t index); + std::function mReadTrace; + uint64_t searchWrittenBytes(void * buf, uint64_t bytes); +}; + +} + +#endif diff --git a/src/runtime_src/xdp/profile/plugin/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/CMakeLists.txt index cdf2460864..02d917bd2e 100644 --- a/src/runtime_src/xdp/profile/plugin/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/CMakeLists.txt @@ -2,7 +2,11 @@ # Copyright (C) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. # -if (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") +if(XDP_TELLURIDE_BUILD_CMAKE STREQUAL "yes") + message("**************************Inside Telluride build CMake**************************") + add_subdirectory(aie_trace) + +elseif (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") add_subdirectory(native) add_subdirectory(user) diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt index 5b1c1bb327..960150edfe 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt @@ -7,7 +7,12 @@ # Edge-Versal systems, but not Edge-aarch64. It also has a dependency # on the hardware shim # ==================================================================== -if (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") +if(XDP_TELLURIDE_BUILD_CMAKE STREQUAL "yes") + message("**************************Inside Telluride build CMake aie_trace**************************") + set(IMPL_DIR "${PROFILE_DIR}/plugin/aie_trace/telluride") + set(OFFLOAD_DIR "${PROFILE_DIR}/device/aie_trace/telluride") + set(DEVICE_DIR "${PROFILE_DIR}/device/hal_device") +elseif (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") set(IMPL_DIR "${PROFILE_DIR}/plugin/aie_trace/client") set(OFFLOAD_DIR "${PROFILE_DIR}/device/aie_trace/client") set(DEVICE_DIR "${PROFILE_DIR}/device/client_device") @@ -43,7 +48,22 @@ file(GLOB AIE_DRIVER_COMMON_UTIL_FILES "${PROFILE_DIR}/device/common/*.cpp" ) -if (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") +if(XDP_TELLURIDE_BUILD_CMAKE STREQUAL "yes") + message("**************************Inside Telluride build CMake aie_trace**************************") + add_library(xdp_aie_trace_plugin MODULE ${AIE_TRACE_PLUGIN_FILES} ${AIE_TRACE_UTIL_FILES}) + + add_dependencies(xdp_aie_trace_plugin xdp_core xrt_coreutil) + target_link_libraries(xdp_aie_trace_plugin PRIVATE xdp_core xrt_coreutil xaiengine) + target_compile_definitions(xdp_aie_trace_plugin PRIVATE FAL_LINUX="on") + + set_target_properties(xdp_aie_trace_plugin PROPERTIES VERSION ${XRT_VERSION_STRING} SOVERSION ${XRT_SOVERSION}) + + install (TARGETS xdp_aie_trace_plugin + LIBRARY DESTINATION ${XDP_PLUGIN_INSTALL_DIR} + ) + + +elseif (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") add_library(xdp_aie_trace_plugin MODULE ${AIE_TRACE_PLUGIN_FILES} ${AIE_DRIVER_COMMON_UTIL_FILES}) add_dependencies(xdp_aie_trace_plugin xdp_core xrt_coreutil) target_link_libraries(xdp_aie_trace_plugin PRIVATE xdp_core xrt_coreutil xaiengine) diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.cpp b/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.cpp new file mode 100755 index 0000000000..e5ff7c911d --- /dev/null +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.cpp @@ -0,0 +1,1015 @@ +/** + * Copyright (C) 2022-2024 Advanced Micro Devices, Inc. - All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may + * not use this file except in compliance with the License. A copy of the + * License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#define XDP_PLUGIN_SOURCE + +#include "xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h" +#include "xdp/profile/plugin/aie_trace/util/aie_trace_util.h" +#include "xdp/profile/plugin/aie_trace/util/aie_trace_config.h" +#include "xdp/profile/database/static_info/aie_util.h" + +#include +#include +#include +#include +#include +#include + +#include "core/common/message.h" +#include "core/common/time.h" +// #include "core/edge/user/shim.h" +#include "core/include/xrt/xrt_kernel.h" +#include "xdp/profile/database/database.h" +#include "xdp/profile/database/events/creator/aie_trace_data_logger.h" +#include "xdp/profile/database/static_info/aie_constructs.h" +#include "xdp/profile/database/static_info/pl_constructs.h" +#include "xdp/profile/device/pl_device_intf.h" +#include "xdp/profile/device/tracedefs.h" +#include "xdp/profile/plugin/aie_trace/aie_trace_metadata.h" +#include "xdp/profile/plugin/vp_base/utility.h" +#include "../../../../../../../../src/shim/shim.h" + +namespace { + static void* fetchAieDevInst(void* devHandle) + { + auto drv = aiarm::shim::handleCheck(devHandle); + if (!drv) + return nullptr; + auto aieArray = drv->get_aie_array(); + if (!aieArray) + return nullptr; + return aieArray->get_dev(); + } + + static void* allocateAieDevice(void* devHandle) + { + auto aieDevInst = static_cast(fetchAieDevInst(devHandle)); + if (!aieDevInst) + return nullptr; + return new xaiefal::XAieDev(aieDevInst, false); + } + + static void deallocateAieDevice(void* aieDevice) + { + auto object = static_cast(aieDevice); + if (object != nullptr) + delete object; + } +} // end anonymous namespace + +namespace xdp { + using severity_level = xrt_core::message::severity_level; + + /**************************************************************************** + * Constructor: AIE trace implementation for edge devices + ***************************************************************************/ + AieTrace_EdgeImpl::AieTrace_EdgeImpl(VPDatabase* database, std::shared_ptr metadata) + : AieTraceImpl(database, metadata) + { + auto hwGen = metadata->getHardwareGen(); + auto counterScheme = metadata->getCounterScheme(); + + // Pre-defined metric sets + coreEventSets = aie::trace::getCoreEventSets(hwGen); + memoryEventSets = aie::trace::getMemoryEventSets(hwGen); + memoryTileEventSets = aie::trace::getMemoryTileEventSets(hwGen); + interfaceTileEventSets = aie::trace::getInterfaceTileEventSets(hwGen); + + // Core/memory module counters + coreCounterStartEvents = aie::trace::getCoreCounterStartEvents(hwGen, counterScheme); + coreCounterEndEvents = aie::trace::getCoreCounterEndEvents(hwGen, counterScheme); + coreCounterEventValues = aie::trace::getCoreCounterEventValues(hwGen, counterScheme); + memoryCounterStartEvents = aie::trace::getMemoryCounterStartEvents(hwGen, counterScheme); + memoryCounterEndEvents = aie::trace::getMemoryCounterEndEvents(hwGen, counterScheme); + memoryCounterEventValues = aie::trace::getMemoryCounterEventValues(hwGen, counterScheme); + + // Core trace start/end: these are also broadcast to memory module + coreTraceStartEvent = XAIE_EVENT_ACTIVE_CORE; + coreTraceEndEvent = XAIE_EVENT_DISABLED_CORE; + + // Memory/interface tile trace is flushed at end of run + memoryTileTraceStartEvent = XAIE_EVENT_TRUE_MEM_TILE; + memoryTileTraceEndEvent = XAIE_EVENT_USER_EVENT_1_MEM_TILE; + interfaceTileTraceStartEvent = XAIE_EVENT_TRUE_PL; + interfaceTileTraceEndEvent = XAIE_EVENT_USER_EVENT_1_PL; + } + + /**************************************************************************** + * Verify correctness of trace buffer size + ***************************************************************************/ + uint64_t AieTrace_EdgeImpl::checkTraceBufSize(uint64_t aieTraceBufSize) + { + uint64_t deviceMemorySize = getPSMemorySize(); + if (deviceMemorySize == 0) + return aieTraceBufSize; + + double percentSize = (100.0 * aieTraceBufSize) / deviceMemorySize; + + std::stringstream percentSizeStr; + percentSizeStr << std::fixed << std::setprecision(3) << percentSize; + + // Limit size of trace buffer if requested amount is too high + if (percentSize >= 80.0) { + aieTraceBufSize = static_cast(std::ceil(0.8 * deviceMemorySize)); + + std::stringstream newBufSizeStr; + newBufSizeStr << std::fixed << std::setprecision(3) << (aieTraceBufSize / (1024.0 * 1024.0)); // In MB + + std::string msg = "Requested AIE trace buffer is " + percentSizeStr.str() + "% of device memory." + + " You may run into errors depending upon memory usage" + " of your application." + + " Limiting to " + newBufSizeStr.str() + " MB."; + xrt_core::message::send(severity_level::warning, "XRT", msg); + } else { + std::string msg = "Requested AIE trace buffer is " + percentSizeStr.str() + "% of device memory."; + xrt_core::message::send(severity_level::info, "XRT", msg); + } + + return aieTraceBufSize; + } + + /**************************************************************************** + * Check if given tile has free resources + ***************************************************************************/ + bool AieTrace_EdgeImpl::tileHasFreeRsc(xaiefal::XAieDev* aieDevice, XAie_LocType& loc, + const module_type type, const std::string& metricSet) + { + auto stats = aieDevice->getRscStat(XAIEDEV_DEFAULT_GROUP_AVAIL); + uint32_t available = 0; + uint32_t required = 0; + std::stringstream msg; + + // Check trace events for interface tiles + if (type == module_type::shim) { + available = stats.getNumRsc(loc, XAIE_PL_MOD, xaiefal::XAIE_TRACEEVENT); + required = interfaceTileEventSets[metricSet].size(); + if (available < required) { + msg << "Available interface tile trace slots for AIE trace : " << available << std::endl + << "Required interface tile trace slots for AIE trace : " << required; + xrt_core::message::send(severity_level::info, "XRT", msg.str()); + return false; + } + return true; + } + + // Memory module/tile perf counters + available = stats.getNumRsc(loc, XAIE_MEM_MOD, xaiefal::XAIE_PERFCOUNT); + required = memoryCounterStartEvents.size(); + if (available < required) { + msg << "Available memory performance counters for AIE trace : " << available << std::endl + << "Required memory performance counters for AIE trace : " << required; + xrt_core::message::send(severity_level::info, "XRT", msg.str()); + return false; + } + + // Memory module/tile trace slots + available = stats.getNumRsc(loc, XAIE_MEM_MOD, xaiefal::XAIE_TRACEEVENT); + required = memoryCounterStartEvents.size() + memoryEventSets[metricSet].size(); + if (available < required) { + msg << "Available memory trace slots for AIE trace : " << available << std::endl + << "Required memory trace slots for AIE trace : " << required; + xrt_core::message::send(severity_level::info, "XRT", msg.str()); + return false; + } + + // Core resources not needed in memory tiles + if (type == module_type::mem_tile) + return true; + + // Core module perf counters + available = stats.getNumRsc(loc, XAIE_CORE_MOD, xaiefal::XAIE_PERFCOUNT); + required = coreCounterStartEvents.size(); + if (metadata->getUseDelay()) { + ++required; + if (!metadata->getUseOneDelayCounter()) + ++required; + } else if (metadata->getUseGraphIterator()) + ++required; + + if (available < required) { + msg << "Available core module performance counters for AIE trace : " << available << std::endl + << "Required core module performance counters for AIE trace : " << required; + xrt_core::message::send(severity_level::info, "XRT", msg.str()); + return false; + } + + // Core module trace slots + available = stats.getNumRsc(loc, XAIE_CORE_MOD, xaiefal::XAIE_TRACEEVENT); + required = coreCounterStartEvents.size() + coreEventSets[metricSet].size(); + if (available < required) { + msg << "Available core module trace slots for AIE trace : " << available << std::endl + << "Required core module trace slots for AIE trace : " << required; + xrt_core::message::send(severity_level::info, "XRT", msg.str()); + return false; + } + + // Core module broadcasts. 2 events for starting/ending trace + available = stats.getNumRsc(loc, XAIE_CORE_MOD, xaiefal::XAIE_BROADCAST); + required = memoryEventSets[metricSet].size() + 2; + if (available < required) { + msg << "Available core module broadcast channels for AIE trace : " << available << std::endl + << "Required core module broadcast channels for AIE trace : " << required; + xrt_core::message::send(severity_level::info, "XRT", msg.str()); + return false; + } + + return true; + } + + /**************************************************************************** + * Stop and release resources (e.g., counters, ports) + ***************************************************************************/ + void AieTrace_EdgeImpl::freeResources() + { + for (auto& c : perfCounters) { + c->stop(); + c->release(); + } + for (auto& p : streamPorts) { + p->stop(); + p->release(); + } + } + + /**************************************************************************** + * Validitate AIE device and runtime metrics + ***************************************************************************/ + bool AieTrace_EdgeImpl::checkAieDeviceAndRuntimeMetrics(uint64_t deviceId, void* handle) + { + aieDevInst = static_cast(db->getStaticInfo().getAieDevInst(fetchAieDevInst, handle)); + aieDevice = static_cast(db->getStaticInfo().getAieDevice(allocateAieDevice, deallocateAieDevice, handle)); + if (!aieDevInst || !aieDevice) { + xrt_core::message::send(severity_level::warning, "XRT", + "Unable to get AIE device. AIE event trace will not be available."); + return false; + } + + // Check compile-time trace + if (!metadata->getRuntimeMetrics()) { + return false; + } + + return true; + } + + /**************************************************************************** + * Update device (e.g., after loading xclbin) + ***************************************************************************/ + void AieTrace_EdgeImpl::updateDevice() + { + if (!checkAieDeviceAndRuntimeMetrics(metadata->getDeviceID(), metadata->getHandle())) + return; + + // Set metrics for counters and trace events + if (!setMetricsSettings(metadata->getDeviceID(), metadata->getHandle())) { + std::string msg("Unable to configure AIE trace control and events. No trace will be generated."); + xrt_core::message::send(severity_level::warning, "XRT", msg); + return; + } + } + + /**************************************************************************** + * Configure requested tiles with trace metrics and settings + ***************************************************************************/ + bool AieTrace_EdgeImpl::setMetricsSettings(uint64_t deviceId, void* handle) + { + if (!metadata->getIsValidMetrics()) { + std::string msg("AIE trace metrics were not specified in xrt.ini. AIE event trace will not be available."); + xrt_core::message::send(severity_level::warning, "XRT", msg); + return false; + } + + // Get channel configurations (memory and interface tiles) + auto configChannel0 = metadata->getConfigChannel0(); + auto configChannel1 = metadata->getConfigChannel1(); + + // Get the column shift for partition + // NOTE: If partition is not used, this value is zero. + uint8_t startColShift = metadata->getPartitionOverlayStartCols().front(); + aie::displayColShiftInfo(startColShift); + + // Zero trace event tile counts + for (int m = 0; m < static_cast(module_type::num_types); ++m) { + for (int n = 0; n <= NUM_TRACE_EVENTS; ++n) + mNumTileTraceEvents[m][n] = 0; + } + + // Using user event for trace end to enable flushing + // NOTE: Flush trace module always at the end because for some applications + // core might be running infinitely. + + if (metadata->getUseUserControl()) + coreTraceStartEvent = XAIE_EVENT_INSTR_EVENT_0_CORE; + coreTraceEndEvent = XAIE_EVENT_INSTR_EVENT_1_CORE; + + // Iterate over all used/specified tiles + // NOTE: rows are stored as absolute as required by resource manager + for (auto& tileMetric : metadata->getConfigMetrics()) { + auto& metricSet = tileMetric.second; + auto tile = tileMetric.first; + auto col = tile.col + startColShift; + auto row = tile.row; + auto subtype = tile.subtype; + auto type = aie::getModuleType(row, metadata->getRowOffset()); + auto typeInt = static_cast(type); + auto& xaieTile = aieDevice->tile(col, row); + auto loc = XAie_TileLoc(col, row); + + if ((type == module_type::core) && !aie::trace::isDmaSet(metricSet)) { + // If we're not looking at DMA events, then don't display the DMA + // If core is not active (i.e., DMA-only tile), then ignore this tile + if (tile.active_core) + tile.active_memory = false; + else + continue; + } + + std::string tileName = (type == module_type::mem_tile) ? "memory" + : ((type == module_type::shim) ? "interface" : "AIE"); + tileName.append(" tile (" + std::to_string(col) + "," + std::to_string(row) + ")"); + + if (aie::isInfoVerbosity()) { + std::stringstream infoMsg; + infoMsg << "Configuring " << tileName << " for trace using metric set " << metricSet; + xrt_core::message::send(severity_level::info, "XRT", infoMsg.str()); + } + + xaiefal::XAieMod core; + xaiefal::XAieMod memory; + xaiefal::XAieMod shim; + if (type == module_type::core) + core = xaieTile.core(); + if (type == module_type::shim) + shim = xaieTile.pl(); + else + memory = xaieTile.mem(); + + // Store location to flush at end of run + if (type == module_type::core || (type == module_type::mem_tile) + || (type == module_type::shim)) { + if (type == module_type::core) + traceFlushLocs.push_back(loc); + else if (type == module_type::mem_tile) + memoryTileTraceFlushLocs.push_back(loc); + else if (type == module_type::shim) + interfaceTileTraceFlushLocs.push_back(loc); + } + + // AIE config object for this tile + auto cfgTile = std::make_unique(col, row, type); + cfgTile->type = type; + cfgTile->trace_metric_set = metricSet; + cfgTile->active_core = tile.active_core; + cfgTile->active_memory = tile.active_memory; + + // Catch core execution trace + if ((type == module_type::core) && (metricSet == "execution")) { + // Set start/end events, use execution packets, and start trace module + auto coreTrace = core.traceControl(); + if (coreTrace->setCntrEvent(coreTraceStartEvent, coreTraceEndEvent) != XAIE_OK) + continue; + coreTrace->reserve(); + + // Driver requires at least one, non-zero trace event + uint8_t slot; + coreTrace->reserveTraceSlot(slot); + coreTrace->setTraceEvent(slot, XAIE_EVENT_TRUE_CORE); + + coreTrace->setMode(XAIE_TRACE_INST_EXEC); + XAie_Packet pkt = {0, 0}; + coreTrace->setPkt(pkt); + coreTrace->start(); + + (db->getStaticInfo()).addAIECfgTile(deviceId, cfgTile); + continue; + } + + // Get vector of pre-defined metrics for this set + // NOTE: these are local copies as we are adding tile/counter-specific events + EventVector coreEvents; + EventVector memoryEvents; + EventVector interfaceEvents; + if (type == module_type::core) { + coreEvents = coreEventSets[metricSet]; + memoryEvents = memoryEventSets[metricSet]; + } + else if (type == module_type::mem_tile) { + memoryEvents = memoryTileEventSets[metricSet]; + } + else if (type == module_type::shim) { + interfaceEvents = interfaceTileEventSets[metricSet]; + } + + if (coreEvents.empty() && memoryEvents.empty() && interfaceEvents.empty()) { + std::stringstream msg; + msg << "Event trace is not available for " << tileName << " using metric set " + << metricSet << " on hardware generation " << metadata->getHardwareGen() << "."; + xrt_core::message::send(severity_level::warning, "XRT", msg.str()); + continue; + } + + // Check Resource Availability + if (!tileHasFreeRsc(aieDevice, loc, type, metricSet)) { + xrt_core::message::send(severity_level::warning, "XRT", + "Tile doesn't have enough free resources for trace. Aborting trace configuration."); + aie::trace::printTileStats(aieDevice, tile); + return false; + } + + int numCoreCounters = 0; + int numMemoryCounters = 0; + int numCoreTraceEvents = 0; + int numMemoryTraceEvents = 0; + int numInterfaceTraceEvents = 0; + + // + // 1. Reserve and start core module counters (as needed) + // + if ((type == module_type::core) && (coreCounterStartEvents.size() > 0)) { + if (aie::isDebugVerbosity()) { + std::stringstream msg; + msg << "Reserving " << coreCounterStartEvents.size() + << " core counters for " << tileName; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + } + + XAie_ModuleType mod = XAIE_CORE_MOD; + + for (int i = 0; i < coreCounterStartEvents.size(); ++i) { + auto perfCounter = core.perfCounter(); + if (perfCounter->initialize(mod, coreCounterStartEvents.at(i), mod, coreCounterEndEvents.at(i)) != XAIE_OK) + break; + if (perfCounter->reserve() != XAIE_OK) + break; + + // NOTE: store events for later use in trace + XAie_Events counterEvent; + perfCounter->getCounterEvent(mod, counterEvent); + int idx = static_cast(counterEvent) - static_cast(XAIE_EVENT_PERF_CNT_0_CORE); + perfCounter->changeThreshold(coreCounterEventValues.at(i)); + + // Set reset event based on counter number + perfCounter->changeRstEvent(mod, counterEvent); + coreEvents.push_back(counterEvent); + + // If no memory counters are used, then we need to broadcast the core + // counter + if (memoryCounterStartEvents.empty()) + memoryEvents.push_back(counterEvent); + + if (perfCounter->start() != XAIE_OK) + break; + + perfCounters.push_back(perfCounter); + numCoreCounters++; + + // Update config file + uint8_t phyEvent = 0; + auto& cfg = cfgTile->core_trace_config.pc[idx]; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, coreCounterStartEvents[i], &phyEvent); + cfg.start_event = phyEvent; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, coreCounterStartEvents[i], &phyEvent); + cfg.stop_event = phyEvent; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, counterEvent, &phyEvent); + cfg.reset_event = phyEvent; + cfg.event_value = coreCounterEventValues[i]; + } + } + + // + // 2. Reserve and start memory module counters (as needed) + // + if ((type == module_type::core) && (memoryCounterStartEvents.size() > 0)) { + if (aie::isDebugVerbosity()) { + std::stringstream msg; + msg << "Reserving " << memoryCounterStartEvents.size() + << " memory counters for " << tileName; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + } + + XAie_ModuleType mod = XAIE_MEM_MOD; + + for (int i = 0; i < memoryCounterStartEvents.size(); ++i) { + auto perfCounter = memory.perfCounter(); + if (perfCounter->initialize(mod, memoryCounterStartEvents.at(i), mod, memoryCounterEndEvents.at(i)) != + XAIE_OK) + break; + if (perfCounter->reserve() != XAIE_OK) + break; + + // Set reset event based on counter number + XAie_Events counterEvent; + perfCounter->getCounterEvent(mod, counterEvent); + int idx = static_cast(counterEvent) - static_cast(XAIE_EVENT_PERF_CNT_0_MEM); + perfCounter->changeThreshold(memoryCounterEventValues.at(i)); + + perfCounter->changeRstEvent(mod, counterEvent); + memoryEvents.push_back(counterEvent); + + if (perfCounter->start() != XAIE_OK) + break; + + perfCounters.push_back(perfCounter); + numMemoryCounters++; + + // Update config file + uint8_t phyEvent = 0; + auto& cfg = cfgTile->memory_trace_config.pc[idx]; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, memoryCounterStartEvents[i], &phyEvent); + cfg.start_event = phyEvent; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, memoryCounterEndEvents[i], &phyEvent); + cfg.stop_event = phyEvent; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, counterEvent, &phyEvent); + cfg.reset_event = phyEvent; + cfg.event_value = memoryCounterEventValues[i]; + } + + // Catch when counters cannot be reserved: report, release, and return + if ((numCoreCounters < coreCounterStartEvents.size()) || + (numMemoryCounters < memoryCounterStartEvents.size())) { + std::stringstream msg; + msg << "Unable to reserve " << coreCounterStartEvents.size() + << " core counters and " << memoryCounterStartEvents.size() + << " memory counters for " << tileName << " required for trace."; + xrt_core::message::send(severity_level::warning, "XRT", msg.str()); + + freeResources(); + // Print resources availability for this tile + aie::trace::printTileStats(aieDevice, tile); + return false; + } + } + + // + // 3. Configure Core Tracing Events + // + if (type == module_type::core) { + if (aie::isDebugVerbosity()) { + std::stringstream msg; + msg << "Reserving " << coreEvents.size() << " core trace events for " << tileName; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + } + + XAie_ModuleType mod = XAIE_CORE_MOD; + uint8_t phyEvent = 0; + auto coreTrace = core.traceControl(); + + // Delay cycles and user control are not compatible with each other + if (metadata->getUseGraphIterator()) { + if (!aie::trace::configStartIteration(core, metadata->getIterationCount(), + coreTraceStartEvent)) + break; + } else if (metadata->getUseDelay()) { + if (!aie::trace::configStartDelay(core, metadata->getDelay(), + coreTraceStartEvent)) + break; + } + + // Configure combo & group events (e.g., to monitor DMA channels) + auto comboEvents = aie::trace::configComboEvents(aieDevInst, xaieTile, loc, mod, type, + metricSet, cfgTile->core_trace_config); + aie::trace::configGroupEvents(aieDevInst, loc, mod, type, metricSet); + + // Set overall start/end for trace capture + if (coreTrace->setCntrEvent(coreTraceStartEvent, coreTraceEndEvent) != XAIE_OK) + break; + + auto ret = coreTrace->reserve(); + if (ret != XAIE_OK) { + std::stringstream msg; + msg << "Unable to reserve core module trace control for " << tileName; + xrt_core::message::send(severity_level::warning, "XRT", msg.str()); + + freeResources(); + // Print resources availability for this tile + aie::trace::printTileStats(aieDevice, tile); + return false; + } + + for (int i = 0; i < coreEvents.size(); i++) { + uint8_t slot; + if (coreTrace->reserveTraceSlot(slot) != XAIE_OK) + break; + if (coreTrace->setTraceEvent(slot, coreEvents[i]) != XAIE_OK) + break; + numCoreTraceEvents++; + + // Update config file + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, coreEvents[i], &phyEvent); + cfgTile->core_trace_config.traced_events[slot] = phyEvent; + } + + // Update config file + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, coreTraceStartEvent, &phyEvent); + cfgTile->core_trace_config.start_event = phyEvent; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, coreTraceEndEvent, &phyEvent); + cfgTile->core_trace_config.stop_event = phyEvent; + + // Record allocated trace events + mNumTileTraceEvents[typeInt][numCoreTraceEvents]++; + coreEvents.clear(); + + // Specify packet type and ID then start core trace + // NOTE: always use PC packets + if (coreTrace->setMode(XAIE_TRACE_EVENT_PC) != XAIE_OK) + break; + XAie_Packet pkt = {0, 0}; + if (coreTrace->setPkt(pkt) != XAIE_OK) + break; + if (coreTrace->start() != XAIE_OK) + break; + } + + // + // 4. Configure Memory Tracing Events + // + // NOTE: this is applicable for memory modules in AIE tiles or memory tiles + uint32_t coreToMemBcMask = 0; + if ((type == module_type::core) || (type == module_type::mem_tile)) { + if (aie::isDebugVerbosity()) { + xrt_core::message::send(severity_level::debug, "XRT", "Reserving " + + std::to_string(memoryEvents.size()) + " memory trace events for " + tileName); + } + + // Set overall start/end for trace capture + // NOTE: this should be done first for FAL-based implementations + auto memoryTrace = memory.traceControl(); + auto traceStartEvent = (type == module_type::core) ? coreTraceStartEvent : memoryTileTraceStartEvent; + auto traceEndEvent = (type == module_type::core) ? coreTraceEndEvent : memoryTileTraceEndEvent; + + aie_cfg_base& aieConfig = cfgTile->core_trace_config; + if (type == module_type::mem_tile) + aieConfig = cfgTile->memory_tile_trace_config; + + // Configure combo events for metric sets that include DMA events + auto comboEvents = aie::trace::configComboEvents(aieDevInst, xaieTile, loc, + XAIE_MEM_MOD, type, metricSet, aieConfig); + if (comboEvents.size() == 2) { + traceStartEvent = comboEvents.at(0); + traceEndEvent = comboEvents.at(1); + } + + // Configure event ports on stream switch + // NOTE: These are events from the core module stream switch + // outputted on the memory module trace stream. + streamPorts = aie::trace::configStreamSwitchPorts(aieDevInst, tile, + xaieTile, loc, type, metricSet, 0, 0, memoryEvents, aieConfig); + + // Set overall start/end for trace capture + if (memoryTrace->setCntrEvent(traceStartEvent, traceEndEvent) != XAIE_OK) + break; + + auto ret = memoryTrace->reserve(); + if (ret != XAIE_OK) { + std::stringstream msg; + msg << "Unable to reserve memory trace control for " << tileName; + xrt_core::message::send(severity_level::warning, "XRT", msg.str()); + + freeResources(); + // Print resources availability for this tile + aie::trace::printTileStats(aieDevice, tile); + return false; + } + + // Specify Sel0/Sel1 for memory tile events 21-44 + if (type == module_type::mem_tile) { + auto iter0 = configChannel0.find(tile); + auto iter1 = configChannel1.find(tile); + uint8_t channel0 = (iter0 == configChannel0.end()) ? 0 : iter0->second; + uint8_t channel1 = (iter1 == configChannel1.end()) ? 1 : iter1->second; + aie::trace::configEventSelections(aieDevInst, loc, type, metricSet, channel0, + channel1, cfgTile->memory_tile_trace_config); + } + else { + // Record if these are channel-specific events + // NOTE: for now, check first event and assume single channel + auto channelNum = aie::trace::getChannelNumberFromEvent(memoryEvents.at(0)); + if (channelNum >= 0) { + if (aie::isInputSet(type, metricSet)) + cfgTile->core_trace_config.mm2s_channels[0] = channelNum; + else + cfgTile->core_trace_config.s2mm_channels[0] = channelNum; + } + } + + // Configure memory trace events + for (int i = 0; i < memoryEvents.size(); i++) { + bool isCoreEvent = aie::trace::isCoreModuleEvent(memoryEvents[i]); + XAie_ModuleType mod = isCoreEvent ? XAIE_CORE_MOD : XAIE_MEM_MOD; + + auto TraceE = memory.traceEvent(); + TraceE->setEvent(mod, memoryEvents[i]); + if (TraceE->reserve() != XAIE_OK) + break; + if (TraceE->start() != XAIE_OK) + break; + numMemoryTraceEvents++; + + // Configure edge events (as needed) + aie::trace::configEdgeEvents(aieDevInst, tile, type, metricSet, memoryEvents[i]); + + // Update config file + // Get Trace slot + uint32_t S = 0; + XAie_LocType L; + XAie_ModuleType M; + TraceE->getRscId(L, M, S); + + // Get physical event + uint8_t phyEvent = 0; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, mod, memoryEvents[i], &phyEvent); + + if (isCoreEvent) { + auto bcId = TraceE->getBc(); + coreToMemBcMask |= (1 << bcId); + + cfgTile->core_trace_config.internal_events_broadcast[bcId] = phyEvent; + cfgTile->memory_trace_config.traced_events[S] = aie::bcIdToEvent(bcId); + } + else if (type == xdp::module_type::mem_tile) + cfgTile->memory_tile_trace_config.traced_events[S] = phyEvent; + else + cfgTile->memory_trace_config.traced_events[S] = phyEvent; + } + + // Add trace control events to config file + { + uint8_t phyEvent = 0; + + // Start + if (aie::trace::isCoreModuleEvent(traceStartEvent)) { + auto bcId = memoryTrace->getStartBc(); + coreToMemBcMask |= (1 << bcId); + + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, XAIE_CORE_MOD, traceStartEvent, &phyEvent); + cfgTile->core_trace_config.internal_events_broadcast[bcId] = phyEvent; + cfgTile->memory_trace_config.start_event = aie::bcIdToEvent(bcId); + } + else { + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, XAIE_MEM_MOD, traceStartEvent, &phyEvent); + if (type == module_type::mem_tile) + cfgTile->memory_tile_trace_config.start_event = phyEvent; + else + cfgTile->memory_trace_config.start_event = phyEvent; + } + + // Stop + if (aie::trace::isCoreModuleEvent(traceEndEvent)) { + auto bcId = memoryTrace->getStopBc(); + coreToMemBcMask |= (1 << bcId); + + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, XAIE_CORE_MOD, traceEndEvent, &phyEvent); + cfgTile->core_trace_config.internal_events_broadcast[bcId] = phyEvent; + cfgTile->memory_trace_config.stop_event = aie::bcIdToEvent(bcId); + + // Use east broadcasting for AIE2+ or odd absolute rows of AIE1 checkerboard + if ((row % 2) || (metadata->getHardwareGen() > 1)) + cfgTile->core_trace_config.broadcast_mask_east = coreToMemBcMask; + else + cfgTile->core_trace_config.broadcast_mask_west = coreToMemBcMask; + } + else { + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, XAIE_MEM_MOD, traceEndEvent, &phyEvent); + if (type == module_type::mem_tile) + cfgTile->memory_tile_trace_config.stop_event = phyEvent; + else + cfgTile->memory_trace_config.stop_event = phyEvent; + } + } + + // Record allocated trace events + mNumTileTraceEvents[typeInt][numMemoryTraceEvents]++; + memoryEvents.clear(); + + // Specify packet type and ID then start memory trace + // NOTE: always use time packets + if (memoryTrace->setMode(XAIE_TRACE_EVENT_TIME) != XAIE_OK) + break; + uint8_t packetType = (type == module_type::mem_tile) ? 3 : 1; + XAie_Packet pkt = {0, packetType}; + if (memoryTrace->setPkt(pkt) != XAIE_OK) + break; + if (memoryTrace->start() != XAIE_OK) + break; + + // Update memory packet type in config file + if (type == module_type::mem_tile) + cfgTile->memory_tile_trace_config.packet_type = packetType; + else + cfgTile->memory_trace_config.packet_type = packetType; + } + + // + // 5. Configure Interface Tile Tracing Events + // + if (type == module_type::shim) { + if (aie::isDebugVerbosity()) { + std::stringstream msg; + msg << "Reserving " << interfaceEvents.size() << " trace events for " << tileName; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + } + + auto shimTrace = shim.traceControl(); + if (shimTrace->setCntrEvent(interfaceTileTraceStartEvent, interfaceTileTraceEndEvent) != XAIE_OK) + break; + + auto ret = shimTrace->reserve(); + if (ret != XAIE_OK) { + std::stringstream msg; + msg << "Unable to reserve trace control for " << tileName; + xrt_core::message::send(severity_level::warning, "XRT", msg.str()); + + freeResources(); + // Print resources availability for this tile + aie::trace::printTileStats(aieDevice, tile); + return false; + } + + // Specify channels for interface tile DMA events + auto iter0 = configChannel0.find(tile); + auto iter1 = configChannel1.find(tile); + uint8_t channel0 = (iter0 == configChannel0.end()) ? 0 : iter0->second; + uint8_t channel1 = (iter1 == configChannel1.end()) ? 1 : iter1->second; + + // Modify events as needed + aie::trace::modifyEvents(type, subtype, metricSet, channel0, interfaceEvents); + + streamPorts = aie::trace::configStreamSwitchPorts(aieDevInst, tile, xaieTile, loc, type, metricSet, + channel0, channel1, interfaceEvents, + cfgTile->interface_tile_trace_config); + + // Configure interface tile trace events + for (int i = 0; i < interfaceEvents.size(); i++) { + auto event = interfaceEvents.at(i); + auto TraceE = shim.traceEvent(); + TraceE->setEvent(XAIE_PL_MOD, event); + if (TraceE->reserve() != XAIE_OK) + break; + if (TraceE->start() != XAIE_OK) + break; + numInterfaceTraceEvents++; + + // Update config file + // Get Trace slot + uint32_t S = 0; + XAie_LocType L; + XAie_ModuleType M; + TraceE->getRscId(L, M, S); + // Get Physical event + uint8_t phyEvent = 0; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, XAIE_PL_MOD, event, &phyEvent); + cfgTile->interface_tile_trace_config.traced_events[S] = phyEvent; + } + + // Update config file + { + // Add interface trace control events + // Start + uint8_t phyEvent = 0; + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, XAIE_PL_MOD, interfaceTileTraceStartEvent, &phyEvent); + cfgTile->interface_tile_trace_config.start_event = phyEvent; + // Stop + XAie_EventLogicalToPhysicalConv(aieDevInst, loc, XAIE_PL_MOD, interfaceTileTraceEndEvent, &phyEvent); + cfgTile->interface_tile_trace_config.stop_event = phyEvent; + } + + // Record allocated trace events + mNumTileTraceEvents[typeInt][numInterfaceTraceEvents]++; + + // Specify packet type and ID then start interface tile trace + // NOTE: always use time packets + if (shimTrace->setMode(XAIE_TRACE_EVENT_TIME) != XAIE_OK) + break; + uint8_t packetType = 4; + XAie_Packet pkt = {0, packetType}; + if (shimTrace->setPkt(pkt) != XAIE_OK) + break; + if (shimTrace->start() != XAIE_OK) + break; + cfgTile->interface_tile_trace_config.packet_type = packetType; + auto channelNum = aie::trace::getChannelNumberFromEvent(interfaceEvents.at(0)); + if (channelNum >= 0) { + if (aie::isInputSet(type, metricSet)) + cfgTile->interface_tile_trace_config.mm2s_channels[channelNum] = channelNum; + else + cfgTile->interface_tile_trace_config.s2mm_channels[channelNum] = channelNum; + } + } // interface tiles + + if (aie::isDebugVerbosity()) { + std::stringstream msg; + msg << "Reserved "; + if (type == module_type::core) + msg << numCoreTraceEvents << " core and " << numMemoryTraceEvents << " memory"; + else if (type == module_type::mem_tile) + msg << numMemoryTraceEvents << " memory tile"; + else if (type == module_type::shim) + msg << numInterfaceTraceEvents << " interface tile"; + msg << " trace events for " << tileName << ". Adding tile to static database."; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + } + + // Add config info to static database + // NOTE: Do not access cfgTile after this + (db->getStaticInfo()).addAIECfgTile(deviceId, cfgTile); + } // For tiles + + // Report and store trace events per tile + for (int m = 0; m < static_cast(module_type::num_types); ++m) { + aie::trace::printTraceEventStats(m, mNumTileTraceEvents[m]); + for (int n = 0; n <= NUM_TRACE_EVENTS; ++n) + (db->getStaticInfo()).addAIECoreEventResources(deviceId, n, mNumTileTraceEvents[m][n]); + } + return true; + } // end setMetricsSettings + + /**************************************************************************** + * Flush trace modules by forcing end events + * + * Trace modules buffer partial packets. At end of run, this needs to be + * flushed using a custom end event. This applies to trace windowing and + * passive tiles like memory and interface. + * + ***************************************************************************/ + void AieTrace_EdgeImpl::flushTraceModules() + { + if (traceFlushLocs.empty() && memoryTileTraceFlushLocs.empty() + && interfaceTileTraceFlushLocs.empty()) + return; + + auto handle = metadata->getHandle(); + aieDevInst = static_cast(db->getStaticInfo().getAieDevInst(fetchAieDevInst, handle)); + + if (aie::isDebugVerbosity()) { + std::stringstream msg; + msg << "Flushing AIE trace by forcing end event for " << traceFlushLocs.size() + << " AIE tiles, " << memoryTileTraceFlushLocs.size() << " memory tiles, and " + << interfaceTileTraceFlushLocs.size() << " interface tiles."; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + } + + // Flush trace by forcing end event + // NOTE: this informs tiles to output remaining packets (even if partial) + for (const auto& loc : traceFlushLocs) + XAie_EventGenerate(aieDevInst, loc, XAIE_CORE_MOD, coreTraceEndEvent); + for (const auto& loc : memoryTileTraceFlushLocs) + XAie_EventGenerate(aieDevInst, loc, XAIE_MEM_MOD, memoryTileTraceEndEvent); + for (const auto& loc : interfaceTileTraceFlushLocs) + XAie_EventGenerate(aieDevInst, loc, XAIE_PL_MOD, interfaceTileTraceEndEvent); + + traceFlushLocs.clear(); + memoryTileTraceFlushLocs.clear(); + interfaceTileTraceFlushLocs.clear(); + } + + /**************************************************************************** + * Poll AIE timers (for system timeline only) + ***************************************************************************/ + void AieTrace_EdgeImpl::pollTimers(uint64_t index, void* handle) + { + // Wait until xclbin has been loaded and device has been updated in database + if (!(db->getStaticInfo().isDeviceReady(index))) + return; + XAie_DevInst* aieDevInst = + static_cast(db->getStaticInfo().getAieDevInst(fetchAieDevInst, handle)) ; + if (!aieDevInst) + return; + + // Only read first timer and assume common time domain across all tiles + static auto tileMetrics = metadata->getConfigMetrics(); + if (tileMetrics.empty()) + return; + + static auto tile = tileMetrics.begin()->first; + auto loc = XAie_TileLoc(tile.col, tile.row); + auto moduleType = aie::getModuleType(tile.row, metadata->getRowOffset()); + auto falModuleType = (moduleType == module_type::core) ? XAIE_CORE_MOD + : ((moduleType == module_type::shim) ? XAIE_PL_MOD + : XAIE_MEM_MOD); + + uint64_t timerValue = 0; + auto timestamp1 = xrt_core::time_ns(); + XAie_ReadTimer(aieDevInst, loc, falModuleType, &timerValue); + auto timestamp2 = xrt_core::time_ns(); + + std::vector values; + values.push_back(tile.col); + values.push_back( aie::getRelativeRow(tile.row, metadata->getRowOffset()) ); + values.push_back(timerValue); + + db->getDynamicInfo().addAIETimerSample(index, timestamp1, timestamp2, values); + } +} // namespace xdp diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h b/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h new file mode 100755 index 0000000000..18d8a06b07 --- /dev/null +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h @@ -0,0 +1,92 @@ +/** + * Copyright (C) 2022-2023 Advanced Micro Devices, Inc. - All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may + * not use this file except in compliance with the License. A copy of the + * License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#ifndef AIE_TRACE_DOT_H +#define AIE_TRACE_DOT_H + +#include + +#include "xaiefal/xaiefal.hpp" +#include "xdp/profile/plugin/aie_trace/aie_trace_impl.h" +#include "xdp/profile/plugin/aie_trace/util/aie_trace_config.h" + +namespace xdp { + + class AieTrace_EdgeImpl : public AieTraceImpl { + public: + AieTrace_EdgeImpl(VPDatabase* database, std::shared_ptr metadata); + ~AieTrace_EdgeImpl() = default; + + virtual void updateDevice(); + virtual void flushTraceModules(); + void pollTimers(uint64_t index, void* handle); + void freeResources(); + + private: + uint64_t checkTraceBufSize(uint64_t size); + bool tileHasFreeRsc(xaiefal::XAieDev* aieDevice, XAie_LocType& loc, + const module_type type, const std::string& metricSet); + bool checkAieDeviceAndRuntimeMetrics(uint64_t deviceId, void* handle); + bool setMetricsSettings(uint64_t deviceId, void* handle); + + private: + typedef XAie_Events EventType; + typedef std::vector EventVector; + typedef std::vector ValueVector; + XAie_DevInst* aieDevInst = nullptr; + xaiefal::XAieDev* aieDevice = nullptr; + + // AIE resources + std::vector> perfCounters; + std::vector> streamPorts; + + std::map coreEventSets; + std::map memoryEventSets; + std::map memoryTileEventSets; + std::map interfaceTileEventSets; + + // Counter metrics (same for all sets) + EventType coreTraceStartEvent; + EventType coreTraceEndEvent; + EventType memoryTileTraceStartEvent; + EventType memoryTileTraceEndEvent; + EventType interfaceTileTraceStartEvent; + EventType interfaceTileTraceEndEvent; + + EventVector coreCounterStartEvents; + EventVector coreCounterEndEvents; + ValueVector coreCounterEventValues; + + EventVector memoryCounterStartEvents; + EventVector memoryCounterEndEvents; + ValueVector memoryCounterEventValues; + + EventVector interfaceCounterStartEvents; + EventVector interfaceCounterEndEvents; + ValueVector interfaceCounterEventValues; + + // Tile locations to apply trace end and flush + std::vector traceFlushLocs; + std::vector memoryTileTraceFlushLocs; + std::vector interfaceTileTraceFlushLocs; + + // Keep track of number of events reserved per module and/or tile + int mNumTileTraceEvents[static_cast(module_type::num_types)][NUM_TRACE_EVENTS + 1]; + }; + +} // namespace xdp + +#endif From b8d8a27bc113402760655eb3f6ee4c031cc10171 Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Thu, 19 Dec 2024 17:07:34 +0530 Subject: [PATCH 2/9] Renaming VE2 Signed-off-by: parthash0804 --- .../aie_trace_logger_ve2.h} | 0 .../aie_trace_offload_ve2.cpp} | 0 .../aie_trace_offload_ve2.h} | 0 .../profile/plugin/aie_trace/CMakeLists.txt | 12 +++++------ .../plugin/aie_trace/aie_trace_plugin.cpp | 5 +++++ .../aie_trace.cpp} | 21 +++++++++---------- .../aie_trace_telluride.h => ve2/aie_trace.h} | 6 +++--- 7 files changed, 24 insertions(+), 20 deletions(-) rename src/runtime_src/xdp/profile/device/aie_trace/{telluride/aie_trace_logger_telluride.h => ve2/aie_trace_logger_ve2.h} (100%) rename src/runtime_src/xdp/profile/device/aie_trace/{telluride/aie_trace_offload_telluride.cpp => ve2/aie_trace_offload_ve2.cpp} (100%) rename src/runtime_src/xdp/profile/device/aie_trace/{telluride/aie_trace_offload_telluride.h => ve2/aie_trace_offload_ve2.h} (100%) rename src/runtime_src/xdp/profile/plugin/aie_trace/{telluride/aie_trace_telluride.cpp => ve2/aie_trace.cpp} (98%) rename src/runtime_src/xdp/profile/plugin/aie_trace/{telluride/aie_trace_telluride.h => ve2/aie_trace.h} (94%) diff --git a/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_logger_ve2.h similarity index 100% rename from src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h rename to src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_logger_ve2.h diff --git a/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.cpp b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp similarity index 100% rename from src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.cpp rename to src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp diff --git a/src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h similarity index 100% rename from src/runtime_src/xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h rename to src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt index 960150edfe..46df52386e 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt @@ -7,10 +7,10 @@ # Edge-Versal systems, but not Edge-aarch64. It also has a dependency # on the hardware shim # ==================================================================== -if(XDP_TELLURIDE_BUILD_CMAKE STREQUAL "yes") +if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") message("**************************Inside Telluride build CMake aie_trace**************************") - set(IMPL_DIR "${PROFILE_DIR}/plugin/aie_trace/telluride") - set(OFFLOAD_DIR "${PROFILE_DIR}/device/aie_trace/telluride") + set(IMPL_DIR "${PROFILE_DIR}/plugin/aie_trace/ve2") + set(OFFLOAD_DIR "${PROFILE_DIR}/device/aie_trace/ve2") set(DEVICE_DIR "${PROFILE_DIR}/device/hal_device") elseif (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") set(IMPL_DIR "${PROFILE_DIR}/plugin/aie_trace/client") @@ -48,14 +48,14 @@ file(GLOB AIE_DRIVER_COMMON_UTIL_FILES "${PROFILE_DIR}/device/common/*.cpp" ) -if(XDP_TELLURIDE_BUILD_CMAKE STREQUAL "yes") +if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") message("**************************Inside Telluride build CMake aie_trace**************************") add_library(xdp_aie_trace_plugin MODULE ${AIE_TRACE_PLUGIN_FILES} ${AIE_TRACE_UTIL_FILES}) add_dependencies(xdp_aie_trace_plugin xdp_core xrt_coreutil) target_link_libraries(xdp_aie_trace_plugin PRIVATE xdp_core xrt_coreutil xaiengine) - target_compile_definitions(xdp_aie_trace_plugin PRIVATE FAL_LINUX="on") - + target_compile_definitions(xdp_aie_trace_plugin PRIVATE XDP_VE2_BUILD=1 FAL_LINUX="on") + target_include_directories(xdp_aie_trace_plugin PRIVATE ${CMAKE_SOURCE_DIR}/src) set_target_properties(xdp_aie_trace_plugin PROPERTIES VERSION ${XRT_VERSION_STRING} SOVERSION ${XRT_SOVERSION}) install (TARGETS xdp_aie_trace_plugin diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/aie_trace_plugin.cpp b/src/runtime_src/xdp/profile/plugin/aie_trace/aie_trace_plugin.cpp index a05ff84121..ee54587114 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/aie_trace_plugin.cpp +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/aie_trace_plugin.cpp @@ -35,6 +35,9 @@ #elif defined(XRT_X86_BUILD) #include "x86/aie_trace.h" #include "xdp/profile/device/hal_device/xdp_hal_device.h" +#elif XDP_VE2_BUILD +#include "ve2/aie_trace.h" +#include "xdp/profile/device/hal_device/xdp_hal_device.h" #else #include "edge/aie_trace.h" #include "xdp/profile/device/hal_device/xdp_hal_device.h" @@ -157,6 +160,8 @@ void AieTracePluginUnified::updateAIEDevice(void *handle) { AIEData.implementation = std::make_unique(db, AIEData.metadata); #elif defined(XRT_X86_BUILD) AIEData.implementation = std::make_unique(db, AIEData.metadata); +#elif XDP_VE2_BUILD + AIEData.implementation = std::make_unique(db, AIEData.metadata); #else AIEData.implementation = std::make_unique(db, AIEData.metadata); #endif diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.cpp b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp similarity index 98% rename from src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.cpp rename to src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp index e5ff7c911d..a5b853acc1 100755 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.cpp +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp @@ -30,7 +30,6 @@ #include "core/common/message.h" #include "core/common/time.h" -// #include "core/edge/user/shim.h" #include "core/include/xrt/xrt_kernel.h" #include "xdp/profile/database/database.h" #include "xdp/profile/database/events/creator/aie_trace_data_logger.h" @@ -40,7 +39,7 @@ #include "xdp/profile/device/tracedefs.h" #include "xdp/profile/plugin/aie_trace/aie_trace_metadata.h" #include "xdp/profile/plugin/vp_base/utility.h" -#include "../../../../../../../../src/shim/shim.h" +#include "shim/shim.h" namespace { static void* fetchAieDevInst(void* devHandle) @@ -76,7 +75,7 @@ namespace xdp { /**************************************************************************** * Constructor: AIE trace implementation for edge devices ***************************************************************************/ - AieTrace_EdgeImpl::AieTrace_EdgeImpl(VPDatabase* database, std::shared_ptr metadata) + AieTrace_VE2Impl::AieTrace_VE2Impl(VPDatabase* database, std::shared_ptr metadata) : AieTraceImpl(database, metadata) { auto hwGen = metadata->getHardwareGen(); @@ -110,7 +109,7 @@ namespace xdp { /**************************************************************************** * Verify correctness of trace buffer size ***************************************************************************/ - uint64_t AieTrace_EdgeImpl::checkTraceBufSize(uint64_t aieTraceBufSize) + uint64_t AieTrace_VE2Impl::checkTraceBufSize(uint64_t aieTraceBufSize) { uint64_t deviceMemorySize = getPSMemorySize(); if (deviceMemorySize == 0) @@ -144,7 +143,7 @@ namespace xdp { /**************************************************************************** * Check if given tile has free resources ***************************************************************************/ - bool AieTrace_EdgeImpl::tileHasFreeRsc(xaiefal::XAieDev* aieDevice, XAie_LocType& loc, + bool AieTrace_VE2Impl::tileHasFreeRsc(xaiefal::XAieDev* aieDevice, XAie_LocType& loc, const module_type type, const std::string& metricSet) { auto stats = aieDevice->getRscStat(XAIEDEV_DEFAULT_GROUP_AVAIL); @@ -232,7 +231,7 @@ namespace xdp { /**************************************************************************** * Stop and release resources (e.g., counters, ports) ***************************************************************************/ - void AieTrace_EdgeImpl::freeResources() + void AieTrace_VE2Impl::freeResources() { for (auto& c : perfCounters) { c->stop(); @@ -247,7 +246,7 @@ namespace xdp { /**************************************************************************** * Validitate AIE device and runtime metrics ***************************************************************************/ - bool AieTrace_EdgeImpl::checkAieDeviceAndRuntimeMetrics(uint64_t deviceId, void* handle) + bool AieTrace_VE2Impl::checkAieDeviceAndRuntimeMetrics(uint64_t deviceId, void* handle) { aieDevInst = static_cast(db->getStaticInfo().getAieDevInst(fetchAieDevInst, handle)); aieDevice = static_cast(db->getStaticInfo().getAieDevice(allocateAieDevice, deallocateAieDevice, handle)); @@ -268,7 +267,7 @@ namespace xdp { /**************************************************************************** * Update device (e.g., after loading xclbin) ***************************************************************************/ - void AieTrace_EdgeImpl::updateDevice() + void AieTrace_VE2Impl::updateDevice() { if (!checkAieDeviceAndRuntimeMetrics(metadata->getDeviceID(), metadata->getHandle())) return; @@ -284,7 +283,7 @@ namespace xdp { /**************************************************************************** * Configure requested tiles with trace metrics and settings ***************************************************************************/ - bool AieTrace_EdgeImpl::setMetricsSettings(uint64_t deviceId, void* handle) + bool AieTrace_VE2Impl::setMetricsSettings(uint64_t deviceId, void* handle) { if (!metadata->getIsValidMetrics()) { std::string msg("AIE trace metrics were not specified in xrt.ini. AIE event trace will not be available."); @@ -944,7 +943,7 @@ namespace xdp { * passive tiles like memory and interface. * ***************************************************************************/ - void AieTrace_EdgeImpl::flushTraceModules() + void AieTrace_VE2Impl::flushTraceModules() { if (traceFlushLocs.empty() && memoryTileTraceFlushLocs.empty() && interfaceTileTraceFlushLocs.empty()) @@ -978,7 +977,7 @@ namespace xdp { /**************************************************************************** * Poll AIE timers (for system timeline only) ***************************************************************************/ - void AieTrace_EdgeImpl::pollTimers(uint64_t index, void* handle) + void AieTrace_VE2Impl::pollTimers(uint64_t index, void* handle) { // Wait until xclbin has been loaded and device has been updated in database if (!(db->getStaticInfo().isDeviceReady(index))) diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.h similarity index 94% rename from src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h rename to src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.h index 18d8a06b07..4bf6afb284 100755 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.h @@ -25,10 +25,10 @@ namespace xdp { - class AieTrace_EdgeImpl : public AieTraceImpl { + class AieTrace_VE2Impl : public AieTraceImpl { public: - AieTrace_EdgeImpl(VPDatabase* database, std::shared_ptr metadata); - ~AieTrace_EdgeImpl() = default; + AieTrace_VE2Impl(VPDatabase* database, std::shared_ptr metadata); + ~AieTrace_VE2Impl() = default; virtual void updateDevice(); virtual void flushTraceModules(); From cb08f1f3ba3cb2a0179191535671ab11ce80e67f Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Thu, 19 Dec 2024 17:18:59 +0530 Subject: [PATCH 3/9] Bug fixes Signed-off-by: parthash0804 --- .../aie_trace/ve2/aie_trace_offload_ve2.cpp | 12 ++++++------ .../device/aie_trace/ve2/aie_trace_offload_ve2.h | 16 +--------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp index d82fc0ec75..196ef191bd 100644 --- a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp +++ b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp @@ -23,8 +23,8 @@ #include "core/include/xrt/xrt_kernel.h" #include "xdp/profile/database/database.h" #include "xdp/profile/database/static_info/aie_constructs.h" -#include "xdp/profile/device/aie_trace/telluride/aie_trace_logger_telluride.h" -#include "xdp/profile/device/aie_trace/telluride/aie_trace_offload_telluride.h" +#include "xdp/profile/device/aie_trace/ve2/aie_trace_logger_ve2.h" +#include "xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h" #include "xdp/profile/device/pl_device_intf.h" #include "xdp/profile/plugin/aie_trace/x86/aie_trace_kernel_config.h" #include @@ -33,12 +33,12 @@ * XRT_X86_BUILD is set only for x86 builds * Only compile this on edge+versal build */ -// #if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) && ! defined (XDP_CLIENT_BUILD) +#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) && ! defined (XDP_CLIENT_BUILD) #include #include "core/include/xrt.h" -// #include "core/edge/user/shim.h" -// #endif -#include "../../../../../../../../src/shim/shim.h" +#include "shim/shim.h" +#endif + namespace xdp { diff --git a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h index 3bd71a2f92..8e5f4791b7 100644 --- a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h +++ b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h @@ -20,22 +20,8 @@ #include "xdp/profile/device/tracedefs.h" -/* - * XRT_NATIVE_BUILD is set only for x86 builds - * We can only include/compile aie specific headers, when compiling for edge+versal. - * - * AIE specific edge code that needs to be protected includes: - * 1. Header file inclusions - * 2. GMIO driver specific definitions - * 3. GMIO driver calls to configure shim DMA - * - * When XRT_NATIVE_BUILD is defined, the offloading structure is: - * 1. For PL offload, same as edge - * 2. For GMIO offload, ps kernel needs to be used to initialize and read data - */ - #if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) -#include "../../../../../../../../src/shim/aie/aie.h" +#include "shim/aie/aie.h" #endif namespace xdp { From 5e751c96b2089b5f4713b28f6341f854f36b738e Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Thu, 19 Dec 2024 17:27:25 +0530 Subject: [PATCH 4/9] Bug fixes Signed-off-by: parthash0804 --- src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp index a5b853acc1..953282862c 100755 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp @@ -16,7 +16,7 @@ #define XDP_PLUGIN_SOURCE -#include "xdp/profile/plugin/aie_trace/telluride/aie_trace_telluride.h" +#include "xdp/profile/plugin/aie_trace/ve2/aie_trace_ve2.h" #include "xdp/profile/plugin/aie_trace/util/aie_trace_util.h" #include "xdp/profile/plugin/aie_trace/util/aie_trace_config.h" #include "xdp/profile/database/static_info/aie_util.h" From e35861ed396d26dd6be6119718e6a9b601c468e4 Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Thu, 19 Dec 2024 17:31:31 +0530 Subject: [PATCH 5/9] Bug fixes Signed-off-by: parthash0804 --- src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp index 953282862c..a4f1ec0578 100755 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.cpp @@ -16,7 +16,7 @@ #define XDP_PLUGIN_SOURCE -#include "xdp/profile/plugin/aie_trace/ve2/aie_trace_ve2.h" +#include "xdp/profile/plugin/aie_trace/ve2/aie_trace.h" #include "xdp/profile/plugin/aie_trace/util/aie_trace_util.h" #include "xdp/profile/plugin/aie_trace/util/aie_trace_config.h" #include "xdp/profile/database/static_info/aie_util.h" From 9d2d4c2128388a74634a98e70a7c5111c26a2e13 Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Thu, 19 Dec 2024 17:52:14 +0530 Subject: [PATCH 6/9] Enable profile Signed-off-by: parthash0804 --- .../aie_trace/ve2/aie_trace_offload_ve2.cpp | 3 +- .../xdp/profile/plugin/CMakeLists.txt | 1 - .../profile/plugin/aie_profile/CMakeLists.txt | 17 +- .../plugin/aie_profile/aie_profile_plugin.cpp | 4 + .../plugin/aie_profile/ve2/aie_profile.cpp | 1266 +++++++++++++++++ .../plugin/aie_profile/ve2/aie_profile.h | 180 +++ .../profile/plugin/aie_trace/CMakeLists.txt | 1 - 7 files changed, 1466 insertions(+), 6 deletions(-) create mode 100644 src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.cpp create mode 100644 src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.h diff --git a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp index 196ef191bd..ee7bd8290f 100644 --- a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp +++ b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp @@ -174,8 +174,7 @@ bool AIETraceOffload::initReadTrace() // Data Mover will write input stream to this address uint64_t bufAddr = deviceIntf->getTraceBufDeviceAddr(buffers[i].bufId); - std::cout<<"*******************************Inside telluride XDP***************************"<(db, AIEData.metadata); #elif defined(XRT_X86_BUILD) AIEData.implementation = std::make_unique(db, AIEData.metadata); +#elif XDP_VE2_BUILD + AIEData.implementation = std::make_unique(db, AIEData.metadata); #else AIEData.implementation = std::make_unique(db, AIEData.metadata); #endif diff --git a/src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.cpp b/src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.cpp new file mode 100644 index 0000000000..395c53786b --- /dev/null +++ b/src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.cpp @@ -0,0 +1,1266 @@ +/** + * Copyright (C) 2022-2023 Advanced Micro Devices, Inc. - All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may + * not use this file except in compliance with the License. A copy of the + * License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#define XDP_PLUGIN_SOURCE + +#include "xdp/profile/plugin/aie_profile/ve2/aie_profile.h" +#include "xdp/profile/plugin/aie_profile/aie_profile_defs.h" +#include "xdp/profile/plugin/aie_profile/util/aie_profile_util.h" +#include "xdp/profile/plugin/aie_profile/util/aie_profile_config.h" + +#include "xdp/profile/database/static_info/aie_util.h" +#include "xdp/profile/database/static_info/aie_constructs.h" + +#include +#include +#include +#include +#include + +#include "core/common/message.h" +#include "core/common/time.h" +#include "core/include/xrt/xrt_kernel.h" +#include "xdp/profile/database/database.h" +#include "xdp/profile/database/static_info/aie_constructs.h" +#include "xdp/profile/database/static_info/pl_constructs.h" +#include "xdp/profile/plugin/aie_profile/aie_profile_defs.h" +#include "xdp/profile/plugin/aie_profile/aie_profile_metadata.h" +#include "shim/shim.h" + +namespace { + static void* fetchAieDevInst(void* devHandle) + { + auto drv = aiarm::shim::handleCheck(devHandle); + if (!drv) + return nullptr ; + auto aieArray = drv->get_aie_array() ; + if (!aieArray) + return nullptr ; + return aieArray->get_dev() ; + } + + static void* allocateAieDevice(void* devHandle) + { + auto aieDevInst = static_cast(fetchAieDevInst(devHandle)) ; + if (!aieDevInst) + return nullptr; + return new xaiefal::XAieDev(aieDevInst, false) ; + } + + static void deallocateAieDevice(void* aieDevice) + { + auto object = static_cast(aieDevice) ; + if (object != nullptr) + delete object ; + } +} // end anonymous namespace + +namespace xdp { + using tile_type = xdp::tile_type; + using module_type = xdp::module_type; + using severity_level = xrt_core::message::severity_level; + + AieProfile_VE2Impl::AieProfile_VE2Impl(VPDatabase* database, std::shared_ptr metadata) + : AieProfileImpl(database, metadata) + { + auto hwGen = metadata->getHardwareGen(); + + coreStartEvents = aie::profile::getCoreEventSets(hwGen); + coreEndEvents = coreStartEvents; + + memoryStartEvents = aie::profile::getMemoryEventSets(hwGen); + memoryEndEvents = memoryStartEvents; + + shimStartEvents = aie::profile::getInterfaceTileEventSets(hwGen); + shimEndEvents = shimStartEvents; + shimEndEvents[METRIC_BYTE_COUNT] = {XAIE_EVENT_PORT_RUNNING_0_PL, XAIE_EVENT_PERF_CNT_0_PL}; + + memTileStartEvents = aie::profile::getMemoryTileEventSets(); + memTileEndEvents = memTileStartEvents; + } + + bool AieProfile_VE2Impl::checkAieDevice(const uint64_t deviceId, void* handle) + { + aieDevInst = static_cast(db->getStaticInfo().getAieDevInst(fetchAieDevInst, handle)) ; + aieDevice = static_cast(db->getStaticInfo().getAieDevice(allocateAieDevice, deallocateAieDevice, handle)) ; + if (!aieDevInst || !aieDevice) { + xrt_core::message::send(severity_level::warning, "XRT", + "Unable to get AIE device. There will be no AIE profiling."); + return false; + } + return true; + } + + void AieProfile_VE2Impl::updateDevice() { + + if(!checkAieDevice(metadata->getDeviceID(), metadata->getHandle())) + return; + + bool runtimeCounters = setMetricsSettings(metadata->getDeviceID(), metadata->getHandle()); + + if (!runtimeCounters) { + std::shared_ptr device = xrt_core::get_userpf_device(metadata->getHandle()); + auto counters = xrt_core::edge::aie::get_profile_counters(device.get()); + + if (counters.empty()) { + xrt_core::message::send(severity_level::warning, "XRT", + "AIE Profile Counters were not found for this design. Please specify tile_based_[aie|aie_memory|interface_tile]_metrics under \"AIE_profile_settings\" section in your xrt.ini."); + (db->getStaticInfo()).setIsAIECounterRead(metadata->getDeviceID(),true); + return; + } + else { + XAie_DevInst* aieDevInst = + static_cast(db->getStaticInfo().getAieDevInst(fetchAieDevInst, metadata->getHandle())); + + for (auto& counter : counters) { + tile_type tile; + auto payload = getCounterPayload(aieDevInst, tile, module_type::core, counter.column, + counter.row, counter.startEvent, "N/A", 0); + + (db->getStaticInfo()).addAIECounter(metadata->getDeviceID(), counter.id, counter.column, + counter.row, counter.counterNumber, counter.startEvent, counter.endEvent, + counter.resetEvent, payload, counter.clockFreqMhz, counter.module, counter.name); + } + } + } + } + + uint8_t AieProfile_VE2Impl::getPortNumberFromEvent(const XAie_Events event) + { + switch (event) { + case XAIE_EVENT_PORT_RUNNING_7_CORE: + case XAIE_EVENT_PORT_STALLED_7_CORE: + case XAIE_EVENT_PORT_IDLE_7_CORE: + case XAIE_EVENT_PORT_RUNNING_7_PL: + case XAIE_EVENT_PORT_STALLED_7_PL: + case XAIE_EVENT_PORT_IDLE_7_PL: + return 7; + case XAIE_EVENT_PORT_RUNNING_6_CORE: + case XAIE_EVENT_PORT_STALLED_6_CORE: + case XAIE_EVENT_PORT_IDLE_6_CORE: + case XAIE_EVENT_PORT_RUNNING_6_PL: + case XAIE_EVENT_PORT_STALLED_6_PL: + case XAIE_EVENT_PORT_IDLE_6_PL: + return 6; + case XAIE_EVENT_PORT_RUNNING_5_CORE: + case XAIE_EVENT_PORT_STALLED_5_CORE: + case XAIE_EVENT_PORT_IDLE_5_CORE: + case XAIE_EVENT_PORT_RUNNING_5_PL: + case XAIE_EVENT_PORT_STALLED_5_PL: + case XAIE_EVENT_PORT_IDLE_5_PL: + return 5; + case XAIE_EVENT_PORT_RUNNING_4_CORE: + case XAIE_EVENT_PORT_STALLED_4_CORE: + case XAIE_EVENT_PORT_IDLE_4_CORE: + case XAIE_EVENT_PORT_RUNNING_4_PL: + case XAIE_EVENT_PORT_STALLED_4_PL: + case XAIE_EVENT_PORT_IDLE_4_PL: + return 4; + case XAIE_EVENT_PORT_RUNNING_3_CORE: + case XAIE_EVENT_PORT_STALLED_3_CORE: + case XAIE_EVENT_PORT_IDLE_3_CORE: + case XAIE_EVENT_PORT_RUNNING_3_PL: + case XAIE_EVENT_PORT_STALLED_3_PL: + case XAIE_EVENT_PORT_IDLE_3_PL: + return 3; + case XAIE_EVENT_PORT_RUNNING_2_CORE: + case XAIE_EVENT_PORT_STALLED_2_CORE: + case XAIE_EVENT_PORT_IDLE_2_CORE: + case XAIE_EVENT_PORT_RUNNING_2_PL: + case XAIE_EVENT_PORT_STALLED_2_PL: + case XAIE_EVENT_PORT_IDLE_2_PL: + return 2; + case XAIE_EVENT_PORT_RUNNING_1_CORE: + case XAIE_EVENT_PORT_STALLED_1_CORE: + case XAIE_EVENT_PORT_IDLE_1_CORE: + case XAIE_EVENT_PORT_RUNNING_1_PL: + case XAIE_EVENT_PORT_STALLED_1_PL: + case XAIE_EVENT_PORT_IDLE_1_PL: + return 1; + default: + return 0; + } + } + + + // Configure stream switch ports for monitoring purposes + // NOTE: Used to monitor streams: trace, interfaces, and memory tiles + void + AieProfile_VE2Impl::configStreamSwitchPorts(XAie_DevInst* aieDevInst, const tile_type& tile, + xaiefal::XAieTile& xaieTile, const XAie_LocType loc, + const module_type type, const uint32_t numCounters, + const std::string metricSet, const uint8_t channel0, + const uint8_t channel1, std::vector& startEvents, + std::vector& endEvents) + { + std::map> switchPortMap; + + // Traverse all counters and request monitor ports as needed + for (uint32_t i=0; i < numCounters; ++i) { + // Ensure applicable event + auto startEvent = startEvents.at(i); + auto endEvent = endEvents.at(i); + if (!aie::profile::isStreamSwitchPortEvent(startEvent)) + continue; + + bool newPort = false; + auto portnum = getPortNumberFromEvent(startEvent); + uint8_t channel = (portnum == 0) ? channel0 : channel1; + + // New port needed: reserver, configure, and store + if (switchPortMap.find(portnum) == switchPortMap.end()) { + auto switchPortRsc = xaieTile.sswitchPort(); + if (switchPortRsc->reserve() != AieRC::XAIE_OK) + continue; + newPort = true; + switchPortMap[portnum] = switchPortRsc; + + if (type == module_type::core) { + int channelNum = 0; + std::string portName; + + // AIE Tiles + if (metricSet.find("trace") != std::string::npos) { + // Monitor memory or core trace (memory:1, core:0) + uint8_t traceSelect = (startEvent == XAIE_EVENT_PORT_RUNNING_0_CORE) ? 1 : 0; + switchPortRsc->setPortToSelect(XAIE_STRMSW_SLAVE, TRACE, traceSelect); + + channelNum = traceSelect; + portName = (traceSelect == 0) ? "core trace" : "memory trace"; + } + else { + auto slaveOrMaster = aie::isInputSet(type, metricSet) ? XAIE_STRMSW_SLAVE : XAIE_STRMSW_MASTER; + switchPortRsc->setPortToSelect(slaveOrMaster, DMA, channel); + + channelNum = channel; + portName = aie::isInputSet(type, metricSet) ? "DMA MM2S" : "DMA S2MM"; + } + + if (aie::isDebugVerbosity()) { + std::stringstream msg; + msg << "Configured core module stream switch to monitor " << portName + << " for metric set " << metricSet << " and channel " << channelNum; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + } + } + // Interface tiles (e.g., PLIO, GMIO) + else if (type == module_type::shim) { + // NOTE: skip configuration of extra ports for tile if stream_ids are not available. + if (portnum >= tile.stream_ids.size()) + continue; + // Grab slave/master and stream ID + auto slaveOrMaster = (tile.is_master_vec.at(portnum) == 0) ? XAIE_STRMSW_SLAVE : XAIE_STRMSW_MASTER; + uint8_t streamPortId = static_cast(tile.stream_ids.at(portnum)); + switchPortRsc->setPortToSelect(slaveOrMaster, SOUTH, streamPortId); + + if (aie::isDebugVerbosity()) { + std::string typeName = (tile.is_master_vec.at(portnum) == 0) ? "slave" : "master"; + std::string msg = "Configuring interface tile stream switch to monitor " + + typeName + " stream port " + std::to_string(streamPortId); + xrt_core::message::send(severity_level::debug, "XRT", msg); + } + } + else { + // Memory tiles + std::string typeName; + uint32_t channelNum = 0; + + if (metricSet.find("trace") != std::string::npos) { + typeName = "trace"; + switchPortRsc->setPortToSelect(XAIE_STRMSW_SLAVE, TRACE, 0); + } + else { + auto slaveOrMaster = aie::isInputSet(type, metricSet) ? XAIE_STRMSW_MASTER : XAIE_STRMSW_SLAVE; + switchPortRsc->setPortToSelect(slaveOrMaster, DMA, channel); + + typeName = (slaveOrMaster == XAIE_STRMSW_MASTER) ? "master" : "slave"; + channelNum = channel; + } + + if (aie::isDebugVerbosity()) { + std::string msg = "Configuring memory tile stream switch to monitor " + + typeName + " stream port " + std::to_string(channelNum); + xrt_core::message::send(severity_level::debug, "XRT", msg); + } + } + } + + auto switchPortRsc = switchPortMap[portnum]; + + // Event options: + // getSSIdleEvent, getSSRunningEvent, getSSStalledEvent, & getSSTlastEvent + XAie_Events ssEvent; + if (aie::profile::isPortRunningEvent(startEvent)) + switchPortRsc->getSSRunningEvent(ssEvent); + else if (aie::profile::isPortTlastEvent(startEvent)) + switchPortRsc->getSSTlastEvent(ssEvent); + else if (aie::profile::isPortStalledEvent(startEvent)) + switchPortRsc->getSSStalledEvent(ssEvent); + else + switchPortRsc->getSSIdleEvent(ssEvent); + + startEvents.at(i) = ssEvent; + endEvents.at(i) = ssEvent; + + if (newPort) { + switchPortRsc->start(); + streamPorts.push_back(switchPortRsc); + } + } + + switchPortMap.clear(); + } + + // Get reportable payload specific for this tile and/or counter + uint64_t + AieProfile_VE2Impl::getCounterPayload(XAie_DevInst* aieDevInst, + const tile_type& tile, + const module_type type, + uint8_t column, + uint8_t row, + uint16_t startEvent, + const std::string metricSet, + const uint8_t channel) + { + // 1. Profile API specific values + if (aie::profile::profileAPIMetricSet(metricSet)) + return getAdfProfileAPIPayload(tile, metricSet); + + // 2. Channel/stream IDs for interface tiles + if (type == module_type::shim) { + // NOTE: value = ((isMaster) << 8) & (isChannel << 7) & (channel/stream ID) + auto portnum = getPortNumberFromEvent(static_cast(startEvent)); + uint8_t streamPortId = (portnum >= tile.stream_ids.size()) ? + 0 : static_cast(tile.stream_ids.at(portnum)); + uint8_t idToReport = (tile.subtype == io_type::GMIO) ? channel : streamPortId; + uint8_t isChannel = (tile.subtype == io_type::GMIO) ? 1 : 0; + uint8_t isMaster = (portnum >= tile.is_master_vec.size()) ? + 0 : static_cast(tile.is_master_vec.at(portnum)); + + return ((isMaster << PAYLOAD_IS_MASTER_SHIFT) + | (isChannel << PAYLOAD_IS_CHANNEL_SHIFT) | idToReport); + } + + // 3. Channel IDs for memory tiles + if (type == module_type::mem_tile) { + // NOTE: value = ((isMaster) << 8) & (isChannel << 7) & (channel ID) + uint8_t isChannel = 1; + uint8_t isMaster = aie::isInputSet(type, metricSet) ? 1 : 0; + return ((isMaster << PAYLOAD_IS_MASTER_SHIFT) + | (isChannel << PAYLOAD_IS_CHANNEL_SHIFT) | channel); + } + + // 4. DMA BD sizes for AIE tiles + // NOTE: value = ((max BD size) << 16) & ((isMaster) << 8) & (isChannel << 7) & (channel ID) + uint8_t isChannel = 1; + uint8_t isMaster = aie::isInputSet(type, metricSet) ? 1 : 0; + uint32_t payloadValue = ((isMaster << PAYLOAD_IS_MASTER_SHIFT) + | (isChannel << PAYLOAD_IS_CHANNEL_SHIFT) | channel); + + if ((metadata->getHardwareGen() != 1) + || ((startEvent != XAIE_EVENT_DMA_S2MM_0_FINISHED_BD_MEM) + && (startEvent != XAIE_EVENT_DMA_S2MM_1_FINISHED_BD_MEM) + && (startEvent != XAIE_EVENT_DMA_MM2S_0_FINISHED_BD_MEM) + && (startEvent != XAIE_EVENT_DMA_MM2S_1_FINISHED_BD_MEM))) + return payloadValue; + + // Get average BD size for throughput calculations (AIE1 only) + constexpr int NUM_BDS = 8; + constexpr uint32_t BYTES_PER_WORD = 4; + constexpr uint32_t ACTUAL_OFFSET = 1; + uint64_t offsets[NUM_BDS] = {XAIEGBL_MEM_DMABD0CTRL, XAIEGBL_MEM_DMABD1CTRL, + XAIEGBL_MEM_DMABD2CTRL, XAIEGBL_MEM_DMABD3CTRL, + XAIEGBL_MEM_DMABD4CTRL, XAIEGBL_MEM_DMABD5CTRL, + XAIEGBL_MEM_DMABD6CTRL, XAIEGBL_MEM_DMABD7CTRL}; + uint32_t lsbs[NUM_BDS] = {XAIEGBL_MEM_DMABD0CTRL_LEN_LSB, XAIEGBL_MEM_DMABD1CTRL_LEN_LSB, + XAIEGBL_MEM_DMABD2CTRL_LEN_LSB, XAIEGBL_MEM_DMABD3CTRL_LEN_LSB, + XAIEGBL_MEM_DMABD4CTRL_LEN_LSB, XAIEGBL_MEM_DMABD5CTRL_LEN_LSB, + XAIEGBL_MEM_DMABD6CTRL_LEN_LSB, XAIEGBL_MEM_DMABD7CTRL_LEN_LSB}; + uint32_t masks[NUM_BDS] = {XAIEGBL_MEM_DMABD0CTRL_LEN_MASK, XAIEGBL_MEM_DMABD1CTRL_LEN_MASK, + XAIEGBL_MEM_DMABD2CTRL_LEN_MASK, XAIEGBL_MEM_DMABD3CTRL_LEN_MASK, + XAIEGBL_MEM_DMABD4CTRL_LEN_MASK, XAIEGBL_MEM_DMABD5CTRL_LEN_MASK, + XAIEGBL_MEM_DMABD6CTRL_LEN_MASK, XAIEGBL_MEM_DMABD7CTRL_LEN_MASK}; + uint32_t valids[NUM_BDS] = {XAIEGBL_MEM_DMABD0CTRL_VALBD_MASK, XAIEGBL_MEM_DMABD1CTRL_VALBD_MASK, + XAIEGBL_MEM_DMABD2CTRL_VALBD_MASK, XAIEGBL_MEM_DMABD3CTRL_VALBD_MASK, + XAIEGBL_MEM_DMABD4CTRL_VALBD_MASK, XAIEGBL_MEM_DMABD5CTRL_VALBD_MASK, + XAIEGBL_MEM_DMABD6CTRL_VALBD_MASK, XAIEGBL_MEM_DMABD7CTRL_VALBD_MASK}; + + uint32_t maxBDSize = 0; + auto tileOffset = XAie_GetTileAddr(aieDevInst, row, column); + for (int bd = 0; bd < NUM_BDS; ++bd) { + uint32_t regValue = 0; + XAie_Read32(aieDevInst, tileOffset + offsets[bd], ®Value); + + if (regValue & valids[bd]) { + uint32_t bdBytes = BYTES_PER_WORD * (((regValue >> lsbs[bd]) & masks[bd]) + ACTUAL_OFFSET); + maxBDSize = std::max(bdBytes, maxBDSize); + } + } + + payloadValue |= (maxBDSize << PAYLOAD_BD_SIZE_SHIFT); + return payloadValue; + } + + uint64_t + AieProfile_VE2Impl::getAdfProfileAPIPayload(const tile_type& tile, const std::string metricSet) + { + if (metricSet == METRIC_LATENCY) + return metadata->getIntfLatencyPayload(tile); + + return 0; + } + + void AieProfile_VE2Impl::printTileModStats(xaiefal::XAieDev* aieDevice, + const tile_type& tile, XAie_ModuleType mod) + { + auto col = tile.col; + auto row = tile.row; + auto loc = XAie_TileLoc(col, row); + std::string moduleName = (mod == XAIE_CORE_MOD) ? "aie" + : ((mod == XAIE_MEM_MOD) ? "aie_memory" + : "interface_tile"); + const std::string groups[3] = { + XAIEDEV_DEFAULT_GROUP_GENERIC, + XAIEDEV_DEFAULT_GROUP_STATIC, + XAIEDEV_DEFAULT_GROUP_AVAIL + }; + + std::stringstream msg; + msg << "Resource usage stats for Tile : (" << +col << "," << +row + << ") Module : " << moduleName << std::endl; + for (auto&g : groups) { + auto stats = aieDevice->getRscStat(g); + auto pc = stats.getNumRsc(loc, mod, xaiefal::XAIE_PERFCOUNT); + auto ts = stats.getNumRsc(loc, mod, xaiefal::XAIE_TRACEEVENT); + auto bc = stats.getNumRsc(loc, mod, xaiefal::XAIE_BROADCAST); + msg << "Resource Group : " << std::left << std::setw(10) << g << " " + << "Performance Counters : " << pc << " " + << "Trace Slots : " << ts << " " + << "Broadcast Channels : " << bc << " " + << std::endl; + } + + xrt_core::message::send(severity_level::info, "XRT", msg.str()); + } + + // Set metrics for all specified AIE counters on this device with configs given in AIE_profile_settings + bool + AieProfile_VE2Impl::setMetricsSettings(const uint64_t deviceId, void* handle) + { + int counterId = 0; + bool runtimeCounters = false; + + auto stats = aieDevice->getRscStat(XAIEDEV_DEFAULT_GROUP_AVAIL); + auto configChannel0 = metadata->getConfigChannel0(); + auto configChannel1 = metadata->getConfigChannel1(); + uint8_t startColShift = metadata->getPartitionOverlayStartCols().front(); + aie::displayColShiftInfo(startColShift); + + for (int module = 0; module < metadata->getNumModules(); ++module) { + auto configMetrics = metadata->getConfigMetricsVec(module); + if (configMetrics.empty()) + continue; + + int numTileCounters[metadata->getNumCountersMod(module)+1] = {0}; + XAie_ModuleType mod = aie::profile::getFalModuleType(module); + + // Iterate over tiles and metrics to configure all desired counters + for (auto& tileMetric : configMetrics) { + auto& metricSet = tileMetric.second; + auto tile = tileMetric.first; + auto col = tile.col + startColShift; + auto row = tile.row; + auto subtype = tile.subtype; + auto type = aie::getModuleType(row, metadata->getAIETileRowOffset()); + if ((mod == XAIE_MEM_MOD) && (type == module_type::core)) + type = module_type::dma; + + // Ignore invalid types and inactive modules + // NOTE: Inactive core modules are configured when utilizing + // stream switch monitor ports to profile DMA channels + if (!aie::profile::isValidType(type, mod)) + continue; + if ((type == module_type::dma) && !tile.active_memory) + continue; + if ((type == module_type::core) && !tile.active_core) { + if (metadata->getPairModuleIndex(metricSet, type) < 0) + continue; + } + + auto loc = XAie_TileLoc(col, row); + auto& xaieTile = aieDevice->tile(col, row); + auto xaieModule = (mod == XAIE_CORE_MOD) ? xaieTile.core() + : ((mod == XAIE_MEM_MOD) ? xaieTile.mem() + : xaieTile.pl()); + + auto startEvents = (type == module_type::core) ? coreStartEvents[metricSet] + : ((type == module_type::dma) ? memoryStartEvents[metricSet] + : ((type == module_type::shim) ? shimStartEvents[metricSet] + : memTileStartEvents[metricSet])); + auto endEvents = (type == module_type::core) ? coreEndEvents[metricSet] + : ((type == module_type::dma) ? memoryEndEvents[metricSet] + : ((type == module_type::shim) ? shimEndEvents[metricSet] + : memTileEndEvents[metricSet])); + std::vector resetEvents = {}; + + int numCounters = 0; + auto numFreeCtr = stats.getNumRsc(loc, mod, xaiefal::XAIE_PERFCOUNT); + numFreeCtr = (startEvents.size() < numFreeCtr) ? startEvents.size() : numFreeCtr; + + int numFreeCtrSS = numFreeCtr; + if (aie::profile::profileAPIMetricSet(metricSet)) { + if (numFreeCtr < 2) { + continue; + } + // We need to monitor single stream switch monitor port + // numFreeCtrSS = 1 ; + } + + // Specify Sel0/Sel1 for memory tile events 21-44 + auto iter0 = configChannel0.find(tile); + auto iter1 = configChannel1.find(tile); + uint8_t channel0 = (iter0 == configChannel0.end()) ? 0 : iter0->second; + uint8_t channel1 = (iter1 == configChannel1.end()) ? 1 : iter1->second; + + // Modify events as needed + aie::profile::modifyEvents(type, subtype, channel0, startEvents, metadata->getHardwareGen()); + endEvents = startEvents; + + // TBD : Placeholder to configure AIE core with required profile counters. + aie::profile::configEventSelections(aieDevInst, loc, type, metricSet, channel0); + // TBD : Placeholder to configure shim tile with required profile counters. + + configStreamSwitchPorts(aieDevInst, tileMetric.first, xaieTile, loc, type, numFreeCtrSS, + metricSet, channel0, channel1, startEvents, endEvents); + + // Identify the profiling API metric sets and configure graph events + if (metadata->getUseGraphIterator() && !graphItrBroadcastConfigDone) { + XAie_Events bcEvent = XAIE_EVENT_NONE_CORE; + bool status = configGraphIteratorAndBroadcast(xaieModule, + loc, mod, type, metricSet, metadata->getIterationCount(), bcEvent); + if (status) { + graphIteratorBrodcastChannelEvent = bcEvent; + graphItrBroadcastConfigDone = true; + } + } + + if (aie::profile::profileAPIMetricSet(metricSet)) { + // Re-use the existing port running event for both the counters + startEvents[startEvents.size()-1] = startEvents[0]; + + // Use start events as End events for profile counters if threshold is not provided + endEvents[endEvents.size()-1] = endEvents[0]; + + // Use the set values broadcast events for the reset of counter + resetEvents = {XAIE_EVENT_NONE_CORE, XAIE_EVENT_NONE_CORE}; + if (type == module_type::shim) { + if (metadata->getUseGraphIterator()) + resetEvents = {graphIteratorBrodcastChannelEvent, graphIteratorBrodcastChannelEvent}; + else + resetEvents = {XAIE_EVENT_NONE_CORE, XAIE_EVENT_USER_EVENT_1_PL}; + } + } + + uint32_t threshold = 0; + // Request and configure all available counters for this tile + for (int i=0; i < numFreeCtr; ++i) { + auto startEvent = startEvents.at(i); + auto endEvent = endEvents.at(i); + XAie_Events resetEvent = XAIE_EVENT_NONE_CORE; + auto portnum = getPortNumberFromEvent(startEvent); + uint8_t channel = (portnum == 0) ? channel0 : channel1; + + // Configure group event before reserving and starting counter + aie::profile::configGroupEvents(aieDevInst, loc, mod, type, metricSet, startEvent, channel); + + // Configure the profile counters for profile APIs metric sets. + std::shared_ptr perfCounter = nullptr; + if (aie::profile::profileAPIMetricSet(metricSet)) { + resetEvent = resetEvents.at(i); + threshold = metadata->getUserSpecifiedThreshold(tileMetric.first, tileMetric.second); + threshold = aie::profile::convertToBeats(tileMetric.second, threshold, metadata->getHardwareGen()); + + if (i==0 && threshold>0) + endEvent = XAIE_EVENT_PERF_CNT_1_PL; + + if (i==1 && threshold == 0) + continue; + + XAie_Events retCounterEvent = XAIE_EVENT_NONE_CORE; + perfCounter = configProfileAPICounters(xaieModule, mod, type, + metricSet, startEvent, endEvent, resetEvent, i, + threshold, retCounterEvent, tile); + } + else { + // Request counter from resource manager + perfCounter = xaieModule.perfCounter(); + auto ret = perfCounter->initialize(mod, startEvent, mod, endEvent); + if (ret != XAIE_OK) break; + ret = perfCounter->reserve(); + if (ret != XAIE_OK) break; + + // Start the counter + ret = perfCounter->start(); + if (ret != XAIE_OK) break; + } + if (!perfCounter) + continue; + perfCounters.push_back(perfCounter); + + // Generate user_event_1 for byte count metric set after configuration + if ((metricSet == METRIC_BYTE_COUNT) && (i == 1) && !graphItrBroadcastConfigDone) { + XAie_LocType tileloc = XAie_TileLoc(tile.col, tile.row); + //Note: For BYTE_COUNT metric, user_event_1 is used twice as eventA & eventB to + // to transition the FSM from Idle->State0->State1. + // eventC = Port Running and eventD = stop event (counter event). + XAie_EventGenerate(aieDevInst, tileloc, mod, XAIE_EVENT_USER_EVENT_1_PL); + XAie_EventGenerate(aieDevInst, tileloc, mod, XAIE_EVENT_USER_EVENT_1_PL); + } + + // Convert enums to physical event IDs for reporting purposes + auto physicalEventIds = getEventPhysicalId(loc, mod, type, metricSet, startEvent, endEvent); + uint16_t phyStartEvent = physicalEventIds.first; + uint16_t phyEndEvent = physicalEventIds.second; + + // Get payload for reporting purposes + uint64_t payload = getCounterPayload(aieDevInst, tileMetric.first, type, col, row, + startEvent, metricSet, channel); + // Store counter info in database + std::string counterName = "AIE Counter " + std::to_string(counterId); + (db->getStaticInfo()).addAIECounter(deviceId, counterId, col, row, i, + phyStartEvent, phyEndEvent, resetEvent, payload, metadata->getClockFreqMhz(), + metadata->getModuleName(module), counterName); + counterId++; + numCounters++; + } // numFreeCtr + + std::stringstream msg; + msg << "Reserved " << numCounters << " counters for profiling AIE tile (" << +col + << "," << +row << ") using metric set " << metricSet << "."; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + numTileCounters[numCounters]++; + } // configMetrics + + // Report counters reserved per tile + { + std::stringstream msg; + msg << "AIE profile counters reserved in " << metadata->getModuleName(module) << " - "; + for (int n=0; n <= metadata->getNumCountersMod(module); ++n) { + if (numTileCounters[n] == 0) + continue; + msg << n << ": " << numTileCounters[n] << " tiles, "; + (db->getStaticInfo()).addAIECounterResources(deviceId, n, numTileCounters[n], module); + } + xrt_core::message::send(severity_level::info, "XRT", msg.str().substr(0, msg.str().size()-2)); + } + + runtimeCounters = true; + } // modules + + return runtimeCounters; + } + + void AieProfile_VE2Impl::poll(const uint32_t index, void* handle) + { + // Wait until xclbin has been loaded and device has been updated in database + if (!(db->getStaticInfo().isDeviceReady(index))) + return; + XAie_DevInst* aieDevInst = + static_cast(db->getStaticInfo().getAieDevInst(fetchAieDevInst, handle)) ; + if (!aieDevInst) + return; + + uint32_t prevColumn = 0; + uint32_t prevRow = 0; + uint64_t timerValue = 0; + + // Iterate over all AIE Counters & Timers + auto numCounters = db->getStaticInfo().getNumAIECounter(index); + for (uint64_t c=0; c < numCounters; c++) { + auto aie = db->getStaticInfo().getAIECounter(index, c); + if (!aie) + continue; + + std::vector values; + values.push_back(aie->column); + values.push_back(aie::getRelativeRow(aie->row, metadata->getAIETileRowOffset())); + values.push_back(aie->startEvent); + values.push_back(aie->endEvent); + values.push_back(aie->resetEvent); + + // Read counter value from device + uint32_t counterValue; + if (perfCounters.empty()) { + // Compiler-defined counters + XAie_LocType tileLocation = XAie_TileLoc(aie->column, aie->row); + XAie_PerfCounterGet(aieDevInst, tileLocation, XAIE_CORE_MOD, aie->counterNumber, &counterValue); + } + else { + // Runtime-defined counters + if (aie::profile::adfAPILatencyConfigEvent(aie->startEvent)) + { + uint32_t srcCounterValue = 0; + uint32_t destCounterValue = 0; + try { + std::string srcDestPairKey = metadata->getSrcDestPairKey(aie->column, aie->row); + uint8_t srcPcIdx = adfAPIResourceInfoMap.at(aie::profile::adfAPI::INTF_TILE_LATENCY).at(srcDestPairKey).srcPcIdx; + uint8_t destPcIdx = adfAPIResourceInfoMap.at(aie::profile::adfAPI::INTF_TILE_LATENCY).at(srcDestPairKey).destPcIdx; + auto srcPerfCount = perfCounters.at(srcPcIdx); + auto destPerfCount = perfCounters.at(destPcIdx); + srcPerfCount->readResult(srcCounterValue); + destPerfCount->readResult(destCounterValue); + counterValue = (destCounterValue > srcCounterValue) ? (destCounterValue-srcCounterValue) : (srcCounterValue-destCounterValue); + uint64_t storedValue = adfAPIResourceInfoMap[aie::profile::adfAPI::INTF_TILE_LATENCY][srcDestPairKey].profileResult; + if (counterValue != storedValue) + adfAPIResourceInfoMap[aie::profile::adfAPI::INTF_TILE_LATENCY][srcDestPairKey].profileResult = counterValue; + } catch(...) { + continue; + } + } + else if (aie::profile::adfAPIStartToTransferredConfigEvent(aie->startEvent)) + { + try { + std::string srcKey = "(" + aie::uint8ToStr(aie->column) + "," + aie::uint8ToStr(aie->row) + ")"; + uint8_t srcPcIdx = adfAPIResourceInfoMap.at(aie::profile::adfAPI::START_TO_BYTES_TRANSFERRED).at(srcKey).srcPcIdx; + auto perfCounter = perfCounters.at(srcPcIdx); + perfCounter->readResult(counterValue); + uint64_t storedValue = adfAPIResourceInfoMap[aie::profile::adfAPI::START_TO_BYTES_TRANSFERRED][srcKey].profileResult; + if (counterValue != storedValue) + adfAPIResourceInfoMap[aie::profile::adfAPI::START_TO_BYTES_TRANSFERRED][srcKey].profileResult = counterValue; + } catch(...) { + continue; + } + } + else { + auto perfCounter = perfCounters.at(c); + perfCounter->readResult(counterValue); + } + } + values.push_back(counterValue); + + // Read tile timer (once per tile to minimize overhead) + if ((aie->column != prevColumn) || (aie->row != prevRow)) { + prevColumn = aie->column; + prevRow = aie->row; + auto moduleType = aie::getModuleType(aie->row, metadata->getAIETileRowOffset()); + auto falModuleType = (moduleType == module_type::core) ? XAIE_CORE_MOD + : ((moduleType == module_type::shim) ? XAIE_PL_MOD + : XAIE_MEM_MOD); + XAie_LocType tileLocation = XAie_TileLoc(aie->column, aie->row); + XAie_ReadTimer(aieDevInst, tileLocation, falModuleType, &timerValue); + } + values.push_back(timerValue); + values.push_back(aie->payload); + + // Get timestamp in milliseconds + double timestamp = xrt_core::time_ns() / 1.0e6; + db->getDynamicInfo().addAIESample(index, timestamp, values); + } + } + + void AieProfile_VE2Impl::freeResources() + { + displayAdfAPIResults(); + for (auto& c : perfCounters){ + c->stop(); + c->release(); + } + + for (auto& c : streamPorts){ + c->stop(); + c->release(); + } + + for (auto &bc : bcResourcesBytesTx) { + bc->stop(); + bc->release(); + } + + for (auto &bc : bcResourcesLatency) { + bc->stop(); + bc->release(); + } + } + + std::shared_ptr + AieProfile_VE2Impl::configProfileAPICounters(xaiefal::XAieMod& xaieModule, + XAie_ModuleType& xaieModType, const module_type xdpModType, + const std::string& metricSet, XAie_Events startEvent, + XAie_Events endEvent, XAie_Events resetEvent, + int pcIndex, size_t threshold, XAie_Events& retCounterEvent, + const tile_type& tile) + { + if (xdpModType != module_type::shim) + return nullptr; + + if (metricSet == METRIC_LATENCY && pcIndex==0) { + bool isSourceTile = true; + auto pc = configIntfLatency(xaieModule, xaieModType, xdpModType, + metricSet, startEvent, endEvent, resetEvent, + pcIndex, threshold, retCounterEvent, tile, isSourceTile); + std::string srcDestPairKey = metadata->getSrcDestPairKey(tile.col, tile.row); + if (isSourceTile) { + adfAPIResourceInfoMap[aie::profile::adfAPI::INTF_TILE_LATENCY][srcDestPairKey].isSourceTile = true; + adfAPIResourceInfoMap[aie::profile::adfAPI::INTF_TILE_LATENCY][srcDestPairKey].srcPcIdx = perfCounters.size(); + } + else { + adfAPIResourceInfoMap[aie::profile::adfAPI::INTF_TILE_LATENCY][srcDestPairKey].destPcIdx = perfCounters.size(); + } + return pc; + } + + if (metricSet == METRIC_BYTE_COUNT && pcIndex==0) { + auto pc = configPCUsingComboEvents(xaieModule, xaieModType, xdpModType, + metricSet, startEvent, endEvent, resetEvent, + pcIndex, threshold, retCounterEvent); + std::string srcKey = "(" + aie::uint8ToStr(tile.col) + "," + aie::uint8ToStr(tile.row) + ")"; + adfAPIResourceInfoMap[aie::profile::adfAPI::START_TO_BYTES_TRANSFERRED][srcKey].srcPcIdx = perfCounters.size(); + adfAPIResourceInfoMap[aie::profile::adfAPI::START_TO_BYTES_TRANSFERRED][srcKey].isSourceTile = true; + return pc; + } + + // Request counter from resource manager + auto pc = xaieModule.perfCounter(); + auto ret = pc->initialize(xaieModType, startEvent, + xaieModType, endEvent); + if (ret != XAIE_OK) + return nullptr; + + ret = pc->reserve(); + if (ret != XAIE_OK) + return nullptr; + + if (resetEvent != XAIE_EVENT_NONE_CORE) + pc->changeRstEvent(xaieModType, resetEvent); + + if (threshold > 0) + pc->changeThreshold(threshold); + + XAie_Events counterEvent; + pc->getCounterEvent(xaieModType, counterEvent); + + // Start the counter + ret = pc->start(); + if (ret != XAIE_OK) return nullptr; + + // Respond back with this performance counter event + // to use it later for broadcasting + retCounterEvent = counterEvent; + return pc; + } + + std::shared_ptr + AieProfile_VE2Impl::configPCUsingComboEvents(xaiefal::XAieMod& xaieModule, + XAie_ModuleType& xaieModType, const module_type xdpModType, + const std::string& metricSet, XAie_Events startEvent, + XAie_Events endEvent, XAie_Events resetEvent, + int pcIndex, size_t threshold, XAie_Events& retCounterEvent) + { + if ((xdpModType != module_type::shim) || (xaieModType != XAIE_PL_MOD)) + return nullptr; + + std::shared_ptr comboEvent0 = nullptr; + std::vector combo_events; + std::vector combo_opts; + std::vector comboConfigedEvents; + XAie_Events newStartEvent = XAIE_EVENT_NONE_CORE; + + // Request combo event from xaie module + auto pc = xaieModule.perfCounter(); + auto ret = pc->initialize(xaieModType, startEvent, + xaieModType, endEvent); + + if (ret != XAIE_OK) return nullptr; + ret = pc->reserve(); + if (ret != XAIE_OK) return nullptr; + + XAie_Events counterEvent; + pc->getCounterEvent(xaieModType, counterEvent); + + if (resetEvent != XAIE_EVENT_NONE_CORE) + pc->changeRstEvent(xaieModType, resetEvent); + + // Configure the combo events if user has specified valid non zero threshold + // if (threshold==0) + // return startCounter(pc, counterEvent, retCounterEvent); + + // Set up a combo event using start & count event type + comboEvent0 = xaieModule.comboEvent(4); + ret = comboEvent0->reserve(); + if (ret != XAIE_OK) + return nullptr; + + // Set up the combo event with FSM type using 4 events state machine + XAie_Events eventA = (resetEvent != XAIE_EVENT_NONE_CORE) ? resetEvent : XAIE_EVENT_USER_EVENT_1_PL; + XAie_Events eventB = XAIE_EVENT_USER_EVENT_1_PL; + XAie_Events eventC = startEvent; + XAie_Events eventD = endEvent; + + combo_events.push_back(eventA); + combo_events.push_back(eventB); + combo_events.push_back(eventC); + combo_events.push_back(eventD); + + // This is NO-OP for COMBO3, necessary for FAL & generates COMBO 1 & 2 events as well + combo_opts.push_back(XAIE_EVENT_COMBO_E1_OR_E2); + combo_opts.push_back(XAIE_EVENT_COMBO_E1_OR_E2); + combo_opts.push_back(XAIE_EVENT_COMBO_E1_OR_E2); + + ret = comboEvent0->setEvents(combo_events, combo_opts); + if (ret != XAIE_OK) + return nullptr; + + ret = comboEvent0->getEvents(comboConfigedEvents); + if (ret != XAIE_OK) + return nullptr; + + // Change the start event to above combo event type + newStartEvent = XAIE_EVENT_COMBO_EVENT_3_PL; + ret = pc->changeStartEvent(xaieModType, newStartEvent); + if (ret != XAIE_OK) + return nullptr; + + // Start the combo event 0 + ret = comboEvent0->start(); + if (ret != XAIE_OK) + return nullptr; + + return startCounter(pc, counterEvent, retCounterEvent); + } + + std::shared_ptr + AieProfile_VE2Impl::configIntfLatency(xaiefal::XAieMod& xaieModule, + XAie_ModuleType& xaieModType, const module_type xdpModType, + const std::string& metricSet, XAie_Events startEvent, + XAie_Events endEvent, XAie_Events resetEvent, int pcIndex, + size_t threshold, XAie_Events& retCounterEvent, + const tile_type& tile, bool& isSource) + { + // Request combo event from xaie module + auto pc = xaieModule.perfCounter(); + + if (!metadata->isValidLatencyTile(tile)) + return nullptr; + + startEvent = XAIE_EVENT_USER_EVENT_0_PL; + if (!metadata->isSourceTile(tile)) { + auto bcPair = setupBroadcastChannel(tile); + startEvent = bcPair.second; + isSource = false; + } + + auto ret = pc->initialize(xaieModType, startEvent, + xaieModType, endEvent); + if (ret != XAIE_OK) + return nullptr; + + ret = pc->reserve(); + if (ret != XAIE_OK) + return nullptr; + + // Start the counter + ret = pc->start(); + if (ret != XAIE_OK) + return nullptr; + + XAie_LocType tileloc = XAie_TileLoc(tile.col, tile.row); + + // uint8_t status = -1; + // uint8_t broadcastId = 10; + + if (isSource) { + auto bc_pair = setupBroadcastChannel(tile); + if (bc_pair.first == -1) + return nullptr; + + uint8_t broadcastId = static_cast(bc_pair.first); + // Set up of the brodcast of event over channel + XAie_EventBroadcast(aieDevInst, tileloc, XAIE_PL_MOD, broadcastId, XAIE_EVENT_USER_EVENT_0_PL); + + XAie_EventGenerate(aieDevInst, tileloc, xaieModType, XAIE_EVENT_USER_EVENT_0_PL); + } + + // to use it later for broadcasting + return pc; + } + + /**************************************************************************** + * Configure the individual AIE events for metric sets related to Profile APIs + ***************************************************************************/ + bool AieProfile_VE2Impl::configGraphIteratorAndBroadcast(xaiefal::XAieMod core, + XAie_LocType loc, const XAie_ModuleType xaieModType, + const module_type xdpModType, const std::string metricSet, + uint32_t iterCount, XAie_Events& bcEvent) + { + bool rc = false; + if (!aie::profile::metricSupportsGraphIterator(metricSet)) + return rc; + + if (xdpModType != module_type::core) { + auto aieCoreTilesVec = metadata->getTiles("all", module_type::core, "all"); + if (aieCoreTilesVec.empty()) { + std::stringstream msg; + msg << "No core tiles available, graph ieration profiling will not be available.\n"; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + return rc; + } + + // Use the first available core tile to configure the broadcasting + uint8_t col = aieCoreTilesVec.begin()->col; + uint8_t row = aieCoreTilesVec.begin()->row; + auto& xaieTile = aieDevice->tile(col, row); + core = xaieTile.core(); + loc = XAie_TileLoc(col, row); + } + + std::stringstream msg; + msg << "Configuring AIE profile start_to_bytes_transferred to start on iteration " << iterCount + << " using core tile (" << +loc.Col << "," << +loc.Row << ").\n"; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + + XAie_Events counterEvent; + // Step 1: Configure the graph iterator event + configStartIteration(core, iterCount, counterEvent); + + // Step 2: Configure the brodcast of the returned counter event + XAie_Events bcChannelEvent; + configEventBroadcast(loc, module_type::core, metricSet, XAIE_CORE_MOD, + counterEvent, bcChannelEvent); + + // Store the brodcasted channel event for later use + bcEvent = bcChannelEvent; + return true; + } + + /**************************************************************************** + * Configure AIE Core module start on graph iteration count threshold + ***************************************************************************/ + bool AieProfile_VE2Impl::configStartIteration(xaiefal::XAieMod core, uint32_t iteration, + XAie_Events& retCounterEvent) + { + XAie_ModuleType mod = XAIE_CORE_MOD; + // Count up by 1 for every iteration + auto pc = core.perfCounter(); + if (pc->initialize(mod, XAIE_EVENT_INSTR_EVENT_0_CORE, + mod, XAIE_EVENT_INSTR_EVENT_0_CORE) != XAIE_OK) + return false; + if (pc->reserve() != XAIE_OK) + return false; + + pc->changeThreshold(iteration); + + XAie_Events counterEvent; + pc->getCounterEvent(mod, counterEvent); + + if (pc->start() != XAIE_OK) + return false; + + // performance counter event to use it later for broadcasting + retCounterEvent = counterEvent; + return true; + } + + /**************************************************************************** + * Configure the broadcasting of provided module and event + * (Brodcasted from AIE Tile core module) + ***************************************************************************/ + void AieProfile_VE2Impl::configEventBroadcast(const XAie_LocType loc, + const module_type xdpModType, + const std::string metricSet, + const XAie_ModuleType xaieModType, + const XAie_Events bcEvent, + XAie_Events& bcChannelEvent) + { + auto bcPair = aie::profile::getPreferredPLBroadcastChannel(); + + std::vector vL; + AieRC RC = AieRC::XAIE_OK; + + // vL.push_back(loc); + // aie::profile::getAllInterfaceTileLocs(vL); + std::vector allIntfTiles = metadata->getInterfaceTiles("all", "all", METRIC_BYTE_COUNT); + std::set allIntfTilesSet(allIntfTiles.begin(), allIntfTiles.end()); + if (allIntfTilesSet.empty()) + return; + + for (auto &tile : allIntfTilesSet) { + vL.push_back(XAie_TileLoc(tile.col, tile.row)); + } + + auto BC = aieDevice->broadcast(vL, XAIE_PL_MOD, XAIE_PL_MOD); + if (!BC) + return; + + bcResourcesBytesTx.push_back(BC); + BC->setPreferredId(bcPair.first); + + RC = BC->reserve(); + if (RC != XAIE_OK) + return; + + RC = BC->start(); + if (RC != XAIE_OK) + return; + + uint8_t bcId = BC->getBc(); + XAie_Events channelEvent; + RC = BC->getEvent(vL.front(), XAIE_PL_MOD, channelEvent); + if (RC != XAIE_OK) + return; + + uint8_t brodcastId = bcId; + int driverStatus = AieRC::XAIE_OK; + driverStatus |= XAie_EventBroadcast(aieDevInst, loc, XAIE_CORE_MOD, brodcastId, bcEvent); + if (driverStatus != XAIE_OK) { + std::stringstream msg; + msg << "Configuration of graph iteration event from core tile "<< +loc.Col << "," << +loc.Row + << " is unavailable, graph ieration profiling will not be available.\n"; + xrt_core::message::send(severity_level::debug, "XRT", msg.str()); + return; + } + + // This is the broadcast channel event seen in interface tiles + bcChannelEvent = channelEvent; + } + + /**************************************************************************** + * Get physical event IDs for metric set + ***************************************************************************/ + std::pair + AieProfile_VE2Impl::getEventPhysicalId(XAie_LocType& tileLoc, + XAie_ModuleType& xaieModType, module_type xdpModType, + const std::string& metricSet, + XAie_Events startEvent, XAie_Events endEvent) + { + if (aie::profile::profileAPIMetricSet(metricSet)) { + uint16_t eventId = aie::profile::getAdfApiReservedEventId(metricSet); + return std::make_pair(eventId, eventId); + } + + uint8_t tmpStart; + uint8_t tmpEnd; + XAie_EventLogicalToPhysicalConv(aieDevInst, tileLoc, xaieModType, startEvent, &tmpStart); + XAie_EventLogicalToPhysicalConv(aieDevInst, tileLoc, xaieModType, endEvent, &tmpEnd); + uint16_t phyStartEvent = tmpStart + aie::profile::getCounterBase(xdpModType); + uint16_t phyEndEvent = tmpEnd + aie::profile::getCounterBase(xdpModType); + return std::make_pair(phyStartEvent, phyEndEvent); + } + + /**************************************************************************** + * Initialize broadcast channels + ***************************************************************************/ + std::pair + AieProfile_VE2Impl::setupBroadcastChannel(const tile_type& currTileLoc) + { + tile_type srcTile = currTileLoc; + if (!metadata->isSourceTile(currTileLoc)) + if (!metadata->getSourceTile(currTileLoc, srcTile)) + return {-1, XAIE_EVENT_NONE_CORE}; + + if (adfAPIBroadcastEventsMap.find(srcTile) == adfAPIBroadcastEventsMap.end()) { + // auto bcPair = aie::profile::getPreferredPLBroadcastChannel(); + auto bcPair = getPLBroadcastChannel(srcTile); + if (bcPair.first == -1 || bcPair.second == XAIE_EVENT_NONE_CORE) { + return {-1, XAIE_EVENT_NONE_CORE}; + } + adfAPIBroadcastEventsMap[srcTile] = bcPair; + } + return adfAPIBroadcastEventsMap.at(srcTile); + } + + /**************************************************************************** + * Get and configure broadcast channels from source to destination tiles + * NOTE: This function applies to interface tiles only + ***************************************************************************/ + std::pair + AieProfile_VE2Impl::getPLBroadcastChannel(const tile_type& srcTile) + { + std::pair rc(-1, XAIE_EVENT_NONE_PL); + AieRC RC = AieRC::XAIE_OK; + tile_type destTile; + + metadata->getDestTile(srcTile, destTile); + XAie_LocType destTileLocation = XAie_TileLoc(destTile.col, destTile.row); + + // Include all tiles between source and destination + std::vector bcTileVec; + for (uint8_t c = std::min(srcTile.col, destTile.col); c <= std::max(srcTile.col, destTile.col); ++c) { + auto tileLocation = XAie_TileLoc(c, srcTile.row); + bcTileVec.push_back(tileLocation); + } + + auto BC = aieDevice->broadcast(bcTileVec, XAIE_PL_MOD, XAIE_PL_MOD); + if (!BC) + return rc; + bcResourcesLatency.push_back(BC); + + auto bcPair = aie::profile::getPreferredPLBroadcastChannel(); + BC->setPreferredId(bcPair.first); + + RC = BC->reserve(); + if (RC != XAIE_OK) + return rc; + + RC = BC->start(); + if (RC != XAIE_OK) + return rc; + + uint8_t bcId = BC->getBc(); + XAie_Events bcEvent; + RC = BC->getEvent(destTileLocation, XAIE_PL_MOD, bcEvent); + if (RC != XAIE_OK) + return rc; + + std::pair bcPairSelected = std::make_pair(bcId, bcEvent); + return bcPairSelected; + } + + /**************************************************************************** + * Display start to bytes or latency results to output transcript + ***************************************************************************/ + void AieProfile_VE2Impl::displayAdfAPIResults() + { + for (auto &adfAPIType : adfAPIResourceInfoMap) { + if (adfAPIType.first == aie::profile::adfAPI::START_TO_BYTES_TRANSFERRED) { + for (auto &adfApiResource : adfAPIType.second) { + std::stringstream msg; + msg << "Total start to bytes transferred for tile " << adfApiResource.first << " is " + << +adfApiResource.second.profileResult << " clock cycles for specified bytes."; + xrt_core::message::send(severity_level::warning, "XRT", msg.str()); + } + } + else if (adfAPIType.first == aie::profile::adfAPI::INTF_TILE_LATENCY) { + for(auto &adfApiResource : adfAPIType.second) { + GraphPortPair graphPortPair; + try { + graphPortPair = metadata->getSrcDestGraphPair(adfApiResource.first); + } + catch (...) { + continue; + } + + std::stringstream msg; + msg << "Total latency between " << graphPortPair.srcGraphName + << ":" << graphPortPair.srcGraphPort << " and " + << graphPortPair.destGraphName << ":" << graphPortPair.destGraphPort + << " is " << +adfApiResource.second.profileResult << " clock cycles."; + xrt_core::message::send(severity_level::warning, "XRT", msg.str()); + } + } + } + } + + } diff --git a/src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.h b/src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.h new file mode 100644 index 0000000000..946948f36e --- /dev/null +++ b/src/runtime_src/xdp/profile/plugin/aie_profile/ve2/aie_profile.h @@ -0,0 +1,180 @@ +/** + * Copyright (C) 2022-2023 Advanced Micro Devices, Inc. - All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may + * not use this file except in compliance with the License. A copy of the + * License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#ifndef AIE_PROFILE_H +#define AIE_PROFILE_H + +#include + +#include "core/edge/common/aie_parser.h" +#include "xdp/profile/plugin/aie_profile/aie_profile_impl.h" +#include "xdp/profile/plugin/aie_profile/util/aie_profile_util.h" +#include "xaiefal/xaiefal.hpp" + +extern "C" { +#include +#include +} + +namespace xdp { + using tile_type = xdp::tile_type; + + class AieProfile_VE2Impl : public AieProfileImpl{ + public: + // AieProfile_VE2Impl(VPDatabase* database, std::shared_ptr metadata) + // : AieProfileImpl(database, metadata){} + AieProfile_VE2Impl(VPDatabase* database, std::shared_ptr metadata); + + ~AieProfile_VE2Impl() = default; + + void updateDevice(); + void poll(const uint32_t index, void* handle); + void freeResources(); + bool checkAieDevice(const uint64_t deviceId, void* handle); + + bool setMetricsSettings(const uint64_t deviceId, void* handle); + uint8_t getPortNumberFromEvent(const XAie_Events event); + void printTileModStats(xaiefal::XAieDev* aieDevice, + const tile_type& tile, + const XAie_ModuleType mod); + void configStreamSwitchPorts(XAie_DevInst* aieDevInst, + const tile_type& tile, + xaiefal::XAieTile& xaieTile, + const XAie_LocType loc, + const module_type type, + const uint32_t numCounters, + const std::string metricSet, + const uint8_t channel0, + const uint8_t channel1, + std::vector& startEvents, + std::vector& endEvents); + + uint64_t getCounterPayload(XAie_DevInst* aieDevInst, + const tile_type& tile, + const module_type type, + uint8_t column, + uint8_t row, + uint16_t startEvent, + const std::string metricSet, + const uint8_t channel); + + uint64_t getAdfProfileAPIPayload(const tile_type& tile, const std::string metricSet); + + private: + std::shared_ptr + configProfileAPICounters(xaiefal::XAieMod& xaieModule, XAie_ModuleType& xaieModType, const module_type xdpModType, + const std::string& metricSet, XAie_Events startEvent, + XAie_Events endEvent, XAie_Events resetEvent, + int pcIndex, size_t threshold, XAie_Events& retCounterEvent, + const tile_type& tile); + + std::shared_ptr + configPCUsingComboEvents(xaiefal::XAieMod& xaieModule, XAie_ModuleType& xaieModType, const module_type xdpModType, + const std::string& metricSet, XAie_Events startEvent, + XAie_Events endEvent, XAie_Events resetEvent, + int pcIndex, size_t threshold, XAie_Events& retCounterEvent); + + std::shared_ptr + configIntfLatency(xaiefal::XAieMod& xaieModule, XAie_ModuleType& xaieModType, + const module_type xdpModType, const std::string& metricSet, + XAie_Events startEvent, XAie_Events endEvent, + XAie_Events resetEvent, int pcIndex, size_t threshold, + XAie_Events& retCounterEvent, + const tile_type& tile, bool& isSource); + + bool + configStartIteration(xaiefal::XAieMod core, uint32_t iteration, + XAie_Events& retCounterEvent); + + void + configEventBroadcast(const XAie_LocType loc, + const module_type xdpModType, + const std::string metricSet, + const XAie_ModuleType xaieModType, + const XAie_Events bcEvent, + XAie_Events& bcChannelEvent); + + bool + configGraphIteratorAndBroadcast(xaiefal::XAieMod core, + XAie_LocType loc, const XAie_ModuleType xaieModType, + const module_type xdpModType, const std::string metricSet, + uint32_t iterCount, XAie_Events& bcEvent); + + std::pair + getEventPhysicalId(XAie_LocType& tileLoc, + XAie_ModuleType& xaieModType, module_type xdpModType, + const std::string& metricSet, + XAie_Events startEvent, XAie_Events endEvent); + + std::pair + setupBroadcastChannel(const tile_type& currTileLoc); + + inline std::shared_ptr + startCounter(std::shared_ptr& pc, + XAie_Events counterEvent, XAie_Events& retCounterEvent) + { + if (!pc) + return nullptr; + + auto ret = pc->start(); + if (ret != XAIE_OK) + return nullptr; + + // Return the known counter event + retCounterEvent = counterEvent; + return pc; + } + + std::pair + getPLBroadcastChannel(const tile_type& srcTile); + + void + displayAdfAPIResults(); + + private: + XAie_DevInst* aieDevInst = nullptr; + xaiefal::XAieDev* aieDevice = nullptr; + + std::map> coreStartEvents; + std::map> coreEndEvents; + std::map> memoryStartEvents; + std::map> memoryEndEvents; + std::map> shimStartEvents; + std::map> shimEndEvents; + std::map> memTileStartEvents; + std::map> memTileEndEvents; + std::vector> perfCounters; + std::vector> streamPorts; + + bool graphItrBroadcastConfigDone = false; + // Graph Iterator broadcast channel event + // This event is used to reset/configure the counters in interface tiles + XAie_Events graphIteratorBrodcastChannelEvent = XAIE_EVENT_NONE_CORE; + + // This event is asserted in another interface tile + XAie_Events latencyUserBrodcastChannelEvent = XAIE_EVENT_NONE_CORE; + + std::map> adfAPIResourceInfoMap; + + // This stores the map of location of tile and configured broadcast channel event + std::map> adfAPIBroadcastEventsMap; + + std::vector> bcResourcesBytesTx; + std::vector> bcResourcesLatency; + }; +} + +#endif diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt index 46df52386e..db10c349fb 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt @@ -49,7 +49,6 @@ file(GLOB AIE_DRIVER_COMMON_UTIL_FILES ) if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") - message("**************************Inside Telluride build CMake aie_trace**************************") add_library(xdp_aie_trace_plugin MODULE ${AIE_TRACE_PLUGIN_FILES} ${AIE_TRACE_UTIL_FILES}) add_dependencies(xdp_aie_trace_plugin xdp_core xrt_coreutil) From e8461368a09724dc3dc9c52e2085b13d2a8e5ae2 Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Thu, 19 Dec 2024 19:19:29 +0530 Subject: [PATCH 7/9] Remove prints and enable profile from cmake Signed-off-by: parthash0804 --- src/runtime_src/xdp/profile/plugin/CMakeLists.txt | 3 ++- src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt | 1 + src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/runtime_src/xdp/profile/plugin/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/CMakeLists.txt index 8221c451a9..467f464ab0 100644 --- a/src/runtime_src/xdp/profile/plugin/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/CMakeLists.txt @@ -2,7 +2,8 @@ # Copyright (C) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. # -if(XDP_TELLURIDE_BUILD_CMAKE STREQUAL "yes") +if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") + add_subdirectory(aie_profile) add_subdirectory(aie_trace) elseif (XDP_CLIENT_BUILD_CMAKE STREQUAL "yes") diff --git a/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt index 372d95fe1f..94e470997e 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt @@ -41,6 +41,7 @@ if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") add_dependencies(xdp_aie_profile_plugin xdp_core xrt_coreutil) target_link_libraries(xdp_aie_profile_plugin PRIVATE xdp_core xrt_coreutil xaiengine) target_compile_definitions(xdp_aie_profile_plugin PRIVATE XDP_VE2_BUILD=1 FAL_LINUX="on") + target_include_directories(xdp_aie_profile_plugin PRIVATE ${CMAKE_SOURCE_DIR}/src) set_target_properties(xdp_aie_profile_plugin PROPERTIES VERSION ${XRT_VERSION_STRING} SOVERSION ${XRT_SOVERSION}) install (TARGETS xdp_aie_profile_plugin diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt index db10c349fb..2009cf468e 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt @@ -8,7 +8,6 @@ # on the hardware shim # ==================================================================== if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") - message("**************************Inside Telluride build CMake aie_trace**************************") set(IMPL_DIR "${PROFILE_DIR}/plugin/aie_trace/ve2") set(OFFLOAD_DIR "${PROFILE_DIR}/device/aie_trace/ve2") set(DEVICE_DIR "${PROFILE_DIR}/device/hal_device") From f325621a8e2aaf9a1f208206c3bf81adec4193f4 Mon Sep 17 00:00:00 2001 From: parthash0804 Date: Fri, 20 Dec 2024 15:51:20 +0530 Subject: [PATCH 8/9] Remove sleep Signed-off-by: parthash0804 --- src/runtime_src/core/common/config_reader.h | 9 --------- .../device/aie_trace/ve2/aie_trace_offload_ve2.cpp | 5 ----- 2 files changed, 14 deletions(-) diff --git a/src/runtime_src/core/common/config_reader.h b/src/runtime_src/core/common/config_reader.h index 34f8191471..863f0ff693 100644 --- a/src/runtime_src/core/common/config_reader.h +++ b/src/runtime_src/core/common/config_reader.h @@ -1025,15 +1025,6 @@ get_aie_trace_settings_enable_system_timeline() return value; } -inline bool -get_aie_trace_settings_sim_trace_time_s() -{ - static unsigned int value = detail::get_uint_value("AIE_trace_settings.sim_trace_time_s", 0); - return value; -} - - - }} // config,xrt_core #endif diff --git a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp index ee7bd8290f..b9bfb6e0b0 100644 --- a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp +++ b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp @@ -505,11 +505,6 @@ void AIETraceOffload::continuousOffload() mReadTrace(false); std::this_thread::sleep_for(std::chrono::microseconds(offloadIntervalUs)); } - - uint64_t simTraceTimeS = xrt_core::config::get_aie_trace_settings_sim_trace_time_s(); - std::cout<<"******************************************** sleep provided in xrt.ini : "< Date: Mon, 23 Dec 2024 14:21:18 +0530 Subject: [PATCH 9/9] Changes as suggested in PR comments Signed-off-by: parthash0804 --- .../aie_trace/ve2/aie_trace_logger_ve2.h | 5 ++- .../aie_trace/ve2/aie_trace_offload_ve2.cpp | 38 ++++--------------- .../aie_trace/ve2/aie_trace_offload_ve2.h | 24 +++--------- .../profile/plugin/aie_profile/CMakeLists.txt | 2 +- .../profile/plugin/aie_trace/CMakeLists.txt | 4 +- .../profile/plugin/aie_trace/ve2/aie_trace.h | 2 +- 6 files changed, 19 insertions(+), 56 deletions(-) diff --git a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_logger_ve2.h b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_logger_ve2.h index 370af45eec..10c4104cea 100644 --- a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_logger_ve2.h +++ b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_logger_ve2.h @@ -1,5 +1,6 @@ /** * Copyright (C) 2020 Xilinx, Inc + * Copyright (C) 2022-2024 Advanced Micro Devices, Inc. - All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"). You may * not use this file except in compliance with the License. A copy of the @@ -14,8 +15,8 @@ * under the License. */ -#ifndef XDP_PROFILE_AIE_TRACE_LOGGER_H -#define XDP_PROFILE_AIE_TRACE_LOGGER_H +#ifndef XDP_PROFILE_AIE_TRACE_VE2_LOGGER_H +#define XDP_PROFILE_AIE_TRACE_VE2_LOGGER_H #include #include diff --git a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp index b9bfb6e0b0..a270c0ecbd 100644 --- a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp +++ b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.cpp @@ -19,6 +19,7 @@ #include +#include "core/include/xrt.h" #include "core/common/message.h" #include "core/include/xrt/xrt_kernel.h" #include "xdp/profile/database/database.h" @@ -27,17 +28,12 @@ #include "xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h" #include "xdp/profile/device/pl_device_intf.h" #include "xdp/profile/plugin/aie_trace/x86/aie_trace_kernel_config.h" -#include +#include "shim/shim.h" -/* - * XRT_X86_BUILD is set only for x86 builds - * Only compile this on edge+versal build - */ -#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) && ! defined (XDP_CLIENT_BUILD) +#include #include -#include "core/include/xrt.h" -#include "shim/shim.h" -#endif + + namespace xdp { @@ -153,14 +149,8 @@ bool AIETraceOffload::initReadTrace() return success; #endif -/* - * XRT_X86_BUILD is set only for x86 builds - * Only compile this on edge+versal build - */ -#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) - gmioDMAInsts.clear(); - gmioDMAInsts.resize(numStream); -#endif + gmioDMAInsts.clear(); + gmioDMAInsts.resize(numStream); } checkCircularBufferSupport(); @@ -181,11 +171,6 @@ bool AIETraceOffload::initReadTrace() if (isPLIO) { deviceIntf->initAIETs2mm(bufAllocSz, bufAddr, i, mEnCircularBuf); } else { - /* - * XRT_X86_BUILD is set only for x86 builds - * Only compile this on edge+versal build - */ -#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) VPDatabase* db = VPDatabase::Instance(); TraceGMIO* traceGMIO = (db->getStaticInfo()).getTraceGMIO(deviceId, i); @@ -236,8 +221,6 @@ bool AIETraceOffload::initReadTrace() // Enqueue BD XAie_DmaChannelPushBdToQueue(devInst, gmioDMAInsts[i].gmioTileLoc, channelNumber, dir, bdNum); - -#endif } } bufferInitialized = true; @@ -255,11 +238,6 @@ void AIETraceOffload::endReadTrace() deviceIntf->resetAIETs2mm(i); // deviceIntf->freeTraceBuf(b.bufId); } else { -/* - * XRT_NATIVE_BUILD is set only for x86 builds - * Only compile this on edge+versal build - */ -#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) VPDatabase* db = VPDatabase::Instance(); TraceGMIO* traceGMIO = (db->getStaticInfo()).getTraceGMIO(deviceId, i); @@ -275,8 +253,6 @@ void AIETraceOffload::endReadTrace() XAie_DmaDirection dir = (traceGMIO->channelNumber > 1) ? DMA_MM2S : DMA_S2MM; XAie_DmaChannelDisable(devInst, gmioDMAInsts[i].gmioTileLoc, channelNumber, dir); -#endif - } deviceIntf->freeTraceBuf(buffers[i].bufId); buffers[i].bufId = 0; diff --git a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h index 8e5f4791b7..b5013b5a55 100644 --- a/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h +++ b/src/runtime_src/xdp/profile/device/aie_trace/ve2/aie_trace_offload_ve2.h @@ -1,6 +1,6 @@ /** * Copyright (C) 2020-2022 Xilinx, Inc - * Copyright (C) 2022-2023 Advanced Micro Devices, Inc. - All rights reserved + * Copyright (C) 2022-2024 Advanced Micro Devices, Inc. - All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"). You may * not use this file except in compliance with the License. A copy of the @@ -15,14 +15,12 @@ * under the License. */ -#ifndef XDP_PROFILE_AIE_TRACE_OFFLOAD_H_ -#define XDP_PROFILE_AIE_TRACE_OFFLOAD_H_ +#ifndef XDP_PROFILE_AIE_TRACE_OFFLOAD_VE2_H_ +#define XDP_PROFILE_AIE_TRACE_OFFLOAD_VE2_H_ #include "xdp/profile/device/tracedefs.h" - -#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) #include "shim/aie/aie.h" -#endif + namespace xdp { @@ -52,18 +50,12 @@ struct AIETraceBufferInfo {} }; -/* - * XRT_NATIVE_BUILD is set only for x86 builds - * Only compile this on edge+versal build - */ -#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) struct AIETraceGmioDMAInst { // C_RTS Shim DMA to where this GMIO object is mapped XAie_DmaDesc shimDmaInst; XAie_LocType gmioTileLoc; }; -#endif enum class AIEOffloadThreadStatus { IDLE, @@ -119,14 +111,8 @@ class AIETraceOffload //Internal use only // Set this for verbose trace offload bool m_debug = false; - -/* - * XRT_NATIVE_BUILD is set only for x86 builds - * Only compile this on edge+versal build - */ -#if defined (XRT_ENABLE_AIE) && ! defined (XRT_X86_BUILD) std::vector gmioDMAInsts; -#endif + // Continuous Trace Offload (For PLIO) bool traceContinuous; diff --git a/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt index 94e470997e..6793c50d64 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/aie_profile/CMakeLists.txt @@ -4,7 +4,7 @@ # ==================================================================== # This builds the AIE Profile plugin. It is currently built -# on both Edge and x86 platforms that support AIE. +# on both Edge, x86, client and ve2 platforms that support AIE. # ==================================================================== if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt index 2009cf468e..af0f9c5aee 100644 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/CMakeLists.txt @@ -3,8 +3,8 @@ # # ==================================================================== -# This builds the AIE Trace plugin. It is currently built on x86 and -# Edge-Versal systems, but not Edge-aarch64. It also has a dependency +# This builds the AIE Trace plugin. It is currently built on x86, +# Edge-Versal systems, client and ve2 but not Edge-aarch64. It also has a dependency # on the hardware shim # ==================================================================== if(XDP_VE2_BUILD_CMAKE STREQUAL "yes") diff --git a/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.h b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.h index 4bf6afb284..6a320ba6be 100755 --- a/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.h +++ b/src/runtime_src/xdp/profile/plugin/aie_trace/ve2/aie_trace.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2022-2023 Advanced Micro Devices, Inc. - All rights reserved + * Copyright (C) 2022-2024 Advanced Micro Devices, Inc. - All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"). You may * not use this file except in compliance with the License. A copy of the