diff --git a/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.cpp b/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.cpp index f53bbefb44..c8cfb1decf 100644 --- a/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.cpp +++ b/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.cpp @@ -60,8 +60,8 @@ namespace xdp { } }; - MLTimelineClientDevImpl::MLTimelineClientDevImpl(VPDatabase*dB) - : MLTimelineImpl(dB) + MLTimelineClientDevImpl::MLTimelineClientDevImpl(VPDatabase*dB, uint32_t sz) + : MLTimelineImpl(dB, sz) { xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT", "Created ML Timeline Plugin for Client Device."); @@ -134,16 +134,16 @@ namespace xdp { // Record Timer TS in JSON // Assuming correct Stub has been called and Write Buffer contains valid data - uint32_t max_count = mBufSz / (3*sizeof(uint32_t)); + uint32_t maxCount = mBufSz / RECORD_TIMER_ENTRY_SZ_IN_BYTES; // Each record timer entry has 32bit ID and 32bit AIE High Timer + 32bit AIE Low Timer value. - uint32_t numEntries = max_count; + uint32_t numEntries = maxCount; std::stringstream msg; msg << "A maximum of " << numEntries << " record can be accommodated in given buffer of bytes size 0x" << std::hex << mBufSz << std::dec << std::endl; xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT", msg.str()); - if (numEntries <= max_count) { + if (numEntries <= maxCount) { for (uint32_t i = 0 ; i < numEntries; i++) { boost::property_tree::ptree ptIdTS; uint32_t id = *ptr; diff --git a/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.h b/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.h index 743720e5e1..c190bc61ff 100644 --- a/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.h +++ b/src/runtime_src/xdp/profile/plugin/ml_timeline/clientDev/ml_timeline.h @@ -27,7 +27,7 @@ namespace xdp { { std::unique_ptr mResultBOHolder; public : - MLTimelineClientDevImpl(VPDatabase* dB); + MLTimelineClientDevImpl(VPDatabase* dB, uint32_t sz); ~MLTimelineClientDevImpl(); diff --git a/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_impl.h b/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_impl.h index 5b1c768d9e..80515bf363 100644 --- a/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_impl.h +++ b/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_impl.h @@ -21,6 +21,9 @@ namespace xdp { + // Each record timer entry has 32bit ID and 32bit AIE High Timer + 32bit AIE Low Timer value. + constexpr uint32_t RECORD_TIMER_ENTRY_SZ_IN_BYTES = 3*sizeof(uint32_t); + class VPDatabase; class MLTimelineImpl @@ -30,8 +33,9 @@ namespace xdp { uint32_t mBufSz; public: - MLTimelineImpl(VPDatabase* dB) - : db(dB) + MLTimelineImpl(VPDatabase* dB, uint32_t sz) + : db(dB), + mBufSz(sz) {} MLTimelineImpl() = delete; @@ -40,11 +44,6 @@ namespace xdp { virtual void updateDevice(void*) = 0; virtual void finishflushDevice(void*, uint64_t) = 0; - - void setBufSize(uint32_t sz) - { - mBufSz = sz; - } }; } diff --git a/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_plugin.cpp b/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_plugin.cpp index 2d3a0a687e..375d59e0a5 100644 --- a/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_plugin.cpp +++ b/src/runtime_src/xdp/profile/plugin/ml_timeline/ml_timeline_plugin.cpp @@ -38,30 +38,47 @@ namespace xdp { uint32_t ParseMLTimelineBufferSizeConfig() { - uint32_t bufSz = 0x20000; + uint32_t bufSz = 0; std::string szCfgStr = xrt_core::config::get_ml_timeline_buffer_size(); std::smatch subStr; + std::stringstream msg; + const std::regex validSzRegEx("\\s*([0-9]+)\\s*(K|k|M|m|)\\s*"); if (std::regex_match(szCfgStr, subStr, validSzRegEx)) { + uint32_t szKB = 0; try { if ("K" == subStr[2] || "k" == subStr[2]) { - bufSz = (uint32_t)std::stoull(subStr[1]) * uint_constants::one_kb; + szKB = (uint32_t)std::stoull(subStr[1]); } else if ("M" == subStr[2] || "m" == subStr[2]) { - bufSz = (uint32_t)std::stoull(subStr[1]) * uint_constants::one_mb; + // Convert to KB now + szKB = (uint32_t)std::stoull(subStr[1]) * uint_constants::one_kb; + } + if (0 != (szKB % RECORD_TIMER_ENTRY_SZ_IN_BYTES)) { + /* Adjust given ML Timeline Buffer Size for alignment to avoid incorrect reads when Host Buffer + * gets overwritten with excess record timer data. + */ + uint32_t q = szKB / RECORD_TIMER_ENTRY_SZ_IN_BYTES; + // Round up to next 12KB aligned size + szKB = (q + 1) * RECORD_TIMER_ENTRY_SZ_IN_BYTES; + bufSz = szKB * uint_constants::one_kb; + std::stringstream amsg; + amsg << "Adjusting given ML Timeline Buffer Size " << szCfgStr + << " to 0x" << std::hex << bufSz << std::dec << " (in bytes) for alignment." << std::endl; + xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT", amsg.str()); + } else if (szKB) { + bufSz = szKB * uint_constants::one_kb; } - } catch (const std::exception &e) { - std::stringstream msg; - msg << "Invalid string specified for ML Timeline Buffer Size. Using default size of 128KB." - << e.what() << std::endl; - xrt_core::message::send(xrt_core::message::severity_level::warning, "XRT", msg.str()); + msg << "Hit exception " << e.what() << ". "; } - - } else { - xrt_core::message::send(xrt_core::message::severity_level::warning, "XRT", - "Invalid string specified for ML Timeline Buffer Size. Using default size of 128KB."); } + if (0 == bufSz) { + bufSz = 0x30000; + msg << "Invalid string " << szCfgStr << " specified for ML Timeline Buffer Size. Using default size of 192KB." << std::endl; + xrt_core::message::send(xrt_core::message::severity_level::warning, "XRT", msg.str()); + } + return bufSz; } @@ -117,9 +134,8 @@ namespace xdp { (db->getStaticInfo()).updateDeviceClient(deviceId, coreDevice, false); (db->getStaticInfo()).setDeviceName(deviceId, winDeviceName); - mMultiImpl[hwCtxImpl] = std::make_pair(implId, std::make_unique(db)); + mMultiImpl[hwCtxImpl] = std::make_pair(implId, std::make_unique(db, mBufSz)); auto mlImpl = mMultiImpl[hwCtxImpl].second.get(); - mlImpl->setBufSize(mBufSz); mlImpl->updateDevice(hwCtxImpl); #endif