diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 966e47c9..d847d761 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -305,10 +305,10 @@ void TlmRecorder::prepareSqlStatements() "UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name"; insertGeneralInfoString = - "INSERT INTO GeneralInfo VALUES" - "(:numberOfTransactions, :end, :numberOfRanks, :numberOfBankGroups, :numberOfBanks, :clk, :unitOfTime, " - ":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, :controllerThread, " - ":maxBufferDepth, :per2BankOffset)"; + "INSERT INTO GeneralInfo VALUES" + "(:numberOfTransactions, :end, :numberOfRanks, :numberOfBankGroups, :numberOfBanks, :clk, :unitOfTime, " + ":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, :controllerThread, " + ":maxBufferDepth, :per2BankOffset, :rowColumnCommandBus)"; insertCommandLengthsString = "INSERT INTO CommandLengths VALUES" "(:command, :length)"; @@ -365,6 +365,16 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast(Configuration::getInstance().requestBufferSize)); sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast(Configuration::getInstance().memSpec->getPer2BankOffset())); + + const auto memoryType = Configuration::getInstance().memSpec->memoryType; + bool rowColumnCommandBus = [memoryType]() -> bool { + if (memoryType == MemSpec::MemoryType::HBM2) + return true; + else + return false; + }(); + + sqlite3_bind_int(insertGeneralInfoStatement, 17, static_cast(rowColumnCommandBus)); executeSqlStatement(insertGeneralInfoStatement); } diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index 0d2ce1ad..31688112 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -189,7 +189,8 @@ private: " RefreshMaxPulledin INTEGER, \n" " ControllerThread INTEGER, \n" " MaxBufferDepth INTEGER, \n" - " Per2BankOffset INTEGER \n" + " Per2BankOffset INTEGER, \n" + " RowColumnCommandBus BOOL \n" "); \n" " \n" "CREATE TABLE CommandLengths( \n" diff --git a/DRAMSys/traceAnalyzer/CMakeLists.txt b/DRAMSys/traceAnalyzer/CMakeLists.txt index 3ce4cceb..f19f7f06 100644 --- a/DRAMSys/traceAnalyzer/CMakeLists.txt +++ b/DRAMSys/traceAnalyzer/CMakeLists.txt @@ -102,12 +102,10 @@ add_executable(TraceAnalyzer businessObjects/phases/phasedependency.cpp businessObjects/phases/dependencyinfos.cpp presentation/tracedrawingproperties.cpp - presentation/util/traceplotline.cpp - presentation/util/traceplotlinecache.cpp presentation/util/customlabelscaledraw.cpp - presentation/traceselector.cpp businessObjects/configmodels.cpp businessObjects/commentmodel.cpp + businessObjects/traceplotlinemodel.cpp simulationdialog.cpp selectmetrics.ui diff --git a/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp b/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp index 149ccf8d..129c93db 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp @@ -278,7 +278,7 @@ QModelIndex MemSpecModel::parent(const QModelIndex &index) const const Node *childNode = static_cast(index.internalPointer()); const Node *parentNode = childNode->parent; - if (!parentNode) + if (!parentNode || parentNode == rootNode.get()) return QModelIndex(); return createIndex(parentNode->getRow(), 0, const_cast(parentNode)); diff --git a/DRAMSys/traceAnalyzer/businessObjects/configmodels.h b/DRAMSys/traceAnalyzer/businessObjects/configmodels.h index 7408db5c..9506e5bf 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/configmodels.h +++ b/DRAMSys/traceAnalyzer/businessObjects/configmodels.h @@ -50,7 +50,6 @@ class McConfigModel : public QAbstractTableModel public: explicit McConfigModel(const TraceDB &traceFile, QObject *parent = nullptr); - ~McConfigModel() {} protected: int rowCount(const QModelIndex &parent = QModelIndex()) const override; @@ -82,7 +81,6 @@ class MemSpecModel : public QAbstractItemModel public: explicit MemSpecModel(const TraceDB &traceFile, QObject *parent = nullptr); - ~MemSpecModel() {} protected: int rowCount(const QModelIndex &parent = QModelIndex()) const override; @@ -106,7 +104,11 @@ private: { using NodeData = std::pair; - Node() {} + /** + * Constructor only used for the root node that does not contain any data. + */ + Node() = default; + Node(NodeData data, const Node *parent) : data(data), parent(parent) {} /** diff --git a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h index 7eb8e8d2..f4f74ebf 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h +++ b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h @@ -62,20 +62,24 @@ struct GeneralInfo uint64_t controllerThread = UINT64_MAX; unsigned int maxBufferDepth = 8; unsigned int per2BankOffset = 1; + bool rowColumnCommandBus = false; GeneralInfo() = default; - GeneralInfo(uint64_t numberOfTransactions, uint64_t numberOfPhases, Timespan span, - unsigned int numberOfRanks, unsigned int numberOfBankgroups, unsigned int numberOfBanks, - QString description, QString unitOfTime, uint64_t clkPeriod, uint64_t windowSize, - unsigned int refreshMaxPostponed, unsigned int refreshMaxPulledin, - uint64_t controllerThread, unsigned int maxBufferDepth, unsigned int per2BankOffset) : - numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), span(span), - numberOfRanks(numberOfRanks), numberOfBankGroups(numberOfBankgroups), numberOfBanks(numberOfBanks), - banksPerRank(numberOfBanks / numberOfRanks), groupsPerRank(numberOfBankgroups / numberOfRanks), - banksPerGroup(numberOfBanks / numberOfBankgroups), description(std::move(description)), - unitOfTime(std::move(unitOfTime)), clkPeriod(clkPeriod), windowSize(windowSize), - refreshMaxPostponed(refreshMaxPostponed), refreshMaxPulledin(refreshMaxPulledin), - controllerThread(controllerThread), maxBufferDepth(maxBufferDepth), per2BankOffset(per2BankOffset) {} + GeneralInfo(uint64_t numberOfTransactions, uint64_t numberOfPhases, Timespan span, unsigned int numberOfRanks, + unsigned int numberOfBankgroups, unsigned int numberOfBanks, QString description, QString unitOfTime, + uint64_t clkPeriod, uint64_t windowSize, unsigned int refreshMaxPostponed, + unsigned int refreshMaxPulledin, uint64_t controllerThread, unsigned int maxBufferDepth, + unsigned int per2BankOffset, bool rowColumnCommandBus) + : numberOfTransactions(numberOfTransactions), numberOfPhases(numberOfPhases), span(span), + numberOfRanks(numberOfRanks), numberOfBankGroups(numberOfBankgroups), numberOfBanks(numberOfBanks), + banksPerRank(numberOfBanks / numberOfRanks), groupsPerRank(numberOfBankgroups / numberOfRanks), + banksPerGroup(numberOfBanks / numberOfBankgroups), description(std::move(description)), + unitOfTime(std::move(unitOfTime)), clkPeriod(clkPeriod), windowSize(windowSize), + refreshMaxPostponed(refreshMaxPostponed), refreshMaxPulledin(refreshMaxPulledin), + controllerThread(controllerThread), maxBufferDepth(maxBufferDepth), per2BankOffset(per2BankOffset), + rowColumnCommandBus(rowColumnCommandBus) + { + } }; #endif // GENERALINFO_H diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp index 463fde5c..2c5c35f8 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp @@ -38,9 +38,10 @@ */ #include "phase.h" -#include "presentation/util/traceplotline.h" -#include "presentation/tracedrawing.h" +#include "businessObjects/traceplotlinemodel.h" #include "businessObjects/transaction.h" +#include "presentation/tracedrawing.h" + #include void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, @@ -64,42 +65,53 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, painter->setPen(pen); } - for (auto line : getTracePlotLines(drawingProperties)) + for (auto yVal : getYVals(drawingProperties)) { - if (!line->isCollapsed()) + drawPhaseSymbol(span.Begin(), span.End(), yVal, drawingProperties.drawText, getPhaseSymbol(), painter, xMap, + yMap, drawingProperties.textColor); + + if (getGranularity() == Granularity::Bankwise) { - drawPhaseSymbol(span.Begin(), span.End(), line->getYVal(), - drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap, drawingProperties.textColor); - - if (getGranularity() == Granularity::Bankwise) + DependencyOptions drawDependenciesOptions = drawingProperties.drawDependenciesOption; + if (drawDependenciesOptions.draw == DependencyOption::All || + (drawDependenciesOptions.draw == DependencyOption::Selected && highlight)) { - - DependencyOptions drawDependenciesOptions = drawingProperties.drawDependenciesOption; - if (drawDependenciesOptions.draw == DependencyOption::All || - (drawDependenciesOptions.draw == DependencyOption::Selected && highlight)) - { - drawPhaseDependencies(span.Begin(), span.End(), line->getYVal(), drawingProperties, painter, xMap, - yMap); - } + drawPhaseDependencies(span.Begin(), span.End(), yVal, drawingProperties, painter, xMap, yMap); } } } for (Timespan span : spansOnCommandBus) { - for (auto commandBusLine : drawingProperties.getCommandBusLines()) + for (const auto &line : drawingProperties.getTracePlotLines()) { - drawPhaseSymbol(span.Begin(), span.End(), commandBusLine->getYVal(), - false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor); + if (line->data.type == AbstractTracePlotLineModel::RowCommandBusLine) + { + if (isColumnCommand()) + continue; + } + else if (line->data.type == AbstractTracePlotLineModel::ColumnCommandBusLine) + { + if (!isColumnCommand()) + continue; + } + else if (line->data.type != AbstractTracePlotLineModel::CommandBusLine) + continue; + + drawPhaseSymbol(span.Begin(), span.End(), line->data.yVal, false, PhaseSymbol::Hexagon, painter, xMap, + yMap, drawingProperties.textColor); } } if (spanOnDataBus) { - for (auto dataBusLine : drawingProperties.getDataBusLines()) + for (const auto &line : drawingProperties.getTracePlotLines()) { - drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), dataBusLine->getYVal(), - false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor); + if (line->data.type != AbstractTracePlotLineModel::DataBusLine) + continue; + + drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), line->data.yVal, false, PhaseSymbol::Hexagon, + painter, xMap, yMap, drawingProperties.textColor); } } } @@ -175,6 +187,80 @@ void Phase::drawPhaseDependencies(traceTime begin, traceTime end, double y, painter->restore(); } +std::vector Phase::getYVals(const TraceDrawingProperties &drawingProperties) const +{ + std::vector yVals; + + unsigned int transactionRank = transaction.lock()->rank; + unsigned int transactionBank = transaction.lock()->bank; + + for (const auto &line : drawingProperties.getTracePlotLines()) + { + if (line->data.type != AbstractTracePlotLineModel::BankLine) + continue; + + unsigned int yVal = line->data.yVal; + + unsigned int rank = line->data.rank; + unsigned int bank = line->data.bank; + + bool shouldBeDrawn = false; + + switch (getGranularity()) + { + case Granularity::Rankwise: + shouldBeDrawn = (transactionRank == rank); + break; + case Granularity::Groupwise: + shouldBeDrawn = (transactionRank == rank) && (transactionBank % drawingProperties.banksPerGroup == + bank % drawingProperties.banksPerGroup); + break; + case Granularity::Bankwise: + shouldBeDrawn = (transactionBank == bank); + break; + + case Granularity::TwoBankwise: + shouldBeDrawn = (transactionBank == bank) || ((transactionBank + drawingProperties.per2BankOffset) == bank); + break; + } + + if (shouldBeDrawn) + yVals.push_back(yVal); + } + + return yVals; +} + +std::vector REQ::getYVals(const TraceDrawingProperties &drawingProperties) const +{ + std::vector yVals; + + for (const auto &line : drawingProperties.getTracePlotLines()) + { + if (line->data.type != AbstractTracePlotLineModel::RequestLine) + continue; + + yVals.push_back(line->data.yVal); + } + + return yVals; +} + +std::vector RESP::getYVals(const TraceDrawingProperties &drawingProperties) const +{ + std::vector yVals; + + for (const auto &line : drawingProperties.getTracePlotLines()) + { + if (line->data.type != AbstractTracePlotLineModel::ResponseLine) + continue; + + yVals.push_back(line->data.yVal); + } + + return yVals; +} + QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const { switch (drawingProperties.colorGrouping) @@ -199,72 +285,57 @@ bool Phase::isSelected(Timespan timespan, double yVal, const TraceDrawingPropert { if (span.overlaps(timespan)) { - for (auto line : getTracePlotLines(drawingProperties)) - { - if (!line->isCollapsed() && fabs(yVal - line->getYVal()) <= hexagonHeight / 2) + for (auto lineYVal : getYVals(drawingProperties)) + if (fabs(yVal - lineYVal) <= hexagonHeight / 2) return true; - } } - if (spanOnDataBus && spanOnDataBus->overlaps(timespan)) - { - for (auto dataBusLine : drawingProperties.getDataBusLines()) - { - if (fabs(yVal - dataBusLine->getYVal()) <= hexagonHeight) - return true; - } - } - - for (const Timespan &span : spansOnCommandBus) + for (Timespan span : spansOnCommandBus) { if (span.overlaps(timespan)) { - for (auto commandBusLine : drawingProperties.getCommandBusLines()) + for (const auto &line : drawingProperties.getTracePlotLines()) { - if (fabs(yVal - commandBusLine->getYVal()) <= hexagonHeight) + if ((line->data.type != AbstractTracePlotLineModel::CommandBusLine) && + (line->data.type != AbstractTracePlotLineModel::RowCommandBusLine) && + (line->data.type != AbstractTracePlotLineModel::ColumnCommandBusLine)) + continue; + + if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2) return true; } } } + if (spanOnDataBus && spanOnDataBus->overlaps(timespan)) + { + for (const auto &line : drawingProperties.getTracePlotLines()) + { + if (line->data.type != AbstractTracePlotLineModel::DataBusLine) + continue; + + if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2) + return true; + } + } + return false; } +bool Phase::isColumnCommand() const +{ + if (dynamic_cast(this) || dynamic_cast(this) || dynamic_cast(this) || + dynamic_cast(this)) + return true; + else + return false; +} + Phase::PhaseSymbol Phase::getPhaseSymbol() const { return PhaseSymbol::Hexagon; } -std::vector> Phase::getTracePlotLines(const TraceDrawingProperties &drawingProperties) const -{ - if (getGranularity() == Granularity::Rankwise) - { - return drawingProperties.getBankLinesFromRank(transaction.lock()->rank); - } - else if (getGranularity() == Granularity::Groupwise) - { - return drawingProperties.getBankLinesGroupwise(transaction.lock()->rank, - transaction.lock()->bank % drawingProperties.banksPerGroup); - } - else if (getGranularity() == Granularity::TwoBankwise) - { - unsigned int firstGroup = transaction.lock()->bank / drawingProperties.banksPerGroup; - unsigned int firstBank = transaction.lock()->bank % drawingProperties.banksPerGroup; - unsigned int secondGroup = (transaction.lock()->bank + drawingProperties.per2BankOffset) - / drawingProperties.banksPerGroup; - unsigned int secondBank = (transaction.lock()->bank + drawingProperties.per2BankOffset) - % drawingProperties.banksPerGroup; - return drawingProperties.getBankLinesTwoBankwise(transaction.lock()->rank, firstGroup, firstBank, secondGroup, - secondBank); - } - else // if (getGranularity() == Granularity::Bankwise) - { - return drawingProperties.getBankLines(transaction.lock()->rank, - transaction.lock()->bankgroup % drawingProperties.groupsPerRank, - transaction.lock()->bank % drawingProperties.banksPerGroup); - } -} - void Phase::addDependency(std::shared_ptr dependency) { mDependencies.push_back(dependency); diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index cca1cf9a..9b9550d1 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -67,6 +67,7 @@ public: const QRectF &canvasRect, bool highlight, const TraceDrawingProperties &drawingProperties) const; bool isSelected(Timespan timespan, double yVal, const TraceDrawingProperties &drawingproperties) const; + bool isColumnCommand() const; const Timespan &Span() const { return span; @@ -97,6 +98,7 @@ protected: virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const; virtual QColor getPhaseColor() const = 0; + virtual std::vector getYVals(const TraceDrawingProperties &drawingProperties) const; virtual void drawPhaseSymbol(traceTime begin, traceTime end, double y, bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, QColor textColor) const; @@ -104,8 +106,6 @@ protected: const TraceDrawingProperties &drawingProperties, QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap) const; - virtual std::vector> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const; - enum class Granularity {Bankwise, TwoBankwise, Groupwise, Rankwise}; virtual Granularity getGranularity() const @@ -129,11 +129,8 @@ protected: { return "REQ"; } - std::vector> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const - override - { - return drawingProperties.getRequestLines(); - } + + std::vector getYVals(const TraceDrawingProperties &drawingProperties) const override; }; class RESP final : public Phase @@ -149,12 +146,8 @@ protected: { return "RESP"; } - std::vector> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const - override - { - return drawingProperties.getResponseLines(); - } + std::vector getYVals(const TraceDrawingProperties &drawingProperties) const override; }; /* class PREB final : public Phase diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.cpp index e76d0f8e..39f3b1d9 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.cpp @@ -69,13 +69,10 @@ bool PhaseDependency::draw(QPoint &end, const TraceDrawingProperties &drawingPro return false; bool drawn = false; - for (auto line : mDependency->getTracePlotLines(drawingProperties)) + for (auto yVal : mDependency->getYVals(drawingProperties)) { - if (!line->isCollapsed()) - { - mDraw(end, line->getYVal(), drawingProperties, painter, xMap, yMap); - drawn = true; - } + mDraw(end, yVal, drawingProperties, painter, xMap, yMap); + drawn = true; } return drawn; @@ -129,4 +126,4 @@ void PhaseDependency::mDraw(QPoint &end, double depY, const TraceDrawingProperti drawText(painter, mTimeDependency, textPosition, alignment); } -} \ No newline at end of file +} diff --git a/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp new file mode 100644 index 00000000..dde50281 --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Derek Christ + */ + +#include "traceplotlinemodel.h" +#include "../presentation/traceplot.h" +#include "../presentation/util/customlabelscaledraw.h" + +#include +#include +#include + +AbstractTracePlotLineModel::AbstractTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent) + : QAbstractItemModel(parent), internalSelectionModel(new QItemSelectionModel(this, this)), + rootNode(std::make_shared()), numberOfRanks(generalInfo.numberOfRanks), + groupsPerRank(generalInfo.groupsPerRank), banksPerGroup(generalInfo.banksPerGroup), + banksPerRank(generalInfo.banksPerRank), commandBusType(getCommandBusType(generalInfo)) +{ + createInitialNodes(); +} + +AvailableTracePlotLineModel::AvailableTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent) + : AbstractTracePlotLineModel(generalInfo, parent) +{ +} + +SelectedTracePlotLineModel::SelectedTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent) + : AbstractTracePlotLineModel(generalInfo, parent) +{ +} + +void AbstractTracePlotLineModel::addTopLevelNode(std::shared_ptr &&node) +{ + rootNode->children.push_back(std::move(node)); +} + +void AbstractTracePlotLineModel::createInitialNodes() +{ + addTopLevelNode( + std::unique_ptr(new Node({LineType::RequestLine, getLabel(LineType::RequestLine)}, rootNode.get()))); + addTopLevelNode( + std::unique_ptr(new Node({LineType::ResponseLine, getLabel(LineType::ResponseLine)}, rootNode.get()))); + + for (unsigned int rank = numberOfRanks; rank--;) + addTopLevelNode(createRankGroupNode(rank)); + + if (commandBusType == CommandBusType::SingleCommandBus) + { + addTopLevelNode(std::unique_ptr( + new Node({LineType::CommandBusLine, getLabel(LineType::CommandBusLine)}, rootNode.get()))); + } + else // commandBusType == CommandBusType::RowColumnCommandBus + { + addTopLevelNode(std::unique_ptr( + new Node({LineType::RowCommandBusLine, getLabel(LineType::RowCommandBusLine)}, rootNode.get()))); + addTopLevelNode(std::unique_ptr( + new Node({LineType::ColumnCommandBusLine, getLabel(LineType::ColumnCommandBusLine)}, rootNode.get()))); + } + + addTopLevelNode( + std::unique_ptr(new Node({LineType::DataBusLine, getLabel(LineType::DataBusLine)}, rootNode.get()))); +} + +std::shared_ptr +AbstractTracePlotLineModel::createRankGroupNode(unsigned int rank) const +{ + auto rankGroup = std::unique_ptr(new Node({LineType::RankGroup, getLabel(rank), rank}, rootNode.get())); + + for (unsigned int group = groupsPerRank; group--;) + { + for (unsigned int bank = banksPerGroup; bank--;) + { + unsigned int absoluteRank = rank; + unsigned int absoluteGroup = group + rank * groupsPerRank; + unsigned int absoluteBank = bank + rank * banksPerRank + group * banksPerGroup; + + auto bankLine = std::unique_ptr( + new Node({LineType::BankLine, getLabel(rank, group, bank), absoluteRank, absoluteGroup, absoluteBank}, + rankGroup.get())); + + rankGroup->children.push_back(std::move(bankLine)); + } + } + + return rankGroup; +} + +int AbstractTracePlotLineModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + + const Node *parentNode; + + if (!parent.isValid()) + parentNode = rootNode.get(); + else + parentNode = static_cast(parent.internalPointer()); + + return parentNode->childCount(); +} + +int AbstractTracePlotLineModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return 1; +} + +QVariant AbstractTracePlotLineModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + auto *node = static_cast(index.internalPointer()); + + switch (role) + { + case Qt::DisplayRole: + return node->data.label; + + case Role::TypeRole: + return QVariant::fromValue(node->data.type); + + case Role::CollapsedRole: + return node->data.collapsed; + } + + return QVariant(); +} + +bool SelectedTracePlotLineModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid()) + return false; + + auto *node = static_cast(index.internalPointer()); + + switch (role) + { + case Role::CollapsedRole: + node->data.collapsed = value.toBool(); + emit dataChanged(index, index, {role}); + return true; + + case Qt::DisplayRole: + case Role::TypeRole: + // Not allowed + return false; + } + + return false; +} + +QVariant AvailableTracePlotLineModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal && section == 0) + return "Available Items"; + + return QVariant(); +} + +QVariant SelectedTracePlotLineModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal && section == 0) + { + return "Selected Items"; + } + + return QVariant(); +} + +QModelIndex AbstractTracePlotLineModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + const Node *parentNode; + + if (!parent.isValid()) + parentNode = rootNode.get(); + else + parentNode = static_cast(parent.internalPointer()); + + const Node *node = parentNode->children[row].get(); + + return createIndex(row, column, const_cast(node)); +} + +QModelIndex AbstractTracePlotLineModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + const Node *childNode = static_cast(index.internalPointer()); + const Node *parentNode = childNode->parent; + + if (!parentNode || parentNode == rootNode.get()) + return QModelIndex(); + + return createIndex(parentNode->getRow(), 0, const_cast(parentNode)); +} + +void SelectedTracePlotLineModel::recreateCollapseButtons(TracePlot *tracePlot, + CustomLabelScaleDraw *customLabelScaleDraw) +{ + // Remove old buttons + for (auto button : collapseButtons) + { + button->hide(); + button->deleteLater(); + } + + collapseButtons.clear(); + + for (const auto &node : rootNode->children) + { + if (node->data.type != LineType::RankGroup) + continue; + + QPushButton *collapseButton = new QPushButton(tracePlot); + + unsigned int yVal = [node]() + { + if (node->data.collapsed) + return node->data.yVal; + else + return node->children.at(0)->data.yVal; + }(); + bool isCollapsed = node->data.collapsed; + QModelIndex nodeIndex = index(node->getRow(), 0); + + auto repositionButton = [=]() + { + QPointF point = tracePlot->axisScaleDraw(QwtPlot::yLeft)->labelPosition(yVal); + collapseButton->setGeometry(point.x(), point.y() - 4, 25, 25); + }; + repositionButton(); + + auto updateLabel = [=]() { collapseButton->setText(isCollapsed ? "+" : "-"); }; + updateLabel(); + + auto toggleCollapsed = [=]() + { + setData(nodeIndex, !isCollapsed, Role::CollapsedRole); + + recreateCollapseButtons(tracePlot, customLabelScaleDraw); + }; + + // Important: The context of the connection is `collapseButton` as it should be disconnected when the button + // ceases to exist. + connect(customLabelScaleDraw, &CustomLabelScaleDraw::scaleRedraw, collapseButton, repositionButton); + connect(collapseButton, &QPushButton::pressed, this, toggleCollapsed); + connect(collapseButton, &QPushButton::pressed, tracePlot, &TracePlot::recreateCollapseButtons); + + collapseButton->show(); + collapseButtons.push_back(collapseButton); + } +} + +int AbstractTracePlotLineModel::Node::getRow() const +{ + if (!parent) + return 0; + + const auto &siblings = parent->children; + const auto siblingsIt = std::find_if(siblings.begin(), siblings.end(), + [this](const std::shared_ptr &node) { return node.get() == this; }); + + Q_ASSERT(siblingsIt != siblings.end()); + + return std::distance(siblings.begin(), siblingsIt); +} + +std::shared_ptr AbstractTracePlotLineModel::Node::cloneNode(const Node *node, + const Node *parent) +{ + std::shared_ptr clonedNode = std::make_shared(node->data, parent); + + for (const auto &child : node->children) + clonedNode->children.push_back(cloneNode(child.get(), clonedNode.get())); + + return clonedNode; +} + +QString AbstractTracePlotLineModel::getLabel(LineType type) +{ + switch (type) + { + case LineType::RequestLine: + return "REQ"; + case LineType::ResponseLine: + return "RESP"; + case LineType::CommandBusLine: + return "Command Bus"; + case LineType::RowCommandBusLine: + return "Command Bus [R]"; + case LineType::ColumnCommandBusLine: + return "Command Bus [C]"; + case LineType::DataBusLine: + return "Data Bus"; + default: + return ""; + } +} + +QString AbstractTracePlotLineModel::getLabel(unsigned int rank) +{ + return "RA" + QString::number(rank); +} + +QString AbstractTracePlotLineModel::getLabel(unsigned int rank, unsigned int group, unsigned int bank) +{ + return "RA" + QString::number(rank) + " BG" + QString::number(group) + " BA" + QString::number(bank); +} + +AbstractTracePlotLineModel::CommandBusType AbstractTracePlotLineModel::getCommandBusType(const GeneralInfo &generalInfo) +{ + if (generalInfo.rowColumnCommandBus) + return CommandBusType::RowColumnCommandBus; + else + return CommandBusType::SingleCommandBus; +} + +bool SelectedTracePlotLineModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent != QModelIndex()) + return false; + + // Note: beginRemoveRows requires [first, last], but erase requires [first, last) + beginRemoveRows(QModelIndex(), row, row + count - 1); + rootNode->children.erase(rootNode->children.begin() + row, rootNode->children.begin() + row + count); + endRemoveRows(); + + return true; +} + +void AvailableTracePlotLineModel::itemsDoubleClicked(const QModelIndex &index) +{ + QModelIndexList indexList({index}); + + emit returnPressed(indexList); +} + +void SelectedTracePlotLineModel::itemsDoubleClicked(const QModelIndex &index) +{ + if (index.parent() != QModelIndex()) + return; + + removeRow(index.row(), QModelIndex()); +} + +bool AvailableTracePlotLineModel::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object) + + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + + if (keyEvent->key() == Qt::Key_Return) + { + const QModelIndexList indexes = internalSelectionModel->selectedRows(); + + emit returnPressed(indexes); + } + else + { + return false; + } + } + + return false; +} + +bool SelectedTracePlotLineModel::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object) + + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + + if (keyEvent->key() == Qt::Key_Delete) + { + // Note: This implementation requires the selection to be contiguous + + const QModelIndexList indexes = internalSelectionModel->selectedRows(); + + if (indexes.count() == 0) + return true; + + for (const auto &index : indexes) + { + // Only remove toplevel indexes + if (index.parent() != QModelIndex()) + return true; + } + + removeRows(indexes.at(0).row(), indexes.size(), QModelIndex()); + return true; + } + else + { + return false; + } + } + + return false; +} + +void SelectedTracePlotLineModel::addIndexesFromAvailableModel(const QModelIndexList &indexes) +{ + for (const auto &index : indexes) + { + auto node = static_cast(index.internalPointer()); + auto clonedNode = Node::cloneNode(node, rootNode.get()); + + beginInsertRows(QModelIndex(), rootNode->children.size(), rootNode->children.size()); + addTopLevelNode(std::move(clonedNode)); + endInsertRows(); + } +} + +QItemSelectionModel *AbstractTracePlotLineModel::selectionModel() const +{ + return internalSelectionModel; +} + +QStringList AbstractTracePlotLineModel::mimeTypes() const +{ + QStringList types = QAbstractItemModel::mimeTypes(); + types << TRACELINE_MIMETYPE; + + return types; +} + +QMimeData *AbstractTracePlotLineModel::mimeData(const QModelIndexList &indexes) const +{ + QByteArray traceLineData; + QDataStream dataStream(&traceLineData, QIODevice::WriteOnly); + + for (const auto &index : indexes) + { + const Node *node = static_cast(index.internalPointer()); + + dataStream << node->data.type << node->data.label << node->data.rank << node->data.group << node->data.bank + << node->data.collapsed; + } + + QMimeData *mimeData = new QMimeData; + mimeData->setData(TRACELINE_MIMETYPE, traceLineData); + + return mimeData; +} + +bool AbstractTracePlotLineModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, + const QModelIndex &parent) const +{ + Q_UNUSED(action); + Q_UNUSED(row); + Q_UNUSED(parent); + + if (!data->hasFormat(TRACELINE_MIMETYPE)) + return false; + + if (column > 0) + return false; + + return true; +} + +bool AbstractTracePlotLineModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, + const QModelIndex &parent) +{ + if (!canDropMimeData(data, action, row, column, parent)) + return false; + + if (action == Qt::IgnoreAction) + return true; + + bool dropHandled = false; + + int beginRow; + + if (row != -1) + beginRow = row; + else + beginRow = rowCount(QModelIndex()); + + if (action == Qt::CopyAction || action == Qt::MoveAction) + { + dropHandled = true; + + QByteArray traceLineData = data->data(TRACELINE_MIMETYPE); + QDataStream dataStream(&traceLineData, QIODevice::ReadOnly); + + std::vector> droppedNodes; + + while (!dataStream.atEnd()) + { + LineType type; + QString label; + unsigned int rank, group, bank; + bool isCollapsed; + + dataStream >> type >> label >> rank >> group >> bank >> isCollapsed; + + std::shared_ptr node; + + if (type == LineType::BankLine) + node = std::make_shared(Node::NodeData{type, label, rank, group, bank}, rootNode.get()); + else if (type == LineType::RankGroup) + node = createRankGroupNode(rank); + else + node = std::make_shared(Node::NodeData{type, label}, rootNode.get()); + + if (node->data.type == RankGroup) + node->data.collapsed = isCollapsed; + + droppedNodes.push_back(std::move(node)); + } + + // Note: beginRemoveRows requires [first, last] + beginInsertRows(QModelIndex(), beginRow, beginRow + droppedNodes.size() - 1); + rootNode->children.insert(rootNode->children.begin() + beginRow, std::make_move_iterator(droppedNodes.begin()), + std::make_move_iterator(droppedNodes.end())); + endInsertRows(); + } + else + { + dropHandled = QAbstractItemModel::dropMimeData(data, action, row, column, parent); + } + + return dropHandled; +} + +Qt::DropActions AbstractTracePlotLineModel::supportedDropActions() const +{ + return (Qt::MoveAction | Qt::CopyAction); +} + +Qt::ItemFlags AbstractTracePlotLineModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); + + if (index.isValid()) + return Qt::ItemIsDragEnabled | defaultFlags; + else + return Qt::ItemIsDropEnabled | defaultFlags; +} + +std::shared_ptr SelectedTracePlotLineModel::getClonedRootNode() +{ + return Node::cloneNode(rootNode.get(), nullptr); +} + +void SelectedTracePlotLineModel::setRootNode(std::shared_ptr node) +{ + removeRows(0, rootNode->childCount(), QModelIndex()); + + beginInsertRows(QModelIndex(), 0, node->childCount() - 1); + rootNode = std::move(node); + endInsertRows(); +} + +TracePlotLineDataSource::TracePlotLineDataSource(SelectedTracePlotLineModel *selectedModel, QObject *parent) + : selectedModel(selectedModel) +{ + Q_UNUSED(parent) + + updateModel(); +} + +void TracePlotLineDataSource::updateModel() +{ + entries.clear(); + + std::function & parent)> addNodes; + addNodes = [=, &addNodes](std::shared_ptr &parent) + { + for (auto &childNode : parent->children) + { + if (childNode->data.type == AbstractTracePlotLineModel::RankGroup && !childNode->data.collapsed) + { + addNodes(childNode); + continue; // Don't add the parent node itself when not collapsed. + } + entries.push_back(childNode); + } + }; + + addNodes(selectedModel->rootNode); + + emit modelChanged(); +} diff --git a/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h new file mode 100644 index 00000000..a696e1ee --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Derek Christ + */ + +#ifndef TRACEPLOTLINEMODEL_H +#define TRACEPLOTLINEMODEL_H + +#include "generalinfo.h" + +#include +#include +#include + +class TracePlot; +class CustomLabelScaleDraw; +class QItemSelectionModel; + +class AbstractTracePlotLineModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit AbstractTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + + QItemSelectionModel *selectionModel() const; + + enum Role + { + TypeRole = Qt::UserRole + 1, + CollapsedRole + }; + Q_ENUM(Role) + + enum LineType + { + RequestLine, + ResponseLine, + CommandBusLine, + RowCommandBusLine, + ColumnCommandBusLine, + DataBusLine, + RankGroup, + BankLine + }; + Q_ENUM(LineType) + + struct Node + { + struct NodeData + { + NodeData() = default; + + NodeData(LineType type, const QString &label) : type(type), label(label) + { + } + + NodeData(LineType type, const QString &label, unsigned int rank) : type(type), label(label), rank(rank) + { + } + + NodeData(LineType type, const QString &label, unsigned int rank, unsigned int group, unsigned int bank) + : type(type), label(label), rank(rank), group(group), bank(bank) + { + } + + LineType type; + QString label; + unsigned int yVal = 0; + + /** + * Used to store the collapsed state in the traceplot. + * The value has only an effect when the type is Type::RankGroup. + */ + bool collapsed = true; + + /** + * Only used when the type is Type::BankLine. + * (Absolute numbering) + */ + unsigned int rank = 0, group = 0, bank = 0; + }; + + /** + * Constructor only used for the root node that does not contain any data. + */ + Node() = default; + + Node(NodeData data, const Node *parent) : data(data), parent(parent) + { + } + + /** + * Gets the row relative to its parent. + */ + int getRow() const; + int childCount() const + { + return children.size(); + } + + static std::shared_ptr cloneNode(const Node *node, const Node *parent); + + NodeData data; + + const Node *parent = nullptr; + std::vector> children; + }; + +protected: + enum class CommandBusType + { + SingleCommandBus, + RowColumnCommandBus + }; + + QStringList mimeTypes() const override; + QMimeData *mimeData(const QModelIndexList &indexes) const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, + const QModelIndex &parent) override; + bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, + const QModelIndex &parent) const override; + Qt::DropActions supportedDropActions() const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void addTopLevelNode(std::shared_ptr &&node); + void createInitialNodes(); + std::shared_ptr createRankGroupNode(unsigned int rank) const; + + static QString getLabel(LineType type); + static QString getLabel(unsigned int rank); + static QString getLabel(unsigned int rank, unsigned int group, unsigned int bank); + + static CommandBusType getCommandBusType(const GeneralInfo &generalInfo); + + static constexpr auto TRACELINE_MIMETYPE = "application/x-tracelinedata"; + + QItemSelectionModel *const internalSelectionModel; + + std::shared_ptr rootNode; + + const unsigned int numberOfRanks; + const unsigned int groupsPerRank; + const unsigned int banksPerGroup; + const unsigned int banksPerRank; + + const CommandBusType commandBusType; +}; + +class AvailableTracePlotLineModel : public AbstractTracePlotLineModel +{ + Q_OBJECT + +public: + explicit AvailableTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr); + +public Q_SLOTS: + void itemsDoubleClicked(const QModelIndex &index); + +Q_SIGNALS: + void returnPressed(const QModelIndexList &indexes); + +protected: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + bool eventFilter(QObject *object, QEvent *event) override; +}; + +class SelectedTracePlotLineModel : public AbstractTracePlotLineModel +{ + Q_OBJECT + +public: + explicit SelectedTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr); + + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + + void recreateCollapseButtons(TracePlot *tracePlot, CustomLabelScaleDraw *customLabelScaleDraw); + + std::shared_ptr getClonedRootNode(); + void setRootNode(std::shared_ptr node); + +public Q_SLOTS: + void itemsDoubleClicked(const QModelIndex &index); + + void addIndexesFromAvailableModel(const QModelIndexList &indexes); + +protected: + bool eventFilter(QObject *object, QEvent *event) override; + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + +private: + std::vector collapseButtons; + + friend class TracePlotLineDataSource; +}; + +/* + * Simple list that is the true source for the traceplot. + */ +class TracePlotLineDataSource : public QObject +{ + Q_OBJECT + +public: + using TracePlotLine = AbstractTracePlotLineModel::Node; + + explicit TracePlotLineDataSource(SelectedTracePlotLineModel *selectedModel, QObject *parent = nullptr); + + SelectedTracePlotLineModel *getSelectedModel() const + { + return selectedModel; + }; + std::vector> &getTracePlotLines() + { + return entries; + } + +public Q_SLOTS: + void updateModel(); + +Q_SIGNALS: + void modelChanged(); + +private: + SelectedTracePlotLineModel *selectedModel; + + std::vector> entries; +}; + +#endif // TRACEPLOTLINEMODEL_H diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index 6d79a2c8..8d2f7b4d 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -316,6 +316,8 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() unsigned maxBufferDepth = parameter.isValid() ? parameter.toUInt() : 8; parameter = getParameterFromTable("Per2BankOffset", "GeneralInfo"); unsigned per2BankOffset = parameter.isValid() ? parameter.toUInt() : 1; + parameter = getParameterFromTable("RowColumnCommandBus", "GeneralInfo"); + bool rowColumnCommandBus = parameter.isValid() ? parameter.toBool() : false; uint64_t numberOfPhases = getNumberOfPhases(); @@ -327,9 +329,12 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() description += "Length of trace: " + prettyFormatTime(traceEnd) + "\n"; description += "Window size: " + QString::number(windowSize) + "\n"; - return {numberOfTransactions, numberOfPhases, Timespan(0, traceEnd), numberOfRanks, - numberOfBankGroups, numberOfBanks, description, unitOfTime, clkPeriod, windowSize, - refreshMaxPostponed, refreshMaxPulledin, controllerThread, maxBufferDepth, per2BankOffset}; + return {numberOfTransactions, numberOfPhases, Timespan(0, traceEnd), + numberOfRanks, numberOfBankGroups, numberOfBanks, + description, unitOfTime, clkPeriod, + windowSize, refreshMaxPostponed, refreshMaxPulledin, + controllerThread, maxBufferDepth, per2BankOffset, + rowColumnCommandBus}; } CommandLengths TraceDB::getCommandLengthsFromDB() diff --git a/DRAMSys/traceAnalyzer/markerplotitem.h b/DRAMSys/traceAnalyzer/markerplotitem.h index 6e04876d..8cce5c44 100644 --- a/DRAMSys/traceAnalyzer/markerplotitem.h +++ b/DRAMSys/traceAnalyzer/markerplotitem.h @@ -33,10 +33,14 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Derek Christ */ #ifndef MARKERPLOTITEM_H #define MARKERPLOTITEM_H + +#include "businessObjects/tracetime.h" + #include #include diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp index b1a5ccc4..f97900c8 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp @@ -35,11 +35,8 @@ */ #include "tracedrawingproperties.h" +#include "../businessObjects/traceplotlinemodel.h" #include "util/customlabelscaledraw.h" -#include "traceplot.h" -#include "util/traceplotline.h" -#include "util/traceplotlinecache.h" -#include "traceselector.h" TraceDrawingProperties::TraceDrawingProperties(bool drawText, bool drawBorder, DependencyOptions drawDependenciesOption, ColorGrouping colorGrouping) @@ -48,85 +45,11 @@ TraceDrawingProperties::TraceDrawingProperties(bool drawText, bool drawBorder, D { } -TraceDrawingProperties::~TraceDrawingProperties() +void TraceDrawingProperties::init(TracePlotLineDataSource *tracePlotLineDataSource) { - tracePlotLines->clear(); - tracePlotLineCache->clearCache(); -} - -void TraceDrawingProperties::init(std::shared_ptr tracePlotLines, - std::shared_ptr tracePlotLineCache) -{ - this->tracePlotLines = tracePlotLines; - this->tracePlotLineCache = tracePlotLineCache; -} - -void TraceDrawingProperties::init(std::shared_ptr tracePlotLines, - std::shared_ptr tracePlotLineCache, - TracePlot *tracePlot) -{ - this->tracePlotLines = tracePlotLines; - this->tracePlotLineCache = tracePlotLineCache; - this->tracePlot = tracePlot; -} - -void TraceDrawingProperties::updateTracePlotLines(QTreeWidget *treeWidget) -{ - tracePlotLines->clear(); - tracePlot->getCustomLabelScaleDraw()->clearCache(); - clearCache(); - - for (int i = 0; i < treeWidget->topLevelItemCount(); i++) - { - auto currentTreeItem = static_cast(treeWidget->topLevelItem(i)); - - if (currentTreeItem->type == TraceSelectorTreeItem::Type::RequestLineItem) - tracePlotLines->push_back(std::make_shared()); - else if (currentTreeItem->type == TraceSelectorTreeItem::Type::ResponseLineItem) - tracePlotLines->push_back(std::make_shared()); - else if (currentTreeItem->type == TraceSelectorTreeItem::Type::CommandBusLineItem) - tracePlotLines->push_back(std::make_shared()); - else if (currentTreeItem->type == TraceSelectorTreeItem::Type::DataBusLineItem) - tracePlotLines->push_back(std::make_shared()); - else if (currentTreeItem->type == TraceSelectorTreeItem::Type::BankLineItem) - tracePlotLines->push_back(std::make_shared(currentTreeItem->rank, currentTreeItem->bankgroup, currentTreeItem->bank)); - else if (currentTreeItem->type == TraceSelectorTreeItem::Type::RankGroupItem) - addRankGroup(currentTreeItem->rank); - } + this->tracePlotLineDataSource = tracePlotLineDataSource; updateLabels(); - tracePlot->updateScrollbar(); - - // This call is needed, otherwise the labels of the axis will not update properly. - tracePlot->update(); -} - -void TraceDrawingProperties::addRankGroup(unsigned int rank) -{ - if (rank >= numberOfRanks) - return; - - std::shared_ptr firstRankLine; - - for (unsigned int group = groupsPerRank; group--;) - { - for (unsigned int bank = banksPerGroup; bank--;) - { - std::shared_ptr line; - - if (bank == banksPerGroup - 1 && group == groupsPerRank - 1) - { - firstRankLine = createFirstRankLine(rank, group, bank); - line = firstRankLine; - } - else - { - line = std::make_shared(rank, group, bank, firstRankLine); - } - - tracePlotLines->push_back(line); - } - } } void TraceDrawingProperties::updateLabels() @@ -135,61 +58,22 @@ void TraceDrawingProperties::updateLabels() labels->clear(); // The lowest line starts at the y value of 0. - int i = 0; + int yVal = 0; - for (auto it = tracePlotLines->rbegin(); it != tracePlotLines->rend(); it++) + auto selectedModel = tracePlotLineDataSource->getSelectedModel(); + + for (auto it = tracePlotLineDataSource->getTracePlotLines().rbegin(); + it != tracePlotLineDataSource->getTracePlotLines().rend(); ++it) { - // Don't add collapsed ranks, but always add the first rank line. - auto bankLine = std::dynamic_pointer_cast(*it); - auto firstRankLine = std::dynamic_pointer_cast(*it); - if (!firstRankLine && bankLine && bankLine->isCollapsed()) - continue; + auto line = *it; - (*labels)[i] = (*it)->getLabel(); + labels->operator[](yVal) = line->data.label; + line->data.yVal = yVal; - (*it)->setYVal(i); - - i++; + yVal++; } - Q_EMIT tracePlot->tracePlotLinesChanged(); -} - -std::shared_ptr TraceDrawingProperties::createFirstRankLine(unsigned int rank, unsigned int group, - unsigned int bank) const -{ - auto firstRankLine = std::make_shared(rank, group, bank, tracePlot); - - QObject::connect(firstRankLine.get(), &TracePlotFirstRankLine::collapsedStateChanged, - this, &TraceDrawingProperties::updateLabels); - - QObject::connect(firstRankLine.get(), &TracePlotFirstRankLine::collapsedStateChanged, - tracePlot, &TracePlot::updateScrollbar); - - QObject::connect(firstRankLine.get(), &TracePlotFirstRankLine::collapsedStateChanged, - tracePlot, &TracePlot::updateToggleCollapsedAction); - - QObject::connect(tracePlot->getCustomLabelScaleDraw(), &CustomLabelScaleDraw::scaleRedraw, - firstRankLine.get(), &TracePlotFirstRankLine::updateButtonPosition); - - return firstRankLine; -} - -void TraceDrawingProperties::collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction) -{ - using CollapseAction = ToggleCollapsedAction::CollapseAction; - - for (auto &line : *tracePlotLines) - { - if (auto firstRankLine = std::dynamic_pointer_cast(line)) - { - if ((!firstRankLine->isCollapsed() && collapseAction == CollapseAction::CollapseAllRanks) - || (firstRankLine->isCollapsed() && collapseAction == CollapseAction::ExpandAllRanks)) - { - Q_EMIT firstRankLine->collapseRequested(); - } - } - } + emit labelsUpdated(); } std::shared_ptr> TraceDrawingProperties::getLabels() const @@ -199,104 +83,5 @@ std::shared_ptr> TraceDrawingProperties::getLabels() const unsigned int TraceDrawingProperties::getNumberOfDisplayedLines() const { - if (!tracePlotLines) - return 0; - - unsigned int max = 0; - - for (auto line : *tracePlotLines) - { - if (!line->isCollapsed() && max < line->getYVal()) - max = line->getYVal(); - } - - return max; -} - -unsigned int TraceDrawingProperties::getNumberOfCollapsedRanks() const -{ - if (!tracePlotLines) - return 0; - - unsigned int numberOfCollapsedRanks = 0; - - for (auto line : *tracePlotLines) - { - if (auto firstRankLine = std::dynamic_pointer_cast(line)) - { - if (firstRankLine->isCollapsed()) - numberOfCollapsedRanks++; - } - } - - return numberOfCollapsedRanks; -} - -void TraceDrawingProperties::clearCache() const -{ - tracePlotLineCache->clearCache(); -} - -TracePlotLineVector TraceDrawingProperties::getRequestLines() const -{ - return tracePlotLineCache->getRequestLines(); -} - -TracePlotLineVector TraceDrawingProperties::getResponseLines() const -{ - return tracePlotLineCache->getResponseLines(); -} - -TracePlotLineVector TraceDrawingProperties::getCommandBusLines() const -{ - return tracePlotLineCache->getCommandBusLines(); -} - -TracePlotLineVector TraceDrawingProperties::getDataBusLines() const -{ - return tracePlotLineCache->getDataBusLines(); -} - -TracePlotLineVector TraceDrawingProperties::getFirstRankLines(unsigned int rank) const -{ - return tracePlotLineCache->getFirstRankLines(rank); -} - -TracePlotLineVector TraceDrawingProperties::getBankLines(unsigned int rank, unsigned int group, unsigned int bank) const -{ - return tracePlotLineCache->getBankLines(rank, group, bank); -} - -TracePlotLineVector TraceDrawingProperties::getBankLinesFromGroup(unsigned int rank, unsigned int group) const -{ - return tracePlotLineCache->getBankLinesFromGroup(rank, group); -} - -TracePlotLineVector TraceDrawingProperties::getBankLinesGroupwise(unsigned int rank, - unsigned int bank) const -{ - auto rankLines = tracePlotLineCache->getBankLinesFromRank(rank); - TracePlotLineVector groupwiseLines; - - std::copy_if(rankLines.begin(), rankLines.end(), std::back_inserter(groupwiseLines), - [bank](std::shared_ptr line) - { return std::static_pointer_cast(line)->bank == bank; }); - - return groupwiseLines; -} - -TracePlotLineVector TraceDrawingProperties::getBankLinesFromRank(unsigned int rank) const -{ - return tracePlotLineCache->getBankLinesFromRank(rank); -} - -TracePlotLineVector TraceDrawingProperties::getBankLinesTwoBankwise(unsigned int rank, unsigned int firstGroup, - unsigned int firstBank, unsigned int secondGroup, - unsigned int secondBank) const -{ - TracePlotLineVector firstBankLines = tracePlotLineCache->getBankLines(rank, firstGroup, firstBank); - TracePlotLineVector secondBankLines = tracePlotLineCache->getBankLines(rank, secondGroup, secondBank); - firstBankLines.insert(firstBankLines.end(), secondBankLines.begin(), secondBankLines.end()); - - return firstBankLines; + return tracePlotLineDataSource->getTracePlotLines().size(); } diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h index 119d1a24..2862a1a8 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h @@ -40,17 +40,13 @@ #ifndef TRACECOLLECTIONDRAWINGPROPERTIES_H #define TRACECOLLECTIONDRAWINGPROPERTIES_H -#include -#include -#include -#include -#include -#include -#include +#include "businessObjects/traceplotlinemodel.h" #include "tracedrawing.h" -#include "util/traceplotline.h" -#include "util/togglecollapsedaction.h" -#include "traceselector.h" +#include +#include +#include +#include +#include enum class ColorGrouping { @@ -60,10 +56,7 @@ enum class ColorGrouping AlphaTransaction }; -class TracePlot; -class TracePlotLineCache; - -using TracePlotLineVector = std::vector>; +class TracePlotLineDataSource; enum class DependencyOption { @@ -71,6 +64,7 @@ enum class DependencyOption Selected, All }; + enum class DependencyTextOption { Enabled, @@ -106,48 +100,26 @@ public: DependencyOptions drawDependenciesOption = {DependencyOption::Disabled, DependencyTextOption::Enabled}, ColorGrouping colorGrouping = ColorGrouping::PhaseType); - ~TraceDrawingProperties(); - void init(std::shared_ptr tracePlotLines, - std::shared_ptr tracePlotLineCache); - - void init(std::shared_ptr tracePlotLines, - std::shared_ptr tracePlotLineCache, TracePlot *tracePlot); + void init(TracePlotLineDataSource *tracePlotLineDataSource); + void updateLabels(); unsigned int getNumberOfDisplayedLines() const; - unsigned int getNumberOfCollapsedRanks() const; - TracePlotLineVector getRequestLines() const; - TracePlotLineVector getResponseLines() const; - TracePlotLineVector getCommandBusLines() const; - TracePlotLineVector getDataBusLines() const; - TracePlotLineVector getFirstRankLines(unsigned int rank) const; - TracePlotLineVector getBankLines(unsigned int rank, unsigned int group, unsigned int bank) const; - TracePlotLineVector getBankLinesFromGroup(unsigned int rank, unsigned int group) const; - TracePlotLineVector getBankLinesGroupwise(unsigned int rank, unsigned int bank) const; - TracePlotLineVector getBankLinesTwoBankwise(unsigned int rank, unsigned int firstGroup, - unsigned int firstBank, unsigned int secondGroup, - unsigned int secondBank) const; - TracePlotLineVector getBankLinesFromRank(unsigned int rank) const; + const std::vector> &getTracePlotLines() const + { + return tracePlotLineDataSource->getTracePlotLines(); + } std::shared_ptr> getLabels() const; - void updateTracePlotLines(QTreeWidget *treeWidget); - void collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction); +Q_SIGNALS: + void labelsUpdated(); private: - void updateLabels(); - void clearCache() const; - void addRankGroup(unsigned int rank); - std::shared_ptr createFirstRankLine(unsigned int rank, unsigned int group, - unsigned int bank) const; - std::shared_ptr> labels = std::make_shared>(); - std::shared_ptr tracePlotLines; - std::shared_ptr tracePlotLineCache; - - TracePlot *tracePlot = nullptr; + TracePlotLineDataSource *tracePlotLineDataSource; }; #endif // TRACECOLLECTIONDRAWINGPROPERTIES_H diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp index ae236ad2..7e43ae5e 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp @@ -38,7 +38,6 @@ */ #include "tracenavigator.h" -#include "util/traceplotlinecache.h" #include "vector" #include "businessObjects/commentmodel.h" #include @@ -59,16 +58,8 @@ TraceNavigator::TraceNavigator(QString path, CommentModel *commentModel, QObject QObject::connect(commentModel, &CommentModel::rowsRemoved, this, &TraceNavigator::traceFileModified); Transaction::setNumTransactions(GeneralTraceInfo().numberOfTransactions); - - tracePlotLineCache = - std::make_shared(getTracePlotLines(), GeneralTraceInfo().numberOfRanks, - GeneralTraceInfo().groupsPerRank, GeneralTraceInfo().banksPerGroup); } -TraceNavigator::~TraceNavigator() -{ - tracePlotLines->clear(); -} /* Navigation * @@ -309,16 +300,6 @@ Timespan TraceNavigator::getSpanCoveredBySelectedTransaction() return Timespan(begin, end); } -std::shared_ptr TraceNavigator::getTracePlotLines() -{ - return tracePlotLines; -} - -std::shared_ptr TraceNavigator::getTracePlotLineCache() -{ - return tracePlotLineCache; -} - const CommentModel *TraceNavigator::getCommentModel() const { return commentModel; diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.h b/DRAMSys/traceAnalyzer/presentation/tracenavigator.h index f8a89bf1..6d32eea6 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.h +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.h @@ -45,7 +45,6 @@ #include "businessObjects/transaction.h" #include "memory" -class TracePlotLineCache; class CommentModel; /* Class to navigate through a tracefile @@ -59,7 +58,6 @@ class TraceNavigator : public QObject public: TraceNavigator(QString path, CommentModel *commentModel, QObject *parent = 0); - ~TraceNavigator(); traceTime CurrentTraceTime() const { @@ -113,9 +111,6 @@ public: void commitChangesToDB(); void refreshData(); - std::shared_ptr getTracePlotLines(); - std::shared_ptr getTracePlotLineCache(); - const CommentModel *getCommentModel() const; bool existChangesToCommit() const; @@ -139,9 +134,6 @@ private: void getCommentsFromDB(); bool changesToCommitExist; - - std::shared_ptr tracePlotLines = std::make_shared(); - std::shared_ptr tracePlotLineCache; }; #endif // TRACENAVIGATOR_H diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp index d81bc852..d066dc1f 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp @@ -37,33 +37,30 @@ * Iron Prando da Silva */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tracePlotMouseLabel.h" #include "traceplot.h" -#include "gototimedialog.h" -#include "tracedrawing.h" #include "businessObjects/commentmodel.h" -#include "util/engineeringScaleDraw.h" +#include "businessObjects/traceplotlinemodel.h" +#include "gototimedialog.h" +#include "tracePlotMouseLabel.h" +#include "tracedrawing.h" #include "util/clkgrid.h" #include "util/customlabelscaledraw.h" -#include "util/togglecollapsedaction.h" - -using namespace std; +#include "util/engineeringScaleDraw.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include TracePlot::TracePlot(QWidget *parent): QwtPlot(parent), isInitialized(false), @@ -73,6 +70,49 @@ TracePlot::TracePlot(QWidget *parent): setUpActions(); } +void TracePlot::init(TraceNavigator *navigator, QScrollBar *scrollBar, TracePlotLineDataSource *tracePlotLineDataSource, + CommentModel *commentModel) +{ + Q_ASSERT(isInitialized == false); + isInitialized = true; + + this->navigator = navigator; + this->scrollBar = scrollBar; + this->commentModel = commentModel; + this->tracePlotLineDataSource = tracePlotLineDataSource; + + installEventFilter(commentModel); + + QObject::connect(commentModel, &CommentModel::dataChanged, this, &TracePlot::commentsChanged); + + QObject::connect(commentModel, &CommentModel::rowsRemoved, this, &TracePlot::commentsChanged); + + QObject::connect(commentModel->selectionModel(), &QItemSelectionModel::selectionChanged, this, + &TracePlot::commentsChanged); + + auto selectedTracePlotLineModel = tracePlotLineDataSource->getSelectedModel(); + QObject::connect(selectedTracePlotLineModel, &QAbstractItemModel::rowsInserted, this, + &TracePlot::recreateCollapseButtons); + QObject::connect(selectedTracePlotLineModel, &QAbstractItemModel::rowsRemoved, this, + &TracePlot::recreateCollapseButtons); + + connectNavigatorQ_SIGNALS(); + setUpDrawingProperties(); + setUpAxis(); + setUpGrid(); + setUpTracePlotItem(); + setUpZoom(); + setUpQueryEditor(); + mouseLabel = new TracePlotMouseLabel(this, navigator->GeneralTraceInfo().clkPeriod, this->mouseDownData.zoomSpan); + getAndDrawComments(); + setZoomLevel(1000); + + updateScrollbar(); + recreateCollapseButtons(); + dependenciesSubMenu->setEnabled(navigator->TraceFile().checkDependencyTableExists()); + replot(); +} + void TracePlot::setUpActions() { insertComment = new QAction("Insert comment", this); @@ -250,46 +290,6 @@ void TracePlot::setUpContextMenu() contextMenu->addActions({showQueryEditor, insertComment, exportToPdf, toggleCollapsedState}); } -void TracePlot::init(TraceNavigator *navigator, QScrollBar *scrollBar, CommentModel *commentModel) -{ - Q_ASSERT(isInitialized == false); - isInitialized = true; - - this->scrollBar = scrollBar; - this->commentModel = commentModel; - - installEventFilter(commentModel); - - QObject::connect(commentModel, &CommentModel::dataChanged, - this, &TracePlot::commentsChanged); - - QObject::connect(commentModel, &CommentModel::rowsRemoved, - this, &TracePlot::commentsChanged); - - QObject::connect(commentModel->selectionModel(), &QItemSelectionModel::selectionChanged, - this, &TracePlot::commentsChanged); - - this->navigator = navigator; - connectNavigatorQ_SIGNALS(); - setUpDrawingProperties(); - setUpAxis(); - setUpGrid(); - setUpTracePlotItem(); - setUpZoom(); - setUpQueryEditor(); - mouseLabel = new TracePlotMouseLabel(this, - navigator->GeneralTraceInfo().clkPeriod, this->mouseDownData.zoomSpan); - getAndDrawComments(); - setZoomLevel(1000); - - updateScrollbar(); - - dependenciesSubMenu->setEnabled(navigator->TraceFile().checkDependencyTableExists()); - - replot(); -} - - void TracePlot::connectNavigatorQ_SIGNALS() { QObject::connect(navigator, SIGNAL(currentTraceTimeChanged()), this, @@ -300,7 +300,10 @@ void TracePlot::connectNavigatorQ_SIGNALS() void TracePlot::setUpDrawingProperties() { - drawingProperties.init(navigator->getTracePlotLines(), navigator->getTracePlotLineCache(), this); + connect(this, &TracePlot::tracePlotLinesChanged, &drawingProperties, &TraceDrawingProperties::updateLabels); + connect(&drawingProperties, &TraceDrawingProperties::labelsUpdated, this, &TracePlot::updateScrollbar); + + drawingProperties.init(tracePlotLineDataSource); drawingProperties.textColor = palette().text().color(); drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks; @@ -353,7 +356,7 @@ void TracePlot::updateScrollbar() // The maximum number of displayed lines determined by the pageStep of the scroll bar. const unsigned int maxDisplayedLines = scrollBar->pageStep(); - const int maximum = drawingProperties.getNumberOfDisplayedLines() - maxDisplayedLines; + const int maximum = drawingProperties.getNumberOfDisplayedLines() - maxDisplayedLines - 1; if (maximum >= 0) { @@ -368,7 +371,7 @@ void TracePlot::updateScrollbar() void TracePlot::verticalScrollbarChanged(int value) { - const int yMax = drawingProperties.getNumberOfDisplayedLines(); + const int yMax = drawingProperties.getNumberOfDisplayedLines() - 1; if (scrollBar->isHidden()) { @@ -393,21 +396,10 @@ void TracePlot::setUpAxis() setAxisScaleDraw(xBottom, new EngineeringScaleDraw); } -void TracePlot::updateTracePlotLines(QTreeWidget *treeWidget) -{ - drawingProperties.updateTracePlotLines(treeWidget); -} - void TracePlot::updateToggleCollapsedAction() { - unsigned int numberOfCollapsedRanks = drawingProperties.getNumberOfCollapsedRanks(); - - if (numberOfCollapsedRanks == drawingProperties.numberOfRanks) - toggleCollapsedState->updateCollapsedState(ToggleCollapsedAction::CollapsedState::Collapsed); - else if (numberOfCollapsedRanks == 0) - toggleCollapsedState->updateCollapsedState(ToggleCollapsedAction::CollapsedState::Expanded); - else - toggleCollapsedState->updateCollapsedState(ToggleCollapsedAction::CollapsedState::Mixed); + ToggleCollapsedAction::CollapsedState state = getCollapsedState(); + toggleCollapsedState->updateCollapsedState(state); } Timespan TracePlot::GetCurrentTimespan() @@ -421,6 +413,71 @@ Timespan TracePlot::GetCurrentTimespan() return span; } +ToggleCollapsedAction::CollapsedState TracePlot::getCollapsedState() const +{ + using CollapsedState = ToggleCollapsedAction::CollapsedState; + + CollapsedState state = CollapsedState::Collapsed; + + unsigned int notCollapsedCount = 0; + unsigned int rankCount = 0; + + auto selectedModel = tracePlotLineDataSource->getSelectedModel(); + + for (unsigned int i = 0; i < selectedModel->rowCount(); i++) + { + QModelIndex index = selectedModel->index(i, 0); + auto type = static_cast( + selectedModel->data(index, AbstractTracePlotLineModel::TypeRole).toInt()); + + if (type != AbstractTracePlotLineModel::RankGroup) + continue; + + bool isCollapsed = selectedModel->data(index, AbstractTracePlotLineModel::CollapsedRole).toBool(); + if (!isCollapsed) + { + notCollapsedCount++; + state = CollapsedState::Mixed; + } + + rankCount++; + } + + if (notCollapsedCount == rankCount) + state = CollapsedState::Expanded; + + return state; +} + +void TracePlot::collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction) +{ + using CollapseAction = ToggleCollapsedAction::CollapseAction; + auto selectedModel = tracePlotLineDataSource->getSelectedModel(); + + for (unsigned int i = 0; i < selectedModel->rowCount(); i++) + { + QModelIndex index = selectedModel->index(i, 0); + auto type = static_cast( + selectedModel->data(index, AbstractTracePlotLineModel::TypeRole).toInt()); + + if (type != AbstractTracePlotLineModel::RankGroup) + continue; + + switch (collapseAction) + { + case CollapseAction::CollapseAllRanks: + selectedModel->setData(index, true, AbstractTracePlotLineModel::CollapsedRole); + break; + + case CollapseAction::ExpandAllRanks: + selectedModel->setData(index, false, AbstractTracePlotLineModel::CollapsedRole); + break; + } + } + + recreateCollapseButtons(); +} + void TracePlot::getAndDrawComments() { QList selectedRows = commentModel->selectionModel()->selectedRows(); @@ -507,12 +564,19 @@ void TracePlot::setZoomLevel(traceTime newZoomLevel) drawingProperties.drawText = false; } - /* Q_SLOTS * * */ +void TracePlot::recreateCollapseButtons() +{ + drawingProperties.updateLabels(); + + auto selectedModel = tracePlotLineDataSource->getSelectedModel(); + selectedModel->recreateCollapseButtons(this, customLabelScaleDraw); +} + void TracePlot::currentTraceTimeChanged() { bool drawDependencies = getDrawingProperties().drawDependenciesOption.draw != DependencyOption::Disabled; @@ -676,7 +740,8 @@ void TracePlot::on_exportToPDF() void TracePlot::on_toggleCollapsedState() { - drawingProperties.collapseOrExpandAllRanks(toggleCollapsedState->getCollapseAction()); + collapseOrExpandAllRanks(toggleCollapsedState->getCollapseAction()); + updateToggleCollapsedAction(); } /* Keyboard and mouse events @@ -853,5 +918,8 @@ void TracePlot::openContextMenu(const QPoint &pos, const QPoint &mouseDown) if (commentModel->hoveredComment(timespan).isValid()) commentModel->openContextMenu(); else + { + updateToggleCollapsedAction(); contextMenu->exec(pos); + } } diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.h b/DRAMSys/traceAnalyzer/presentation/traceplot.h index c3ec388c..b5416aea 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.h +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.h @@ -39,6 +39,13 @@ #ifndef TRACEPLOT_H #define TRACEPLOT_H + +#include "markerplotitem.h" +#include "queryeditor.h" +#include "tracenavigator.h" +#include "traceplotitem.h" +#include "util/togglecollapsedaction.h" + #include #include #include @@ -49,31 +56,25 @@ #include #include #include -#include "traceplotitem.h" -#include "tracenavigator.h" -#include "queryeditor.h" +class TracePlotMouseLabel; +class CustomLabelScaleDraw; +class CommentModel; +class TracePlotLineDataSource; -#include "markerplotitem.h" /* A plot that plots all phases and transactions of a trace file * Y Axis : Bank0,...,Bank7,Trans,CC * X Axis : Time * */ - -class TracePlotMouseLabel; -class CustomLabelScaleDraw; -class ToggleCollapsedAction; -class CommentModel; - class TracePlot : public QwtPlot { - Q_OBJECT public: TracePlot(QWidget *parent = NULL); - void init(TraceNavigator *navigator, QScrollBar *scrollBar, CommentModel *commentModel); + void init(TraceNavigator *navigator, QScrollBar *scrollBar, TracePlotLineDataSource *tracePlotLineDataSource, + CommentModel *commentModel); Timespan GetCurrentTimespan(); traceTime ZoomLevel() const; @@ -88,7 +89,7 @@ public Q_SLOTS: void commentsChanged(); void verticalScrollbarChanged(int value); void updateScrollbar(); - void updateTracePlotLines(QTreeWidget *treeWidget); + void recreateCollapseButtons(); void updateToggleCollapsedAction(); Q_SIGNALS: @@ -128,8 +129,11 @@ private: QMenu *contextMenu; QScrollBar *scrollBar; CustomLabelScaleDraw *customLabelScaleDraw; + CommentModel *commentModel; + TracePlotLineDataSource *tracePlotLineDataSource; + void setUpTracePlotItem(); void setUpDrawingProperties(); void setUpGrid(); @@ -142,6 +146,8 @@ private: void connectNavigatorQ_SIGNALS(); void getAndDrawComments(); + ToggleCollapsedAction::CollapsedState getCollapsedState() const; + void collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction); /* zooming * diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp index 883c7c5c..7332c48f 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp @@ -36,12 +36,13 @@ * Derek Christ */ -#include -#include -#include #include "tracescroller.h" #include "traceplotitem.h" #include "util/engineeringScaleDraw.h" +#include +#include +#include +#include TraceScroller::TraceScroller(QWidget *parent) : QwtPlot(parent), isInitialized(false), @@ -55,11 +56,14 @@ TraceScroller::TraceScroller(QWidget *parent) canvasClip->attach(this); } -void TraceScroller::init(TraceNavigator *navigator, TracePlot *tracePlot) +void TraceScroller::init(TraceNavigator *navigator, TracePlot *tracePlot, + TracePlotLineDataSource *tracePlotLineDataSource) { Q_ASSERT(isInitialized == false); isInitialized = true; + this->tracePlotLineDataSource = tracePlotLineDataSource; + this -> navigator = navigator; connectNavigatorQ_SIGNALS(); @@ -74,6 +78,8 @@ void TraceScroller::init(TraceNavigator *navigator, TracePlot *tracePlot) QObject::connect(commentModel->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TraceScroller::commentsChanged); + QObject::connect(tracePlotLineDataSource, &TracePlotLineDataSource::modelChanged, this, &TraceScroller::updateAxis); + setUpDrawingProperties(); setUpAxis(); setUpTracePlotItem(); @@ -104,7 +110,7 @@ void TraceScroller::setUpTracePlotItem() void TraceScroller::setUpDrawingProperties() { - drawingProperties.init(navigator->getTracePlotLines(), navigator->getTracePlotLineCache()); + drawingProperties.init(tracePlotLineDataSource); drawingProperties.textColor = palette().text().color(); drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks; @@ -125,7 +131,7 @@ void TraceScroller::setUpAxis() void TraceScroller::updateAxis() { - setAxisScale(yLeft, -1, drawingProperties.getNumberOfDisplayedLines() + 1, 1.0); + setAxisScale(yLeft, -1, drawingProperties.getNumberOfDisplayedLines(), 1.0); replot(); } diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.h b/DRAMSys/traceAnalyzer/presentation/tracescroller.h index ad7b01eb..d94b407f 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.h +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.h @@ -46,6 +46,7 @@ #include "presentation/tracenavigator.h" #include "traceplot.h" +class TracePlotLineDataSource; class TraceScroller : public QwtPlot { @@ -55,6 +56,7 @@ private: bool isInitialized; TraceNavigator *navigator; TracePlot *tracePlot; + TracePlotLineDataSource *tracePlotLineDataSource; constexpr static int tracePlotEnlargementFactor = 4; void setUpTracePlotItem(); void setUpDrawingProperties(); @@ -69,7 +71,7 @@ private: public: TraceScroller(QWidget *parent = NULL); - void init(TraceNavigator *navigator, TracePlot *tracePlot); + void init(TraceNavigator *navigator, TracePlot *tracePlot, TracePlotLineDataSource *tracePlotLineDataSource); Timespan GetCurrentTimespan(); public Q_SLOTS: diff --git a/DRAMSys/traceAnalyzer/presentation/traceselector.cpp b/DRAMSys/traceAnalyzer/presentation/traceselector.cpp deleted file mode 100644 index 434f7ac2..00000000 --- a/DRAMSys/traceAnalyzer/presentation/traceselector.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Derek Christ - */ - -#include "traceselector.h" -#include "traceplot.h" - -#include -#include -#include -#include -#include -#include -#include - -QMimeData *TraceAvailableTree::mimeData(const QList items) const -{ - QByteArray traceLineData; - QDataStream dataStream(&traceLineData, QIODevice::WriteOnly); - - for (QTreeWidgetItem *item : items) - { - TraceSelectorTreeItem *treeSelectorItem = static_cast(item); - - dataStream << static_cast(treeSelectorItem->type) - << treeSelectorItem->rank - << treeSelectorItem->bankgroup - << treeSelectorItem->bank; - } - - QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-tracelinedata", traceLineData); - - return mimeData; -} - -QStringList TraceAvailableTree::mimeTypes() const -{ - QStringList types = QTreeWidget::mimeTypes(); - types << "application/x-tracelinedata"; - - return types; -} - -void TraceAvailableTree::keyPressEvent(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Return) - { - for (unsigned int i = 0; i < topLevelItemCount(); i++) - { - auto currentItem = static_cast(topLevelItem(i)); - - if (currentItem->isSelected()) - { - auto clonedItem = new TraceSelectorTreeItem(*currentItem); - - for (int i = 0; i < currentItem->childCount(); i++) - { - auto child = static_cast(currentItem->child(i)); - clonedItem->addChild(new TraceSelectorTreeItem(*child)); - } - - selectedTree->addTopLevelItem(clonedItem); - } - - // Also add child items that could be selected. - for (unsigned int i = 0; i < currentItem->childCount(); i++) - { - auto currentChildItem = static_cast(currentItem->child(i)); - - if (currentChildItem->isSelected()) - { - auto clonedItem = new TraceSelectorTreeItem(*currentChildItem); - selectedTree->addTopLevelItem(clonedItem); - } - } - } - - Q_EMIT selectedTree->itemsChanged(); - } - - QTreeWidget::keyPressEvent(event); -} - -TraceSelectedTree::TraceSelectedTree(QWidget *parent) : - QTreeWidget(parent) -{ -} - -void TraceSelectedTree::init(unsigned int groupsPerRank, unsigned int banksPerGroup) -{ - this->groupsPerRank = groupsPerRank; - this->banksPerGroup = banksPerGroup; -} - -std::vector TraceSelectedTree::clonedItems() const -{ - std::vector clonedTopLevelItems; - - for (unsigned int i = 0; i < topLevelItemCount(); i++) - { - clonedTopLevelItems.push_back(topLevelItem(i)->clone()); - } - - return clonedTopLevelItems; -} - -void TraceSelectedTree::setItems(const std::vector &items) -{ - for (unsigned int i = topLevelItemCount(); i--;) - takeTopLevelItem(i); - - for (auto item : items) - addTopLevelItem(item); - - emit itemsChanged(); -} - -QMimeData *TraceSelectedTree::mimeData(const QList items) const -{ - QByteArray traceLineData; - QDataStream dataStream(&traceLineData, QIODevice::WriteOnly); - - for (QTreeWidgetItem *item : items) - { - TraceSelectorTreeItem *treeSelectorItem = static_cast(item); - - dataStream << static_cast(treeSelectorItem->type) - << treeSelectorItem->rank - << treeSelectorItem->bankgroup - << treeSelectorItem->bank; - } - - QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-tracelinedata", traceLineData); - - return mimeData; -} - -QStringList TraceSelectedTree::mimeTypes() const -{ - QStringList types = QTreeWidget::mimeTypes(); - types << "application/x-tracelinedata"; - - return types; -} - -Qt::DropActions TraceSelectedTree::supportedDropActions() const -{ - return (Qt::MoveAction | Qt::CopyAction); -} - -bool TraceSelectedTree::dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) -{ - bool dropHandled = false; - - if (action == Qt::CopyAction && data->hasFormat("application/x-tracelinedata")) - { - dropHandled = true; - - QByteArray traceLineData = data->data("application/x-tracelinedata"); - QDataStream dataStream(&traceLineData, QIODevice::ReadOnly); - - QList droppedItems; - - while (!dataStream.atEnd()) - { - TraceSelectorTreeItem::Type currentType; - int currentTypeNum; - unsigned int currentRank, currentBankGroup, currentBank; - - dataStream >> currentTypeNum - >> currentRank - >> currentBankGroup - >> currentBank; - - currentType = static_cast(currentTypeNum); - - QTreeWidgetItem *droppedItem; - - switch (currentType) - { - case TraceSelectorTreeItem::Type::RequestLineItem: - case TraceSelectorTreeItem::Type::ResponseLineItem: - case TraceSelectorTreeItem::Type::CommandBusLineItem: - case TraceSelectorTreeItem::Type::DataBusLineItem: - droppedItem = new TraceSelectorTreeItem(currentType); - break; - - case TraceSelectorTreeItem::Type::BankLineItem: - droppedItem = new TraceSelectorTreeItem(currentType, currentRank, currentBankGroup, currentBank); - break; - - case TraceSelectorTreeItem::Type::RankGroupItem: - droppedItem = TraceSelectorTreeItem::createRankParentItem(currentRank, groupsPerRank, banksPerGroup); - break; - } - - droppedItems.append(droppedItem); - } - - insertTopLevelItems(index, droppedItems); - } - else - dropHandled = QTreeWidget::dropMimeData(parent, index, data, action); - - return dropHandled; -} - -void TraceSelectedTree::dropEvent(QDropEvent *event) -{ - if (event->source() == this) - event->setDropAction(Qt::MoveAction); - else - event->setDropAction(Qt::CopyAction); - - QTreeWidget::dropEvent(event); - - Q_EMIT itemsChanged(); -} - -void TraceSelectedTree::keyPressEvent(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Delete) - { - for (unsigned int i = topLevelItemCount(); i--;) - { - if (topLevelItem(i)->isSelected()) - takeTopLevelItem(i); - } - - Q_EMIT itemsChanged(); - } - - QTreeWidget::keyPressEvent(event); -} - -TraceSelector::TraceSelector(QWidget *parent) : - QWidget(parent), layout(new QVBoxLayout(this)), - selectedTree(new TraceSelectedTree(this)), - availableTree(new TraceAvailableTree(selectedTree, this)) -{ - QLabel *descriptionLabel = new QLabel(); - descriptionLabel->setText( - "To customize the displayed rows double click or " - "drag and drop items from the upper list to the lower list." - ); - descriptionLabel->setWordWrap(true); - descriptionLabel->setAlignment(Qt::AlignCenter); - - layout->addWidget(descriptionLabel); - layout->addWidget(availableTree); - layout->addWidget(selectedTree); - - availableTree->setHeaderLabel("Available Items"); - availableTree->setDragEnabled(true); - availableTree->setExpandsOnDoubleClick(false); - availableTree->setSelectionMode(QAbstractItemView::ExtendedSelection); - - selectedTree->setHeaderLabel("Selected Items"); - selectedTree->setDragEnabled(true); - selectedTree->setAcceptDrops(true); - selectedTree->setDropIndicatorShown(true); - selectedTree->setExpandsOnDoubleClick(false); - selectedTree->setSelectionMode(QAbstractItemView::ExtendedSelection); - - connect(selectedTree, &TraceSelectedTree::itemsChanged, this, [=](){ - Q_EMIT selectedTreeChanged(selectedTree); - }); - - connect(availableTree, &QTreeWidget::itemDoubleClicked, this, [=](QTreeWidgetItem *item, int column) { - Q_UNUSED(column) - - auto traceSelectorItem = static_cast(item); - auto clonedItem = new TraceSelectorTreeItem(*traceSelectorItem); - - for (int i = 0; i < traceSelectorItem->childCount(); i++) - { - auto child = static_cast(traceSelectorItem->child(i)); - clonedItem->addChild(new TraceSelectorTreeItem(*child)); - } - - selectedTree->addTopLevelItem(clonedItem); - - Q_EMIT selectedTreeChanged(selectedTree); - }); - - connect(selectedTree, &QTreeWidget::itemDoubleClicked, this, [=](QTreeWidgetItem *item, int column) { - Q_UNUSED(column) - - int index = selectedTree->indexOfTopLevelItem(item); - selectedTree->takeTopLevelItem(index); - - Q_EMIT selectedTreeChanged(selectedTree); - }); -} - -void TraceSelector::init(TracePlot *traceplot) -{ - this->traceplot = traceplot; - numberOfRanks = traceplot->getDrawingProperties().numberOfRanks; - groupsPerRank = traceplot->getDrawingProperties().groupsPerRank; - banksPerGroup = traceplot->getDrawingProperties().banksPerGroup; - selectedTree->init(groupsPerRank, banksPerGroup); - - setUpTreeWidget(availableTree); - - // By default, all available items will also be in the selectedTree. - setUpTreeWidget(selectedTree); - - Q_EMIT selectedTreeChanged(selectedTree); -} - -void TraceSelector::setUpTreeWidget(QTreeWidget *treeWidget) -{ - treeWidget->addTopLevelItem( - new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::RequestLineItem) - ); - - treeWidget->addTopLevelItem( - new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::ResponseLineItem) - ); - - for (unsigned int rank = numberOfRanks; rank--;) - { - TraceSelectorTreeItem *rankItem = - TraceSelectorTreeItem::createRankParentItem(rank, groupsPerRank, banksPerGroup); - - treeWidget->addTopLevelItem(rankItem); - } - - treeWidget->addTopLevelItem( - new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::CommandBusLineItem) - ); - - treeWidget->addTopLevelItem( - new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::DataBusLineItem) - ); -} - -std::vector TraceSelector::getTraceSelectorState() const -{ - return selectedTree->clonedItems(); -} - -void TraceSelector::restoreTraceSelectorState(const std::vector &items) -{ - selectedTree->setItems(items); -} - -TraceSelectorTreeItem *TraceSelectorTreeItem::createRankParentItem(unsigned int rank,unsigned int groupsPerRank, - unsigned int banksPerGroup) -{ - TraceSelectorTreeItem *rankItem = new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::RankGroupItem, rank); - - for (unsigned int group = groupsPerRank; group--;) - { - for (unsigned int bank = banksPerGroup; bank--;) - { - rankItem->addChild( - new TraceSelectorTreeItem(TraceSelectorTreeItem::Type::BankLineItem, rank, group, bank) - ); - } - } - - return rankItem; -} - -TraceSelectorTreeItem::TraceSelectorTreeItem(TraceSelectorTreeItem::Type type) : - QTreeWidgetItem({getLabel(type)}), type(type) -{ - setFlags(flags() & ~Qt::ItemIsDropEnabled); -} - -TraceSelectorTreeItem::TraceSelectorTreeItem(TraceSelectorTreeItem::Type type, - unsigned int rank) : - QTreeWidgetItem({getLabel(rank)}), type(type), rank(rank) -{ - setFlags(flags() & ~Qt::ItemIsDropEnabled); -} - -TraceSelectorTreeItem::TraceSelectorTreeItem(TraceSelectorTreeItem::Type type, - unsigned int rank, unsigned int bankgroup, unsigned int bank) : - QTreeWidgetItem({getLabel(rank, bankgroup, bank)}), type(type), rank(rank), bankgroup(bankgroup), bank(bank) -{ - setFlags(flags() & ~Qt::ItemIsDropEnabled); -} - -QString TraceSelectorTreeItem::getLabel(Type type) -{ - switch (type) { - case Type::RequestLineItem: - return "REQ"; - case Type::ResponseLineItem: - return "RESP"; - case Type::CommandBusLineItem: - return "Command Bus"; - case Type::DataBusLineItem: - return "Data Bus"; - default: - return ""; - } -} - -QString TraceSelectorTreeItem::getLabel(unsigned int rank) -{ - return "RA" + QString::number(rank); -} - -QString TraceSelectorTreeItem::getLabel(unsigned int rank, unsigned int bankgroup, unsigned int bank) -{ - return "RA" + QString::number(rank) + " BG" + QString::number(bankgroup) + " BA" + QString::number(bank); -} - -QTreeWidgetItem *TraceSelectorTreeItem::clone() const -{ - TraceSelectorTreeItem *cloned = new TraceSelectorTreeItem(*this); - - std::vector clonedChildren; - for (unsigned int i = 0; i < childCount(); i++) - { - clonedChildren.push_back(static_cast(child(i)->clone())); - } - - for (auto child : clonedChildren) - cloned->addChild(child); - - return cloned; -} diff --git a/DRAMSys/traceAnalyzer/presentation/traceselector.h b/DRAMSys/traceAnalyzer/presentation/traceselector.h deleted file mode 100644 index 6a2a9fd3..00000000 --- a/DRAMSys/traceAnalyzer/presentation/traceselector.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Derek Christ - */ - -#ifndef TRACESELECTOR_H -#define TRACESELECTOR_H - -#include -#include -#include -#include - -class TracePlot; -class TracePlotLine; -class TraceSelectedTree; -class QVBoxLayout; - -class TraceAvailableTree : public QTreeWidget -{ - Q_OBJECT -public: - explicit TraceAvailableTree(TraceSelectedTree* selectedTree, QWidget *parent = nullptr) : - QTreeWidget(parent), selectedTree(selectedTree) {} - -protected: - void keyPressEvent(QKeyEvent *event) override; - - QMimeData *mimeData(const QList items) const override; - QStringList mimeTypes() const override; - -private: - TraceSelectedTree *selectedTree; -}; - -class TraceSelectedTree : public QTreeWidget -{ - Q_OBJECT -public: - explicit TraceSelectedTree(QWidget *parent = nullptr); - void init(unsigned int groupsPerRank, unsigned int banksPerGroup); - - std::vector clonedItems() const; - void setItems(const std::vector &items); - -Q_SIGNALS: - void itemsChanged(); - -protected: - void keyPressEvent(QKeyEvent *event) override; - - void dropEvent(QDropEvent *event) override; - bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) override; - Qt::DropActions supportedDropActions() const override; - QMimeData *mimeData(const QList items) const override; - QStringList mimeTypes() const override; - -private: - unsigned int groupsPerRank; - unsigned int banksPerGroup; -}; - -class TraceSelectorTreeItem : public QTreeWidgetItem -{ -public: - enum class Type { - RequestLineItem, ResponseLineItem, - CommandBusLineItem, DataBusLineItem, - RankGroupItem, BankLineItem - } const type; - - TraceSelectorTreeItem(Type type); - TraceSelectorTreeItem(Type type, unsigned int rank); - TraceSelectorTreeItem(Type type, unsigned int rank, unsigned int bankgroup, unsigned int bank); - - static TraceSelectorTreeItem *createRankParentItem(unsigned int rank, unsigned int groupsPerRank, - unsigned int banksPerGroup); - - static QString getLabel(Type type); - static QString getLabel(unsigned int rank); - static QString getLabel(unsigned int rank, unsigned int bankgroup, unsigned int bank); - - const unsigned int rank = 0, bankgroup = 0, bank = 0; - -protected: - QTreeWidgetItem *clone() const override; -}; - -class TraceSelector : public QWidget -{ - Q_OBJECT - -public: - explicit TraceSelector(QWidget *parent = nullptr); - void init(TracePlot *traceplot); - - std::vector getTraceSelectorState() const; - void restoreTraceSelectorState(const std::vector &items); - -signals: - void selectedTreeChanged(QTreeWidget *treeWidget); - -private: - void setUpTreeWidget(QTreeWidget *treeWidget); - - unsigned int numberOfRanks; - unsigned int groupsPerRank; - unsigned int banksPerGroup; - - TracePlot *traceplot; - QVBoxLayout *layout; - TraceSelectedTree *selectedTree; - TraceAvailableTree *availableTree; -}; - -#endif //TRACESELECTOR_H diff --git a/DRAMSys/traceAnalyzer/presentation/util/traceplotline.cpp b/DRAMSys/traceAnalyzer/presentation/util/traceplotline.cpp deleted file mode 100644 index f4e9b9ae..00000000 --- a/DRAMSys/traceAnalyzer/presentation/util/traceplotline.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: - * Derek Christ - */ - -#include "traceplotline.h" -#include "../traceplot.h" - -#include -#include - -TracePlotLine::TracePlotLine(QString label) : - label(label) -{ -} - -TracePlotLine::TracePlotLine() -{ -} - -TracePlotLine::~TracePlotLine() {} - -QString TracePlotLine::getLabel() const -{ - return label; -} - -bool TracePlotLine::isCollapsed() const -{ - return false; -} - -void TracePlotLine::setYVal (int yVal) -{ - this->yVal = yVal; -} - -int TracePlotLine::getYVal() const -{ - return yVal; -} - - -TracePlotBankLine::TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank, - std::shared_ptr firstRankLine) : - TracePlotBankLine(rank, group, bank) -{ - this->firstRankLine = firstRankLine; -} - -TracePlotBankLine::TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank) : - rank(rank), group(group), bank(bank) -{ - QString rankLabel = QString("RA") + QString::number(rank); - QString bankGroupLabel = QString("BG") + QString::number(group); - QString bankLabel = QString("BA") + QString::number(bank); - - label = rankLabel + QString(" ") + bankGroupLabel + QString(" ") + bankLabel; -} - -bool TracePlotBankLine::isCollapsed() const -{ - if (!firstRankLine.lock()) - return false; - - return firstRankLine.lock()->isCollapsed(); -} - - -TracePlotFirstRankLine::TracePlotFirstRankLine(unsigned int rank, unsigned int group, unsigned int bank, - TracePlot *tracePlot) : - TracePlotBankLine(rank, group, bank), - collapseButton(new QPushButton(tracePlot)), tracePlot(tracePlot) -{ - collapsedLabel = QString("RA") + QString::number(rank); - - collapseButton->setText(collapsed ? "+" : "-"); - collapseButton->show(); - - QObject::connect(collapseButton, &QPushButton::pressed, this, [=](){ - collapsed = !collapsed; - collapseButton->setText(collapsed ? "+" : "-"); - Q_EMIT collapsedStateChanged(); - }); - - QObject::connect(this, &TracePlotFirstRankLine::collapseRequested, - collapseButton, &QPushButton::pressed); -} - -TracePlotFirstRankLine::~TracePlotFirstRankLine() -{ - // Delete the collapseButton because its parent will still exist. - collapseButton->deleteLater(); -} - -void TracePlotFirstRankLine::updateButtonPosition() -{ - QPointF point = tracePlot->axisScaleDraw(QwtPlot::yLeft)->labelPosition(getYVal()); - collapseButton->setGeometry(point.x(), point.y() - 4, 25, 25); -} - -bool TracePlotFirstRankLine::isCollapsed() const -{ - return collapsed; -} - -QString TracePlotFirstRankLine::getLabel() const -{ - if (collapsed) - return collapsedLabel; - else - return TracePlotLine::getLabel(); -} - -QString TracePlotFirstRankLine::getFullLabel() const -{ - return TracePlotLine::getLabel(); -} diff --git a/DRAMSys/traceAnalyzer/presentation/util/traceplotline.h b/DRAMSys/traceAnalyzer/presentation/util/traceplotline.h deleted file mode 100644 index a5f50318..00000000 --- a/DRAMSys/traceAnalyzer/presentation/util/traceplotline.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: - * Derek Christ - */ - -#ifndef TRACELOTLINE_H -#define TRACELOTLINE_H - -#include -#include -#include -#include - -class QPushButton; -class TracePlot; -class TracePlotFirstRankLine; - -class TracePlotLine : public QObject -{ - Q_OBJECT - -public: - TracePlotLine(QString label); - virtual ~TracePlotLine() = 0; - - virtual QString getLabel() const; - virtual bool isCollapsed() const; - - void setYVal(int yVal); - int getYVal() const; - -protected: - TracePlotLine(); - - QString label; - int yVal; -}; - -class TracePlotBankLine : public TracePlotLine -{ - Q_OBJECT - -public: - TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank, - std::shared_ptr firstRankLine); - - TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank); - ~TracePlotBankLine() = default; - - virtual bool isCollapsed() const override; - std::shared_ptr getFirstRankLine() const { - return firstRankLine.lock(); - } - - const unsigned int rank; - const unsigned int group; - const unsigned int bank; - -private: - std::weak_ptr firstRankLine; -}; - - -class TracePlotFirstRankLine final : public TracePlotBankLine -{ - Q_OBJECT - -public: - TracePlotFirstRankLine(unsigned int rank, unsigned int group, unsigned int bank, - TracePlot *tracePlot); - - ~TracePlotFirstRankLine(); - - bool isCollapsed() const override; - QString getLabel() const override; - QString getFullLabel() const; - -public Q_SLOTS: - void updateButtonPosition(); - -Q_SIGNALS: - void collapsedStateChanged(); - void collapseRequested(); - -private: - QString collapsedLabel; - QPushButton *collapseButton; - bool collapsed = true; - TracePlot *tracePlot; -}; - - -class TracePlotRequestLine final : public TracePlotLine -{ - Q_OBJECT - -public: - TracePlotRequestLine() : TracePlotLine("REQ") {} - ~TracePlotRequestLine() = default; -}; - -class TracePlotResponseLine final : public TracePlotLine -{ - Q_OBJECT - -public: - TracePlotResponseLine() : TracePlotLine("RESP") {} - ~TracePlotResponseLine() = default; -}; - -class TracePlotDataBusLine final : public TracePlotLine -{ - Q_OBJECT - -public: - TracePlotDataBusLine() : TracePlotLine("Data Bus") {} - ~TracePlotDataBusLine() = default; -}; - -class TracePlotCommandBusLine final : public TracePlotLine -{ - Q_OBJECT - -public: - TracePlotCommandBusLine() : TracePlotLine("Command Bus") {} - ~TracePlotCommandBusLine() = default; -}; - -#endif // TRACELOTLINE_H diff --git a/DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.cpp b/DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.cpp deleted file mode 100644 index 09c1d790..00000000 --- a/DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: - * Derek Christ - */ - -#include "traceplotlinecache.h" -#include "../tracedrawingproperties.h" -#include "traceplotline.h" - -TracePlotLineCache::TracePlotLineCache(std::shared_ptr tracePlotLines, unsigned int numberOfRanks, - unsigned int groupsPerRank, unsigned int banksPerGroup) : - tracePlotLines(tracePlotLines), numberOfRanks(numberOfRanks), - groupsPerRank(groupsPerRank), banksPerGroup(banksPerGroup) -{ -} - -void TracePlotLineCache::clearCache() const -{ - bankLinesCache.clear(); - bankLinesFromGroupCache.clear(); - bankLinesFromRankCache.clear(); - firstRankLinesCache.clear(); - requestLinesCache.clear(); - responseLinesCache.clear(); - commandBusLinesCache.clear(); - dataBusLinesCache.clear(); -} - -TracePlotLineVector TracePlotLineCache::getCommandBusLines() const -{ - if (commandBusLinesCache.size() != 0) - return commandBusLinesCache; - - std::vector> commandBusLines; - for (auto line : *tracePlotLines) - { - auto commandBusLine = std::dynamic_pointer_cast(line); - if (commandBusLine) - commandBusLines.push_back(commandBusLine); - } - - commandBusLinesCache = commandBusLines; - - return commandBusLines; -} - -TracePlotLineVector TracePlotLineCache::getDataBusLines() const -{ - if (dataBusLinesCache.size() != 0) - return dataBusLinesCache; - - std::vector> dataBusLines; - for (auto line : *tracePlotLines) - { - auto dataBusLine = std::dynamic_pointer_cast(line); - if (dataBusLine) - dataBusLines.push_back(dataBusLine); - } - - dataBusLinesCache = dataBusLines; - - return dataBusLines; -} - -TracePlotLineVector TracePlotLineCache::getRequestLines() const -{ - if (requestLinesCache.size() != 0) - return requestLinesCache; - - std::vector> requestLines; - for (auto line : *tracePlotLines) - { - auto requestLine = std::dynamic_pointer_cast(line); - if (requestLine) - requestLines.push_back(requestLine); - } - - requestLinesCache = requestLines; - - return requestLines; -} - -TracePlotLineVector TracePlotLineCache::getResponseLines() const -{ - if (responseLinesCache.size() != 0) - return responseLinesCache; - - std::vector> responseLines; - for (auto line : *tracePlotLines) - { - auto responseLine = std::dynamic_pointer_cast(line); - if (responseLine) - responseLines.push_back(responseLine); - } - - responseLinesCache = responseLines; - - return responseLines; -} - -TracePlotLineVector TracePlotLineCache::getFirstRankLines(unsigned int rank) const -{ - Q_ASSERT(rank <= numberOfRanks - 1); - - if (firstRankLinesCache.find(rank) != firstRankLinesCache.end()) - return firstRankLinesCache[rank]; - - std::vector> firstRankLines; - - for (auto line : *tracePlotLines) - { - auto firstRankLine = std::dynamic_pointer_cast(line); - if (firstRankLine && firstRankLine->rank == rank) - firstRankLines.push_back(firstRankLine); - } - - firstRankLinesCache[rank] = firstRankLines; - - return firstRankLines; -} - -TracePlotLineVector TracePlotLineCache::getBankLinesFromRank(unsigned int rank) const -{ - Q_ASSERT(rank <= numberOfRanks - 1); - - if (bankLinesFromRankCache.find(rank) != bankLinesFromRankCache.end()) - return bankLinesFromRankCache[rank]; - - std::vector> bankLines; - for (auto line : *tracePlotLines) - { - auto bankLine = std::dynamic_pointer_cast(line); - - if (bankLine && bankLine->rank == rank) - bankLines.push_back(bankLine); - } - - bankLinesFromRankCache[rank] = bankLines; - - return bankLines; -} - -TracePlotLineVector TracePlotLineCache::getBankLinesFromGroup(unsigned int rank, unsigned int group) const -{ - Q_ASSERT(rank <= numberOfRanks - 1); - Q_ASSERT(group <= groupsPerRank - 1); - - std::tuple bankLinesTuple {rank, group}; - - if (bankLinesFromGroupCache.find(bankLinesTuple) != bankLinesFromGroupCache.end()) - return bankLinesFromGroupCache[bankLinesTuple]; - - std::vector> bankLines; - - for (auto line : *tracePlotLines) - { - auto bankLine = std::dynamic_pointer_cast(line); - - if (bankLine && bankLine->rank == rank && bankLine->group == group) - bankLines.push_back(bankLine); - } - - bankLinesFromGroupCache[bankLinesTuple] = bankLines; - - return bankLines; -} - -TracePlotLineVector TracePlotLineCache::getBankLines(unsigned int rank, unsigned int group, - unsigned int bank) const -{ - Q_ASSERT(rank <= numberOfRanks - 1); - Q_ASSERT(group <= groupsPerRank - 1); - Q_ASSERT(bank <= banksPerGroup - 1); - - std::tuple bankLinesTuple {rank, group, bank}; - - if (bankLinesCache.find(bankLinesTuple) != bankLinesCache.end()) - return bankLinesCache[bankLinesTuple]; - - std::vector> bankLines; - - for (auto line : *tracePlotLines) - { - auto bankLine = std::dynamic_pointer_cast(line); - - if (bankLine && bankLine->rank == rank && bankLine->group == group && bankLine->bank == bank) - bankLines.push_back(bankLine); - } - - bankLinesCache[bankLinesTuple] = bankLines; - - return bankLines; -} diff --git a/DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.h b/DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.h deleted file mode 100644 index e7b8d833..00000000 --- a/DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: - * Derek Christ - */ - -#ifndef TRACELOTLINECACHE_H -#define TRACELOTLINECACHE_H - -#include -#include -#include - -class TracePlotLine; - -using TracePlotLineVector = std::vector>; - -struct TracePlotLineCache -{ - TracePlotLineCache(std::shared_ptr tracePlotLines, unsigned int numberOfRanks, - unsigned int groupsPerRank, unsigned int banksPerGroup); - - TracePlotLineVector getRequestLines() const; - TracePlotLineVector getResponseLines() const; - TracePlotLineVector getCommandBusLines() const; - TracePlotLineVector getDataBusLines() const; - TracePlotLineVector getFirstRankLines(unsigned int rank) const; - TracePlotLineVector getBankLines(unsigned int rank, unsigned int group, unsigned int bank) const; - TracePlotLineVector getBankLinesFromGroup(unsigned int rank, unsigned int group) const; - TracePlotLineVector getBankLinesFromRank(unsigned int rank) const; - - void clearCache() const; - -private: - std::shared_ptr tracePlotLines; - - unsigned int numberOfRanks; - unsigned int groupsPerRank; - unsigned int banksPerGroup; - - mutable std::map, std::vector>> bankLinesCache; - mutable std::map, std::vector>> bankLinesFromGroupCache; - mutable std::map>> bankLinesFromRankCache; - mutable std::map>> firstRankLinesCache; - mutable std::vector> requestLinesCache; - mutable std::vector> responseLinesCache; - mutable std::vector> commandBusLinesCache; - mutable std::vector> dataBusLinesCache; -}; - -#endif // TRACELOTLINECACHE_H diff --git a/DRAMSys/traceAnalyzer/scripts/metrics.py b/DRAMSys/traceAnalyzer/scripts/metrics.py index 4d05186e..028c4b73 100644 --- a/DRAMSys/traceAnalyzer/scripts/metrics.py +++ b/DRAMSys/traceAnalyzer/scripts/metrics.py @@ -39,24 +39,51 @@ def trace_length_in_ns(connection): @metric def command_bus_utilisation_in_percent(connection): cursor = connection.cursor() - cursor.execute(""" - SELECT - SUM(CommandLengths.Length) - FROM - Phases - INNER JOIN - CommandLengths + cursor.execute("""SELECT RowColumnCommandBus FROM GeneralInfo""") + rowColumnCommandBus = cursor.fetchone()[0] + if rowColumnCommandBus: + cursor.execute(""" + SELECT SUM(CommandLengths.Length) + FROM Phases + INNER JOIN CommandLengths ON Phases.PhaseName = CommandLengths.Command - """) - result = cursor.fetchone()[0] + WHERE PhaseName <> 'RD' AND PhaseName <> 'RDA' AND PhaseName <> 'WR' AND PhaseName <> 'WRA' + """) + rowBusUtil = cursor.fetchone()[0] + if rowBusUtil is None: + rowBusUtil = 0 + + cursor.execute(""" + SELECT SUM(CommandLengths.Length) + FROM Phases + INNER JOIN CommandLengths + ON Phases.PhaseName = CommandLengths.Command + WHERE PhaseName = 'RD' OR PhaseName = 'RDA' OR PhaseName = 'WR' OR PhaseName = 'WRA' + """) + columnBusUtil = cursor.fetchone()[0] + if columnBusUtil is None: + columnBusUtil = 0 + + clk, _ = getClock(connection) + traceEnd = getTraceEndTime(connection) + rowBusOccupied = rowBusUtil * clk / traceEnd * 100 + columnBusOccupied = columnBusUtil * clk / traceEnd * 100 + return "row commands: {}, column commands: {}".format(rowBusOccupied, columnBusOccupied) + else: + cursor.execute(""" + SELECT SUM(CommandLengths.Length) + FROM Phases + INNER JOIN CommandLengths + ON Phases.PhaseName = CommandLengths.Command + """) + util = cursor.fetchone()[0] + if (util is None): + util = 0 - if (result is None): - result = 0 - - clk, _ = getClock(connection) - traceEnd = getTraceEndTime(connection) - cmdBusOccupied = result * clk - return cmdBusOccupied / traceEnd * 100 + clk, _ = getClock(connection) + traceEnd = getTraceEndTime(connection) + commandBusOccupied = util * clk / traceEnd * 100 + return ": {}".format(commandBusOccupied) @metric def average_response_latency_in_ns(connection): @@ -1027,7 +1054,7 @@ def calculateMetrics(pathToTrace, selectedMetrics=[]): nbanks = nbanks + 1 r = (name, float(v)) calculatedMetrics.append(r) - elif (metric.__name__ == "delayed_reasons"): + elif (metric.__name__ == "delayed_reasons" or metric.__name__ == "command_bus_utilisation_in_percent"): values = mres.split(",") for v in values: name = mname + " (" + v.partition(":")[0].strip() + ")" diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.cpp b/DRAMSys/traceAnalyzer/traceanalyzer.cpp index 1cc0db53..0eb8fe77 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.cpp +++ b/DRAMSys/traceAnalyzer/traceanalyzer.cpp @@ -179,7 +179,7 @@ void TraceAnalyzer::reloadTab(int index) QString traceFile = traceFileTab->getPathToTraceFile(); traceTime time = traceFileTab->getCurrentTraceTime(); traceTime zoomLevel = traceFileTab->getZoomLevel(); - auto treeItems = traceFileTab->saveTraceSelectorState(); + auto rootNode = traceFileTab->saveTraceSelectorState(); if (!traceFileTab->close()) return; @@ -190,7 +190,7 @@ void TraceAnalyzer::reloadTab(int index) traceFileTab = createTraceFileTab(traceFile); traceFileTab->setZoomLevel(zoomLevel); traceFileTab->navigateToTime(time); - traceFileTab->restoreTraceSelectorState(treeItems); + traceFileTab->restoreTraceSelectorState(std::move(rootNode)); ui->traceFileTabs->insertTab(index, traceFileTab, QFileInfo(traceFile).baseName()); ui->traceFileTabs->setCurrentIndex(index); diff --git a/DRAMSys/traceAnalyzer/tracefiletab.cpp b/DRAMSys/traceAnalyzer/tracefiletab.cpp index bd6e72cb..01ce5ce7 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.cpp +++ b/DRAMSys/traceAnalyzer/tracefiletab.cpp @@ -42,8 +42,8 @@ #include "businessObjects/commentmodel.h" #include "businessObjects/configmodels.h" #include "businessObjects/pythoncaller.h" +#include "businessObjects/traceplotlinemodel.h" #include "businessObjects/tracetime.h" -#include "presentation/traceselector.h" #include "qmessagebox.h" #include "queryeditor.h" #include "qwt_legend.h" @@ -72,8 +72,12 @@ TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) : QWidget(parent), ui(new Ui::TraceFileTab), commentModel(new CommentModel(this)), navigator(new TraceNavigator(path, commentModel, this)), mcConfigModel(new McConfigModel(navigator->TraceFile(), this)), - memSpecModel(new MemSpecModel(navigator->TraceFile(), this)), savingChangesToDB(false), - depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)) + memSpecModel(new MemSpecModel(navigator->TraceFile(), this)), + availableRowsModel(new AvailableTracePlotLineModel(navigator->GeneralTraceInfo(), this)), + selectedRowsModel(new SelectedTracePlotLineModel(navigator->GeneralTraceInfo(), this)), + tracePlotLineDataSource(new TracePlotLineDataSource(selectedRowsModel, this)), + depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)), + savingChangesToDB(false) { ui->setupUi(this); this->path = path; @@ -81,12 +85,6 @@ TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) std::cout << "Opening new tab for \"" << path.toStdString() << "\"" << std::endl; - initNavigatorAndItsDependentWidgets(path); - setUpFileWatcher(path); - setUpTraceplotScrollbar(); - setUpTraceSelector(); - setUpCommentView(); - ui->mcConfigView->setModel(mcConfigModel); ui->mcConfigView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); @@ -96,6 +94,12 @@ TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) ui->depInfosView->setModel(depInfosView); ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + setUpTraceSelector(); + initNavigatorAndItsDependentWidgets(path); + setUpFileWatcher(path); + setUpTraceplotScrollbar(); + setUpCommentView(); + tracefileChanged(); } @@ -131,6 +135,32 @@ void TraceFileTab::exportAsVCD() } } +void TraceFileTab::setUpTraceSelector() +{ + ui->availableTreeView->setModel(availableRowsModel); + ui->availableTreeView->setSelectionModel(availableRowsModel->selectionModel()); + ui->availableTreeView->installEventFilter(availableRowsModel); + + ui->selectedTreeView->setModel(selectedRowsModel); + ui->selectedTreeView->setSelectionModel(selectedRowsModel->selectionModel()); + ui->selectedTreeView->installEventFilter(selectedRowsModel); + + connect(availableRowsModel, &AvailableTracePlotLineModel::returnPressed, selectedRowsModel, + &SelectedTracePlotLineModel::addIndexesFromAvailableModel); + + connect(ui->availableTreeView, &QAbstractItemView::doubleClicked, availableRowsModel, + &AvailableTracePlotLineModel::itemsDoubleClicked); + connect(ui->selectedTreeView, &QAbstractItemView::doubleClicked, selectedRowsModel, + &SelectedTracePlotLineModel::itemsDoubleClicked); + + connect(selectedRowsModel, &QAbstractItemModel::dataChanged, tracePlotLineDataSource, + &TracePlotLineDataSource::updateModel); + connect(selectedRowsModel, &QAbstractItemModel::rowsInserted, tracePlotLineDataSource, + &TracePlotLineDataSource::updateModel); + connect(selectedRowsModel, &QAbstractItemModel::rowsRemoved, tracePlotLineDataSource, + &TracePlotLineDataSource::updateModel); +} + void TraceFileTab::setUpTraceplotScrollbar() { QObject::connect(ui->traceplotScrollbar, SIGNAL(valueChanged(int)), @@ -139,9 +169,9 @@ void TraceFileTab::setUpTraceplotScrollbar() void TraceFileTab::initNavigatorAndItsDependentWidgets(QString path) { - ui->traceplot->init(navigator, ui->traceplotScrollbar, commentModel); + ui->traceplot->init(navigator, ui->traceplotScrollbar, tracePlotLineDataSource, commentModel); - ui->traceScroller->init(navigator, ui->traceplot); + ui->traceScroller->init(navigator, ui->traceplot, tracePlotLineDataSource); connect(this, SIGNAL(colorGroupingChanged(ColorGrouping)), ui->traceScroller, SLOT(colorGroupingChanged(ColorGrouping))); @@ -160,14 +190,6 @@ void TraceFileTab::setUpFileWatcher(QString path) SLOT(tracefileChanged())); } -void TraceFileTab::setUpTraceSelector() -{ - TraceSelector *selector = static_cast(ui->tabCustomizePlot); - connect(selector, &TraceSelector::selectedTreeChanged, - ui->traceplot, &TracePlot::updateTracePlotLines); - selector->init(ui->traceplot); -} - void TraceFileTab::setUpCommentView() { ui->commentView->setModel(commentModel); @@ -262,16 +284,14 @@ void TraceFileTab::setZoomLevel(traceTime zoomLevel) tracescroller->tracePlotZoomChanged(); } -std::vector TraceFileTab::saveTraceSelectorState() const +std::shared_ptr TraceFileTab::saveTraceSelectorState() const { - TraceSelector *selector = static_cast(ui->tabCustomizePlot); - return selector->getTraceSelectorState(); + return selectedRowsModel->getClonedRootNode(); } -void TraceFileTab::restoreTraceSelectorState(const std::vector &items) +void TraceFileTab::restoreTraceSelectorState(std::shared_ptr rootNode) { - TraceSelector *selector = static_cast(ui->tabCustomizePlot); - selector->restoreTraceSelectorState(items); + selectedRowsModel->setRootNode(std::move(rootNode)); } class ItemDelegate: public QItemDelegate diff --git a/DRAMSys/traceAnalyzer/tracefiletab.h b/DRAMSys/traceAnalyzer/tracefiletab.h index a345bbc1..bc966548 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.h +++ b/DRAMSys/traceAnalyzer/tracefiletab.h @@ -40,15 +40,19 @@ #ifndef TRACEFILETAB_H #define TRACEFILETAB_H -#include -#include -#include +#include "businessObjects/traceplotlinemodel.h" #include "presentation/tracenavigator.h" #include "presentation/traceplot.h" #include "presentation/tracescroller.h" -#include "businessObjects/configmodels.h" + +#include +#include +#include +#include class CommentModel; +class McConfigModel; +class MemSpecModel; namespace Ui { class TraceFileTab; @@ -64,8 +68,8 @@ public: void setUpFileWatcher(QString filename); void setUpTraceplotScrollbar(); - void setUpTraceSelector(); void setUpCommentView(); + void setUpTraceSelector(); void initNavigatorAndItsDependentWidgets(QString path); QString getPathToTraceFile() { @@ -79,8 +83,8 @@ public: traceTime getZoomLevel() const; void setZoomLevel(traceTime zoomLevel); - std::vector saveTraceSelectorState() const; - void restoreTraceSelectorState(const std::vector &items); + std::shared_ptr saveTraceSelectorState() const; + void restoreTraceSelectorState(std::shared_ptr rootNode); protected: void closeEvent(QCloseEvent *event) override; @@ -100,8 +104,12 @@ private: CommentModel *commentModel; TraceNavigator *navigator; - QAbstractItemModel *mcConfigModel; - QAbstractItemModel *memSpecModel; + McConfigModel *mcConfigModel; + MemSpecModel *memSpecModel; + + AvailableTracePlotLineModel *availableRowsModel; + SelectedTracePlotLineModel *selectedRowsModel; + TracePlotLineDataSource *tracePlotLineDataSource; QAbstractItemModel *depInfosView; diff --git a/DRAMSys/traceAnalyzer/tracefiletab.ui b/DRAMSys/traceAnalyzer/tracefiletab.ui index 22a0a210..cb1e8a42 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.ui +++ b/DRAMSys/traceAnalyzer/tracefiletab.ui @@ -197,10 +197,69 @@ - + Customize Plot + + + + + <html><head/><body><p>To customize the displayed rows double click or drag and drop items from the upper list to the lower list.</p></body></html> + + + false + + + Qt::AlignCenter + + + true + + + + + + + false + + + true + + + QAbstractItemView::DragOnly + + + QAbstractItemView::ExtendedSelection + + + false + + + + + + + true + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + QAbstractItemView::ExtendedSelection + + + false + + + + @@ -377,6 +436,7 @@ QwtPlot QFrame
qwt_plot.h
+ 1 TracePlot @@ -393,12 +453,6 @@ QTreeWidget
presentation/selectedtransactiontreewidget.h
- - TraceSelector - QWidget -
presentation/traceselector.h
- 1 -