From 816a6b7df8293e0ca877e61fb800f8b728dec946 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 11 Oct 2021 11:41:39 +0200 Subject: [PATCH 1/4] Introduce a model/view based approach for the TraceSelector Replace the old TraceSelector with a new, more generic model/view based approach. This approach has the advantage that the seperate lines that are available in a plot are generated at one single place in the code. Also states such as the collapsed state can be stored in this model, making it much easier to save and restore the whole selected tree of TracePlotLines. This approach makes it also easier to add new functionality to the TraceAnalyzer in the future. --- DRAMSys/traceAnalyzer/CMakeLists.txt | 4 +- .../businessObjects/configmodels.cpp | 2 +- .../businessObjects/configmodels.h | 8 +- .../businessObjects/phases/phase.cpp | 188 ++++-- .../businessObjects/phases/phase.h | 16 +- .../phases/phasedependency.cpp | 11 +- .../businessObjects/traceplotlinemodel.cpp | 605 ++++++++++++++++++ .../businessObjects/traceplotlinemodel.h | 256 ++++++++ DRAMSys/traceAnalyzer/markerplotitem.h | 4 + .../presentation/tracedrawingproperties.cpp | 243 +------ .../presentation/tracedrawingproperties.h | 62 +- .../presentation/tracenavigator.cpp | 19 - .../presentation/tracenavigator.h | 8 - .../traceAnalyzer/presentation/traceplot.cpp | 228 ++++--- .../traceAnalyzer/presentation/traceplot.h | 32 +- .../presentation/tracescroller.cpp | 18 +- .../presentation/tracescroller.h | 4 +- .../presentation/traceselector.cpp | 460 ------------- .../presentation/traceselector.h | 146 ----- .../presentation/util/traceplotline.cpp | 148 ----- .../presentation/util/traceplotline.h | 159 ----- .../presentation/util/traceplotlinecache.cpp | 223 ------- .../presentation/util/traceplotlinecache.h | 80 --- DRAMSys/traceAnalyzer/traceanalyzer.cpp | 4 +- DRAMSys/traceAnalyzer/tracefiletab.cpp | 70 +- DRAMSys/traceAnalyzer/tracefiletab.h | 26 +- DRAMSys/traceAnalyzer/tracefiletab.ui | 68 +- 27 files changed, 1337 insertions(+), 1755 deletions(-) create mode 100644 DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp create mode 100644 DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h delete mode 100644 DRAMSys/traceAnalyzer/presentation/traceselector.cpp delete mode 100644 DRAMSys/traceAnalyzer/presentation/traceselector.h delete mode 100644 DRAMSys/traceAnalyzer/presentation/util/traceplotline.cpp delete mode 100644 DRAMSys/traceAnalyzer/presentation/util/traceplotline.h delete mode 100644 DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.cpp delete mode 100644 DRAMSys/traceAnalyzer/presentation/util/traceplotlinecache.h 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/phases/phase.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp index 463fde5c..35a70281 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,43 @@ 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::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 +177,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,31 +275,35 @@ 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; + } + + for (Timespan span : spansOnCommandBus) + { + if (span.overlaps(timespan)) + { + for (const auto &line : drawingProperties.getTracePlotLines()) + { + if (line->data.type != AbstractTracePlotLineModel::CommandBusLine) + continue; + + if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2) + return true; + } } } if (spanOnDataBus && spanOnDataBus->overlaps(timespan)) { - for (auto dataBusLine : drawingProperties.getDataBusLines()) + for (const auto &line : drawingProperties.getTracePlotLines()) { - if (fabs(yVal - dataBusLine->getYVal()) <= hexagonHeight) - return true; - } - } + if (line->data.type != AbstractTracePlotLineModel::DataBusLine) + continue; - for (const Timespan &span : spansOnCommandBus) - { - if (span.overlaps(timespan)) - { - for (auto commandBusLine : drawingProperties.getCommandBusLines()) - { - if (fabs(yVal - commandBusLine->getYVal()) <= hexagonHeight) - return true; - } + if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2) + return true; } } @@ -235,36 +315,6 @@ 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..04fb939c 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -97,6 +97,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 +105,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 +128,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 +145,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..d05c51f2 --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp @@ -0,0 +1,605 @@ +/* + * 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) +{ + 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)); + + addTopLevelNode(std::unique_ptr( + new Node({LineType::CommandBusLine, getLabel(LineType::CommandBusLine)}, 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(); + + collapseButtons.clear(); + + for (const auto &node : rootNode->children) + { + if (node->data.type != LineType::RankGroup) + continue; + + QPushButton *collapseButton = new QPushButton(tracePlot); + + unsigned int yVal = [&]() + { + 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); + }; + + connect(customLabelScaleDraw, &CustomLabelScaleDraw::scaleRedraw, this, 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::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); +} + +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 (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) +{ + auto availableModel = qobject_cast(sender()); + + 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 << "application/x-tracelinedata"; + + 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("application/x-tracelinedata", 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("application/x-tracelinedata")) + 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("application/x-tracelinedata"); + 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) +{ + 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..efff80db --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.h @@ -0,0 +1,256 @@ +/* + * 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, + 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: + 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); + + QItemSelectionModel *internalSelectionModel; + + std::shared_ptr rootNode; + + unsigned int numberOfRanks; + unsigned int groupsPerRank; + unsigned int banksPerGroup; + unsigned int banksPerRank; +}; + +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/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/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 -
From 487ef6cb4ecf6577246d39fadb1445e5ff2a2368 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 14 Feb 2022 12:55:24 +0100 Subject: [PATCH 2/4] Fix minor memory leak when recreating buttons --- .../traceAnalyzer/businessObjects/traceplotlinemodel.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp index d05c51f2..b57b2f4f 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp @@ -232,7 +232,10 @@ void SelectedTracePlotLineModel::recreateCollapseButtons(TracePlot *tracePlot, { // Remove old buttons for (auto button : collapseButtons) + { button->hide(); + button->deleteLater(); + } collapseButtons.clear(); @@ -243,7 +246,7 @@ void SelectedTracePlotLineModel::recreateCollapseButtons(TracePlot *tracePlot, QPushButton *collapseButton = new QPushButton(tracePlot); - unsigned int yVal = [&]() + unsigned int yVal = [node]() { if (node->data.collapsed) return node->data.yVal; @@ -270,7 +273,9 @@ void SelectedTracePlotLineModel::recreateCollapseButtons(TracePlot *tracePlot, recreateCollapseButtons(tracePlot, customLabelScaleDraw); }; - connect(customLabelScaleDraw, &CustomLabelScaleDraw::scaleRedraw, this, repositionButton); + // 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); From e24ec133cc44a267c41da98794d8124dabdc1e91 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 14 Feb 2022 15:37:32 +0100 Subject: [PATCH 3/4] Seperated command bus for HBM2 --- DRAMSys/library/src/common/TlmRecorder.cpp | 18 ++++++-- DRAMSys/library/src/common/TlmRecorder.h | 3 +- .../businessObjects/generalinfo.h | 28 ++++++------ .../businessObjects/phases/phase.cpp | 25 ++++++++++- .../businessObjects/phases/phase.h | 1 + .../businessObjects/traceplotlinemodel.cpp | 43 ++++++++++++++----- .../businessObjects/traceplotlinemodel.h | 24 ++++++++--- DRAMSys/traceAnalyzer/data/tracedb.cpp | 11 +++-- 8 files changed, 116 insertions(+), 37 deletions(-) diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index c89b60f9..ddaca67c 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/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 35a70281..2c5c35f8 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp @@ -85,7 +85,17 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, { for (const auto &line : drawingProperties.getTracePlotLines()) { - if (line->data.type != AbstractTracePlotLineModel::CommandBusLine) + 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, @@ -286,7 +296,9 @@ bool Phase::isSelected(Timespan timespan, double yVal, const TraceDrawingPropert { for (const auto &line : drawingProperties.getTracePlotLines()) { - if (line->data.type != AbstractTracePlotLineModel::CommandBusLine) + 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) @@ -310,6 +322,15 @@ bool Phase::isSelected(Timespan timespan, double yVal, const TraceDrawingPropert 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; diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index 04fb939c..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; diff --git a/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp index b57b2f4f..dde50281 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/traceplotlinemodel.cpp @@ -45,7 +45,7 @@ AbstractTracePlotLineModel::AbstractTracePlotLineModel(const GeneralInfo &genera : QAbstractItemModel(parent), internalSelectionModel(new QItemSelectionModel(this, this)), rootNode(std::make_shared()), numberOfRanks(generalInfo.numberOfRanks), groupsPerRank(generalInfo.groupsPerRank), banksPerGroup(generalInfo.banksPerGroup), - banksPerRank(generalInfo.banksPerRank) + banksPerRank(generalInfo.banksPerRank), commandBusType(getCommandBusType(generalInfo)) { createInitialNodes(); } @@ -75,8 +75,19 @@ void AbstractTracePlotLineModel::createInitialNodes() for (unsigned int rank = numberOfRanks; rank--;) addTopLevelNode(createRankGroupNode(rank)); - addTopLevelNode(std::unique_ptr( - new Node({LineType::CommandBusLine, getLabel(LineType::CommandBusLine)}, rootNode.get()))); + 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()))); } @@ -319,6 +330,10 @@ QString AbstractTracePlotLineModel::getLabel(LineType type) 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: @@ -336,6 +351,14 @@ QString AbstractTracePlotLineModel::getLabel(unsigned int rank, unsigned int gro 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()) @@ -404,7 +427,7 @@ bool SelectedTracePlotLineModel::eventFilter(QObject *object, QEvent *event) if (indexes.count() == 0) return true; - for (auto &index : indexes) + for (const auto &index : indexes) { // Only remove toplevel indexes if (index.parent() != QModelIndex()) @@ -425,8 +448,6 @@ bool SelectedTracePlotLineModel::eventFilter(QObject *object, QEvent *event) void SelectedTracePlotLineModel::addIndexesFromAvailableModel(const QModelIndexList &indexes) { - auto availableModel = qobject_cast(sender()); - for (const auto &index : indexes) { auto node = static_cast(index.internalPointer()); @@ -446,7 +467,7 @@ QItemSelectionModel *AbstractTracePlotLineModel::selectionModel() const QStringList AbstractTracePlotLineModel::mimeTypes() const { QStringList types = QAbstractItemModel::mimeTypes(); - types << "application/x-tracelinedata"; + types << TRACELINE_MIMETYPE; return types; } @@ -465,7 +486,7 @@ QMimeData *AbstractTracePlotLineModel::mimeData(const QModelIndexList &indexes) } QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-tracelinedata", traceLineData); + mimeData->setData(TRACELINE_MIMETYPE, traceLineData); return mimeData; } @@ -477,7 +498,7 @@ bool AbstractTracePlotLineModel::canDropMimeData(const QMimeData *data, Qt::Drop Q_UNUSED(row); Q_UNUSED(parent); - if (!data->hasFormat("application/x-tracelinedata")) + if (!data->hasFormat(TRACELINE_MIMETYPE)) return false; if (column > 0) @@ -508,7 +529,7 @@ bool AbstractTracePlotLineModel::dropMimeData(const QMimeData *data, Qt::DropAct { dropHandled = true; - QByteArray traceLineData = data->data("application/x-tracelinedata"); + QByteArray traceLineData = data->data(TRACELINE_MIMETYPE); QDataStream dataStream(&traceLineData, QIODevice::ReadOnly); std::vector> droppedNodes; @@ -583,6 +604,8 @@ void SelectedTracePlotLineModel::setRootNode(std::shared_ptr rootNode; - unsigned int numberOfRanks; - unsigned int groupsPerRank; - unsigned int banksPerGroup; - unsigned int banksPerRank; + const unsigned int numberOfRanks; + const unsigned int groupsPerRank; + const unsigned int banksPerGroup; + const unsigned int banksPerRank; + + const CommandBusType commandBusType; }; class AvailableTracePlotLineModel : public AbstractTracePlotLineModel 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() From 4346fc72cb79739a203cb53beb0b020faa2d7765 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 31 Mar 2022 17:02:02 +0200 Subject: [PATCH 4/4] Adapt metric for separate command buses. --- DRAMSys/traceAnalyzer/scripts/metrics.py | 61 +++++++++++++++++------- 1 file changed, 44 insertions(+), 17 deletions(-) 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() + ")"