Merge branch 'work/traceanalyzer_rowmodel' into 'develop'

Introduce a model/view based approach for the TraceSelector

See merge request ems/astdm/modeling.dram/dram.sys!324
This commit is contained in:
Lukas Steiner
2022-04-01 12:12:37 +00:00
32 changed files with 1484 additions and 1791 deletions

View File

@@ -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<int>(Configuration::getInstance().requestBufferSize));
sqlite3_bind_int(insertGeneralInfoStatement, 16,
static_cast<int>(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<int>(rowColumnCommandBus));
executeSqlStatement(insertGeneralInfoStatement);
}

View File

@@ -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"

View File

@@ -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

View File

@@ -278,7 +278,7 @@ QModelIndex MemSpecModel::parent(const QModelIndex &index) const
const Node *childNode = static_cast<const Node *>(index.internalPointer());
const Node *parentNode = childNode->parent;
if (!parentNode)
if (!parentNode || parentNode == rootNode.get())
return QModelIndex();
return createIndex(parentNode->getRow(), 0, const_cast<Node *>(parentNode));

View File

@@ -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<QString, QString>;
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) {}
/**

View File

@@ -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

View File

@@ -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 <cmath>
void Phase::draw(QPainter *painter, const QwtScaleMap &xMap,
@@ -64,42 +65,53 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap,
painter->setPen(pen);
}
for (auto line : getTracePlotLines(drawingProperties))
for (auto yVal : getYVals(drawingProperties))
{
if (!line->isCollapsed())
drawPhaseSymbol(span.Begin(), span.End(), yVal, drawingProperties.drawText, getPhaseSymbol(), painter, xMap,
yMap, drawingProperties.textColor);
if (getGranularity() == Granularity::Bankwise)
{
drawPhaseSymbol(span.Begin(), span.End(), line->getYVal(),
drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap, drawingProperties.textColor);
if (getGranularity() == Granularity::Bankwise)
DependencyOptions drawDependenciesOptions = drawingProperties.drawDependenciesOption;
if (drawDependenciesOptions.draw == DependencyOption::All ||
(drawDependenciesOptions.draw == DependencyOption::Selected && highlight))
{
DependencyOptions drawDependenciesOptions = drawingProperties.drawDependenciesOption;
if (drawDependenciesOptions.draw == DependencyOption::All ||
(drawDependenciesOptions.draw == DependencyOption::Selected && highlight))
{
drawPhaseDependencies(span.Begin(), span.End(), line->getYVal(), drawingProperties, painter, xMap,
yMap);
}
drawPhaseDependencies(span.Begin(), span.End(), yVal, drawingProperties, painter, xMap, yMap);
}
}
}
for (Timespan span : spansOnCommandBus)
{
for (auto commandBusLine : drawingProperties.getCommandBusLines())
for (const auto &line : drawingProperties.getTracePlotLines())
{
drawPhaseSymbol(span.Begin(), span.End(), commandBusLine->getYVal(),
false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor);
if (line->data.type == AbstractTracePlotLineModel::RowCommandBusLine)
{
if (isColumnCommand())
continue;
}
else if (line->data.type == AbstractTracePlotLineModel::ColumnCommandBusLine)
{
if (!isColumnCommand())
continue;
}
else if (line->data.type != AbstractTracePlotLineModel::CommandBusLine)
continue;
drawPhaseSymbol(span.Begin(), span.End(), line->data.yVal, false, PhaseSymbol::Hexagon, painter, xMap,
yMap, drawingProperties.textColor);
}
}
if (spanOnDataBus)
{
for (auto dataBusLine : drawingProperties.getDataBusLines())
for (const auto &line : drawingProperties.getTracePlotLines())
{
drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), dataBusLine->getYVal(),
false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor);
if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
continue;
drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), line->data.yVal, false, PhaseSymbol::Hexagon,
painter, xMap, yMap, drawingProperties.textColor);
}
}
}
@@ -175,6 +187,80 @@ void Phase::drawPhaseDependencies(traceTime begin, traceTime end, double y,
painter->restore();
}
std::vector<int> Phase::getYVals(const TraceDrawingProperties &drawingProperties) const
{
std::vector<int> 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<int> REQ::getYVals(const TraceDrawingProperties &drawingProperties) const
{
std::vector<int> yVals;
for (const auto &line : drawingProperties.getTracePlotLines())
{
if (line->data.type != AbstractTracePlotLineModel::RequestLine)
continue;
yVals.push_back(line->data.yVal);
}
return yVals;
}
std::vector<int> RESP::getYVals(const TraceDrawingProperties &drawingProperties) const
{
std::vector<int> yVals;
for (const auto &line : drawingProperties.getTracePlotLines())
{
if (line->data.type != AbstractTracePlotLineModel::ResponseLine)
continue;
yVals.push_back(line->data.yVal);
}
return yVals;
}
QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const
{
switch (drawingProperties.colorGrouping)
@@ -199,72 +285,57 @@ bool Phase::isSelected(Timespan timespan, double yVal, const TraceDrawingPropert
{
if (span.overlaps(timespan))
{
for (auto line : getTracePlotLines(drawingProperties))
{
if (!line->isCollapsed() && fabs(yVal - line->getYVal()) <= hexagonHeight / 2)
for (auto lineYVal : getYVals(drawingProperties))
if (fabs(yVal - lineYVal) <= hexagonHeight / 2)
return true;
}
}
if (spanOnDataBus && spanOnDataBus->overlaps(timespan))
{
for (auto dataBusLine : drawingProperties.getDataBusLines())
{
if (fabs(yVal - dataBusLine->getYVal()) <= hexagonHeight)
return true;
}
}
for (const Timespan &span : spansOnCommandBus)
for (Timespan span : spansOnCommandBus)
{
if (span.overlaps(timespan))
{
for (auto commandBusLine : drawingProperties.getCommandBusLines())
for (const auto &line : drawingProperties.getTracePlotLines())
{
if (fabs(yVal - commandBusLine->getYVal()) <= hexagonHeight)
if ((line->data.type != AbstractTracePlotLineModel::CommandBusLine) &&
(line->data.type != AbstractTracePlotLineModel::RowCommandBusLine) &&
(line->data.type != AbstractTracePlotLineModel::ColumnCommandBusLine))
continue;
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
return true;
}
}
}
if (spanOnDataBus && spanOnDataBus->overlaps(timespan))
{
for (const auto &line : drawingProperties.getTracePlotLines())
{
if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
continue;
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
return true;
}
}
return false;
}
bool Phase::isColumnCommand() const
{
if (dynamic_cast<const RD *>(this) || dynamic_cast<const RDA *>(this) || dynamic_cast<const WR *>(this) ||
dynamic_cast<const WRA *>(this))
return true;
else
return false;
}
Phase::PhaseSymbol Phase::getPhaseSymbol() const
{
return PhaseSymbol::Hexagon;
}
std::vector<std::shared_ptr<TracePlotLine>> 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<PhaseDependency> dependency)
{
mDependencies.push_back(dependency);

View File

@@ -67,6 +67,7 @@ public:
const QRectF &canvasRect, bool highlight,
const TraceDrawingProperties &drawingProperties) const;
bool isSelected(Timespan timespan, double yVal, const TraceDrawingProperties &drawingproperties) const;
bool isColumnCommand() const;
const Timespan &Span() const
{
return span;
@@ -97,6 +98,7 @@ protected:
virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const;
virtual QColor getPhaseColor() const = 0;
virtual std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const;
virtual void drawPhaseSymbol(traceTime begin, traceTime end, double y,
bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap,
const QwtScaleMap &yMap, QColor textColor) const;
@@ -104,8 +106,6 @@ protected:
const TraceDrawingProperties &drawingProperties, QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap) const;
virtual std::vector<std::shared_ptr<TracePlotLine>> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const;
enum class Granularity {Bankwise, TwoBankwise, Groupwise, Rankwise};
virtual Granularity getGranularity() const
@@ -129,11 +129,8 @@ protected:
{
return "REQ";
}
std::vector<std::shared_ptr<TracePlotLine>> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const
override
{
return drawingProperties.getRequestLines();
}
std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const override;
};
class RESP final : public Phase
@@ -149,12 +146,8 @@ protected:
{
return "RESP";
}
std::vector<std::shared_ptr<TracePlotLine>> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const
override
{
return drawingProperties.getResponseLines();
}
std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const override;
};
/*
class PREB final : public Phase

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,633 @@
/*
* Copyright (c) 2021, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "traceplotlinemodel.h"
#include "../presentation/traceplot.h"
#include "../presentation/util/customlabelscaledraw.h"
#include <QItemSelectionModel>
#include <QKeyEvent>
#include <QMimeData>
AbstractTracePlotLineModel::AbstractTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent)
: QAbstractItemModel(parent), internalSelectionModel(new QItemSelectionModel(this, this)),
rootNode(std::make_shared<Node>()), numberOfRanks(generalInfo.numberOfRanks),
groupsPerRank(generalInfo.groupsPerRank), banksPerGroup(generalInfo.banksPerGroup),
banksPerRank(generalInfo.banksPerRank), commandBusType(getCommandBusType(generalInfo))
{
createInitialNodes();
}
AvailableTracePlotLineModel::AvailableTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent)
: AbstractTracePlotLineModel(generalInfo, parent)
{
}
SelectedTracePlotLineModel::SelectedTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent)
: AbstractTracePlotLineModel(generalInfo, parent)
{
}
void AbstractTracePlotLineModel::addTopLevelNode(std::shared_ptr<Node> &&node)
{
rootNode->children.push_back(std::move(node));
}
void AbstractTracePlotLineModel::createInitialNodes()
{
addTopLevelNode(
std::unique_ptr<Node>(new Node({LineType::RequestLine, getLabel(LineType::RequestLine)}, rootNode.get())));
addTopLevelNode(
std::unique_ptr<Node>(new Node({LineType::ResponseLine, getLabel(LineType::ResponseLine)}, rootNode.get())));
for (unsigned int rank = numberOfRanks; rank--;)
addTopLevelNode(createRankGroupNode(rank));
if (commandBusType == CommandBusType::SingleCommandBus)
{
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::CommandBusLine, getLabel(LineType::CommandBusLine)}, rootNode.get())));
}
else // commandBusType == CommandBusType::RowColumnCommandBus
{
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::RowCommandBusLine, getLabel(LineType::RowCommandBusLine)}, rootNode.get())));
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::ColumnCommandBusLine, getLabel(LineType::ColumnCommandBusLine)}, rootNode.get())));
}
addTopLevelNode(
std::unique_ptr<Node>(new Node({LineType::DataBusLine, getLabel(LineType::DataBusLine)}, rootNode.get())));
}
std::shared_ptr<AbstractTracePlotLineModel::Node>
AbstractTracePlotLineModel::createRankGroupNode(unsigned int rank) const
{
auto rankGroup = std::unique_ptr<Node>(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<Node>(
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<const Node *>(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<const Node *>(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<Node *>(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<const Node *>(parent.internalPointer());
const Node *node = parentNode->children[row].get();
return createIndex(row, column, const_cast<Node *>(node));
}
QModelIndex AbstractTracePlotLineModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
const Node *childNode = static_cast<const Node *>(index.internalPointer());
const Node *parentNode = childNode->parent;
if (!parentNode || parentNode == rootNode.get())
return QModelIndex();
return createIndex(parentNode->getRow(), 0, const_cast<Node *>(parentNode));
}
void SelectedTracePlotLineModel::recreateCollapseButtons(TracePlot *tracePlot,
CustomLabelScaleDraw *customLabelScaleDraw)
{
// Remove old buttons
for (auto button : collapseButtons)
{
button->hide();
button->deleteLater();
}
collapseButtons.clear();
for (const auto &node : rootNode->children)
{
if (node->data.type != LineType::RankGroup)
continue;
QPushButton *collapseButton = new QPushButton(tracePlot);
unsigned int yVal = [node]()
{
if (node->data.collapsed)
return node->data.yVal;
else
return node->children.at(0)->data.yVal;
}();
bool isCollapsed = node->data.collapsed;
QModelIndex nodeIndex = index(node->getRow(), 0);
auto repositionButton = [=]()
{
QPointF point = tracePlot->axisScaleDraw(QwtPlot::yLeft)->labelPosition(yVal);
collapseButton->setGeometry(point.x(), point.y() - 4, 25, 25);
};
repositionButton();
auto updateLabel = [=]() { collapseButton->setText(isCollapsed ? "+" : "-"); };
updateLabel();
auto toggleCollapsed = [=]()
{
setData(nodeIndex, !isCollapsed, Role::CollapsedRole);
recreateCollapseButtons(tracePlot, customLabelScaleDraw);
};
// Important: The context of the connection is `collapseButton` as it should be disconnected when the button
// ceases to exist.
connect(customLabelScaleDraw, &CustomLabelScaleDraw::scaleRedraw, collapseButton, repositionButton);
connect(collapseButton, &QPushButton::pressed, this, toggleCollapsed);
connect(collapseButton, &QPushButton::pressed, tracePlot, &TracePlot::recreateCollapseButtons);
collapseButton->show();
collapseButtons.push_back(collapseButton);
}
}
int AbstractTracePlotLineModel::Node::getRow() const
{
if (!parent)
return 0;
const auto &siblings = parent->children;
const auto siblingsIt = std::find_if(siblings.begin(), siblings.end(),
[this](const std::shared_ptr<Node> &node) { return node.get() == this; });
Q_ASSERT(siblingsIt != siblings.end());
return std::distance(siblings.begin(), siblingsIt);
}
std::shared_ptr<AbstractTracePlotLineModel::Node> AbstractTracePlotLineModel::Node::cloneNode(const Node *node,
const Node *parent)
{
std::shared_ptr<Node> clonedNode = std::make_shared<Node>(node->data, parent);
for (const auto &child : node->children)
clonedNode->children.push_back(cloneNode(child.get(), clonedNode.get()));
return clonedNode;
}
QString AbstractTracePlotLineModel::getLabel(LineType type)
{
switch (type)
{
case LineType::RequestLine:
return "REQ";
case LineType::ResponseLine:
return "RESP";
case LineType::CommandBusLine:
return "Command Bus";
case LineType::RowCommandBusLine:
return "Command Bus [R]";
case LineType::ColumnCommandBusLine:
return "Command Bus [C]";
case LineType::DataBusLine:
return "Data Bus";
default:
return "";
}
}
QString AbstractTracePlotLineModel::getLabel(unsigned int rank)
{
return "RA" + QString::number(rank);
}
QString AbstractTracePlotLineModel::getLabel(unsigned int rank, unsigned int group, unsigned int bank)
{
return "RA" + QString::number(rank) + " BG" + QString::number(group) + " BA" + QString::number(bank);
}
AbstractTracePlotLineModel::CommandBusType AbstractTracePlotLineModel::getCommandBusType(const GeneralInfo &generalInfo)
{
if (generalInfo.rowColumnCommandBus)
return CommandBusType::RowColumnCommandBus;
else
return CommandBusType::SingleCommandBus;
}
bool SelectedTracePlotLineModel::removeRows(int row, int count, const QModelIndex &parent)
{
if (parent != QModelIndex())
return false;
// Note: beginRemoveRows requires [first, last], but erase requires [first, last)
beginRemoveRows(QModelIndex(), row, row + count - 1);
rootNode->children.erase(rootNode->children.begin() + row, rootNode->children.begin() + row + count);
endRemoveRows();
return true;
}
void AvailableTracePlotLineModel::itemsDoubleClicked(const QModelIndex &index)
{
QModelIndexList indexList({index});
emit returnPressed(indexList);
}
void SelectedTracePlotLineModel::itemsDoubleClicked(const QModelIndex &index)
{
if (index.parent() != QModelIndex())
return;
removeRow(index.row(), QModelIndex());
}
bool AvailableTracePlotLineModel::eventFilter(QObject *object, QEvent *event)
{
Q_UNUSED(object)
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(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<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Delete)
{
// Note: This implementation requires the selection to be contiguous
const QModelIndexList indexes = internalSelectionModel->selectedRows();
if (indexes.count() == 0)
return true;
for (const auto &index : indexes)
{
// Only remove toplevel indexes
if (index.parent() != QModelIndex())
return true;
}
removeRows(indexes.at(0).row(), indexes.size(), QModelIndex());
return true;
}
else
{
return false;
}
}
return false;
}
void SelectedTracePlotLineModel::addIndexesFromAvailableModel(const QModelIndexList &indexes)
{
for (const auto &index : indexes)
{
auto node = static_cast<const Node *>(index.internalPointer());
auto clonedNode = Node::cloneNode(node, rootNode.get());
beginInsertRows(QModelIndex(), rootNode->children.size(), rootNode->children.size());
addTopLevelNode(std::move(clonedNode));
endInsertRows();
}
}
QItemSelectionModel *AbstractTracePlotLineModel::selectionModel() const
{
return internalSelectionModel;
}
QStringList AbstractTracePlotLineModel::mimeTypes() const
{
QStringList types = QAbstractItemModel::mimeTypes();
types << TRACELINE_MIMETYPE;
return types;
}
QMimeData *AbstractTracePlotLineModel::mimeData(const QModelIndexList &indexes) const
{
QByteArray traceLineData;
QDataStream dataStream(&traceLineData, QIODevice::WriteOnly);
for (const auto &index : indexes)
{
const Node *node = static_cast<const Node *>(index.internalPointer());
dataStream << node->data.type << node->data.label << node->data.rank << node->data.group << node->data.bank
<< node->data.collapsed;
}
QMimeData *mimeData = new QMimeData;
mimeData->setData(TRACELINE_MIMETYPE, traceLineData);
return mimeData;
}
bool AbstractTracePlotLineModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent) const
{
Q_UNUSED(action);
Q_UNUSED(row);
Q_UNUSED(parent);
if (!data->hasFormat(TRACELINE_MIMETYPE))
return false;
if (column > 0)
return false;
return true;
}
bool AbstractTracePlotLineModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent)
{
if (!canDropMimeData(data, action, row, column, parent))
return false;
if (action == Qt::IgnoreAction)
return true;
bool dropHandled = false;
int beginRow;
if (row != -1)
beginRow = row;
else
beginRow = rowCount(QModelIndex());
if (action == Qt::CopyAction || action == Qt::MoveAction)
{
dropHandled = true;
QByteArray traceLineData = data->data(TRACELINE_MIMETYPE);
QDataStream dataStream(&traceLineData, QIODevice::ReadOnly);
std::vector<std::shared_ptr<Node>> 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> node;
if (type == LineType::BankLine)
node = std::make_shared<Node>(Node::NodeData{type, label, rank, group, bank}, rootNode.get());
else if (type == LineType::RankGroup)
node = createRankGroupNode(rank);
else
node = std::make_shared<Node>(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<AbstractTracePlotLineModel::Node> SelectedTracePlotLineModel::getClonedRootNode()
{
return Node::cloneNode(rootNode.get(), nullptr);
}
void SelectedTracePlotLineModel::setRootNode(std::shared_ptr<AbstractTracePlotLineModel::Node> node)
{
removeRows(0, rootNode->childCount(), QModelIndex());
beginInsertRows(QModelIndex(), 0, node->childCount() - 1);
rootNode = std::move(node);
endInsertRows();
}
TracePlotLineDataSource::TracePlotLineDataSource(SelectedTracePlotLineModel *selectedModel, QObject *parent)
: selectedModel(selectedModel)
{
Q_UNUSED(parent)
updateModel();
}
void TracePlotLineDataSource::updateModel()
{
entries.clear();
std::function<void(std::shared_ptr<AbstractTracePlotLineModel::Node> & parent)> addNodes;
addNodes = [=, &addNodes](std::shared_ptr<AbstractTracePlotLineModel::Node> &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();
}

View File

@@ -0,0 +1,270 @@
/*
* Copyright (c) 2021, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#ifndef TRACEPLOTLINEMODEL_H
#define TRACEPLOTLINEMODEL_H
#include "generalinfo.h"
#include <QAbstractItemModel>
#include <QPushButton>
#include <memory>
class TracePlot;
class CustomLabelScaleDraw;
class QItemSelectionModel;
class AbstractTracePlotLineModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit AbstractTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
QItemSelectionModel *selectionModel() const;
enum Role
{
TypeRole = Qt::UserRole + 1,
CollapsedRole
};
Q_ENUM(Role)
enum LineType
{
RequestLine,
ResponseLine,
CommandBusLine,
RowCommandBusLine,
ColumnCommandBusLine,
DataBusLine,
RankGroup,
BankLine
};
Q_ENUM(LineType)
struct Node
{
struct NodeData
{
NodeData() = default;
NodeData(LineType type, const QString &label) : type(type), label(label)
{
}
NodeData(LineType type, const QString &label, unsigned int rank) : type(type), label(label), rank(rank)
{
}
NodeData(LineType type, const QString &label, unsigned int rank, unsigned int group, unsigned int bank)
: type(type), label(label), rank(rank), group(group), bank(bank)
{
}
LineType type;
QString label;
unsigned int yVal = 0;
/**
* Used to store the collapsed state in the traceplot.
* The value has only an effect when the type is Type::RankGroup.
*/
bool collapsed = true;
/**
* Only used when the type is Type::BankLine.
* (Absolute numbering)
*/
unsigned int rank = 0, group = 0, bank = 0;
};
/**
* Constructor only used for the root node that does not contain any data.
*/
Node() = default;
Node(NodeData data, const Node *parent) : data(data), parent(parent)
{
}
/**
* Gets the row relative to its parent.
*/
int getRow() const;
int childCount() const
{
return children.size();
}
static std::shared_ptr<Node> cloneNode(const Node *node, const Node *parent);
NodeData data;
const Node *parent = nullptr;
std::vector<std::shared_ptr<Node>> children;
};
protected:
enum class CommandBusType
{
SingleCommandBus,
RowColumnCommandBus
};
QStringList mimeTypes() const override;
QMimeData *mimeData(const QModelIndexList &indexes) const override;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent) override;
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent) const override;
Qt::DropActions supportedDropActions() const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
void addTopLevelNode(std::shared_ptr<Node> &&node);
void createInitialNodes();
std::shared_ptr<Node> createRankGroupNode(unsigned int rank) const;
static QString getLabel(LineType type);
static QString getLabel(unsigned int rank);
static QString getLabel(unsigned int rank, unsigned int group, unsigned int bank);
static CommandBusType getCommandBusType(const GeneralInfo &generalInfo);
static constexpr auto TRACELINE_MIMETYPE = "application/x-tracelinedata";
QItemSelectionModel *const internalSelectionModel;
std::shared_ptr<Node> rootNode;
const unsigned int numberOfRanks;
const unsigned int groupsPerRank;
const unsigned int banksPerGroup;
const unsigned int banksPerRank;
const CommandBusType commandBusType;
};
class AvailableTracePlotLineModel : public AbstractTracePlotLineModel
{
Q_OBJECT
public:
explicit AvailableTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr);
public Q_SLOTS:
void itemsDoubleClicked(const QModelIndex &index);
Q_SIGNALS:
void returnPressed(const QModelIndexList &indexes);
protected:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
bool eventFilter(QObject *object, QEvent *event) override;
};
class SelectedTracePlotLineModel : public AbstractTracePlotLineModel
{
Q_OBJECT
public:
explicit SelectedTracePlotLineModel(const GeneralInfo &generalInfo, QObject *parent = nullptr);
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
void recreateCollapseButtons(TracePlot *tracePlot, CustomLabelScaleDraw *customLabelScaleDraw);
std::shared_ptr<Node> getClonedRootNode();
void setRootNode(std::shared_ptr<Node> 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<QPushButton *> 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<std::shared_ptr<TracePlotLine>> &getTracePlotLines()
{
return entries;
}
public Q_SLOTS:
void updateModel();
Q_SIGNALS:
void modelChanged();
private:
SelectedTracePlotLineModel *selectedModel;
std::vector<std::shared_ptr<TracePlotLine>> entries;
};
#endif // TRACEPLOTLINEMODEL_H

View File

@@ -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()

View File

@@ -33,10 +33,14 @@
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef MARKERPLOTITEM_H
#define MARKERPLOTITEM_H
#include "businessObjects/tracetime.h"
#include <QColor>
#include <qwt_plot_item.h>

View File

@@ -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<TracePlotLineVector> tracePlotLines,
std::shared_ptr<TracePlotLineCache> tracePlotLineCache)
{
this->tracePlotLines = tracePlotLines;
this->tracePlotLineCache = tracePlotLineCache;
}
void TraceDrawingProperties::init(std::shared_ptr<TracePlotLineVector> tracePlotLines,
std::shared_ptr<TracePlotLineCache> 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<TraceSelectorTreeItem *>(treeWidget->topLevelItem(i));
if (currentTreeItem->type == TraceSelectorTreeItem::Type::RequestLineItem)
tracePlotLines->push_back(std::make_shared<TracePlotRequestLine>());
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::ResponseLineItem)
tracePlotLines->push_back(std::make_shared<TracePlotResponseLine>());
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::CommandBusLineItem)
tracePlotLines->push_back(std::make_shared<TracePlotCommandBusLine>());
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::DataBusLineItem)
tracePlotLines->push_back(std::make_shared<TracePlotDataBusLine>());
else if (currentTreeItem->type == TraceSelectorTreeItem::Type::BankLineItem)
tracePlotLines->push_back(std::make_shared<TracePlotBankLine>(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<TracePlotFirstRankLine> firstRankLine;
for (unsigned int group = groupsPerRank; group--;)
{
for (unsigned int bank = banksPerGroup; bank--;)
{
std::shared_ptr<TracePlotBankLine> line;
if (bank == banksPerGroup - 1 && group == groupsPerRank - 1)
{
firstRankLine = createFirstRankLine(rank, group, bank);
line = firstRankLine;
}
else
{
line = std::make_shared<TracePlotBankLine>(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<TracePlotBankLine>(*it);
auto firstRankLine = std::dynamic_pointer_cast<TracePlotFirstRankLine>(*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<TracePlotFirstRankLine> TraceDrawingProperties::createFirstRankLine(unsigned int rank, unsigned int group,
unsigned int bank) const
{
auto firstRankLine = std::make_shared<TracePlotFirstRankLine>(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<TracePlotFirstRankLine>(line))
{
if ((!firstRankLine->isCollapsed() && collapseAction == CollapseAction::CollapseAllRanks)
|| (firstRankLine->isCollapsed() && collapseAction == CollapseAction::ExpandAllRanks))
{
Q_EMIT firstRankLine->collapseRequested();
}
}
}
emit labelsUpdated();
}
std::shared_ptr<QHash<int, QString>> TraceDrawingProperties::getLabels() const
@@ -199,104 +83,5 @@ std::shared_ptr<QHash<int, QString>> 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<TracePlotFirstRankLine>(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<TracePlotLine> line)
{ return std::static_pointer_cast<TracePlotBankLine>(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();
}

View File

@@ -40,17 +40,13 @@
#ifndef TRACECOLLECTIONDRAWINGPROPERTIES_H
#define TRACECOLLECTIONDRAWINGPROPERTIES_H
#include <QObject>
#include <QString>
#include <QColor>
#include <map>
#include <QHash>
#include <QTreeWidget>
#include <tuple>
#include "businessObjects/traceplotlinemodel.h"
#include "tracedrawing.h"
#include "util/traceplotline.h"
#include "util/togglecollapsedaction.h"
#include "traceselector.h"
#include <QAbstractProxyModel>
#include <QColor>
#include <QHash>
#include <QString>
#include <map>
enum class ColorGrouping
{
@@ -60,10 +56,7 @@ enum class ColorGrouping
AlphaTransaction
};
class TracePlot;
class TracePlotLineCache;
using TracePlotLineVector = std::vector<std::shared_ptr<TracePlotLine>>;
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<TracePlotLineVector> tracePlotLines,
std::shared_ptr<TracePlotLineCache> tracePlotLineCache);
void init(std::shared_ptr<TracePlotLineVector> tracePlotLines,
std::shared_ptr<TracePlotLineCache> 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<std::shared_ptr<TracePlotLineDataSource::TracePlotLine>> &getTracePlotLines() const
{
return tracePlotLineDataSource->getTracePlotLines();
}
std::shared_ptr<QHash<int, QString>> 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<TracePlotFirstRankLine> createFirstRankLine(unsigned int rank, unsigned int group,
unsigned int bank) const;
std::shared_ptr<QHash<int, QString>> labels = std::make_shared<QHash<int, QString>>();
std::shared_ptr<TracePlotLineVector> tracePlotLines;
std::shared_ptr<TracePlotLineCache> tracePlotLineCache;
TracePlot *tracePlot = nullptr;
TracePlotLineDataSource *tracePlotLineDataSource;
};
#endif // TRACECOLLECTIONDRAWINGPROPERTIES_H

View File

@@ -38,7 +38,6 @@
*/
#include "tracenavigator.h"
#include "util/traceplotlinecache.h"
#include "vector"
#include "businessObjects/commentmodel.h"
#include <QInputDialog>
@@ -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<TracePlotLineCache>(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<TracePlotLineVector> TraceNavigator::getTracePlotLines()
{
return tracePlotLines;
}
std::shared_ptr<TracePlotLineCache> TraceNavigator::getTracePlotLineCache()
{
return tracePlotLineCache;
}
const CommentModel *TraceNavigator::getCommentModel() const
{
return commentModel;

View File

@@ -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<TracePlotLineVector> getTracePlotLines();
std::shared_ptr<TracePlotLineCache> getTracePlotLineCache();
const CommentModel *getCommentModel() const;
bool existChangesToCommit() const;
@@ -139,9 +134,6 @@ private:
void getCommentsFromDB();
bool changesToCommitExist;
std::shared_ptr<TracePlotLineVector> tracePlotLines = std::make_shared<TracePlotLineVector>();
std::shared_ptr<TracePlotLineCache> tracePlotLineCache;
};
#endif // TRACENAVIGATOR_H

View File

@@ -37,33 +37,30 @@
* Iron Prando da Silva
*/
#include <qwt_plot_grid.h>
#include <QWheelEvent>
#include <QMessageBox>
#include <QMouseEvent>
#include <iostream>
#include <QMenu>
#include <cmath>
#include <QInputDialog>
#include <QKeySequence>
#include <QFileInfo>
#include <QPushButton>
#include <qfiledialog.h>
#include <iostream>
#include <qwt_plot_renderer.h>
#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 <QFileInfo>
#include <QInputDialog>
#include <QItemSelectionModel>
#include <QKeySequence>
#include <QMenu>
#include <QMessageBox>
#include <QMouseEvent>
#include <QPushButton>
#include <QWheelEvent>
#include <cmath>
#include <iostream>
#include <qfiledialog.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_renderer.h>
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<AbstractTracePlotLineModel::LineType>(
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<AbstractTracePlotLineModel::LineType>(
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<QModelIndex> 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);
}
}

View File

@@ -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 <qwt_plot.h>
#include <QString>
#include <QColor>
@@ -49,31 +56,25 @@
#include <QScrollBar>
#include <QPushButton>
#include <qwt_plot_zoneitem.h>
#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
*

View File

@@ -36,12 +36,13 @@
* Derek Christ
*/
#include <qwt_plot_zoneitem.h>
#include <QWheelEvent>
#include <QMouseEvent>
#include "tracescroller.h"
#include "traceplotitem.h"
#include "util/engineeringScaleDraw.h"
#include <QItemSelectionModel>
#include <QMouseEvent>
#include <QWheelEvent>
#include <qwt_plot_zoneitem.h>
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();
}

View File

@@ -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:

View File

@@ -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 <QTreeWidget>
#include <QTreeWidgetItem>
#include <QTreeView>
#include <QVBoxLayout>
#include <QDropEvent>
#include <QLabel>
#include <QMimeData>
QMimeData *TraceAvailableTree::mimeData(const QList<QTreeWidgetItem *> items) const
{
QByteArray traceLineData;
QDataStream dataStream(&traceLineData, QIODevice::WriteOnly);
for (QTreeWidgetItem *item : items)
{
TraceSelectorTreeItem *treeSelectorItem = static_cast<TraceSelectorTreeItem *>(item);
dataStream << static_cast<int>(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<TraceSelectorTreeItem *>(topLevelItem(i));
if (currentItem->isSelected())
{
auto clonedItem = new TraceSelectorTreeItem(*currentItem);
for (int i = 0; i < currentItem->childCount(); i++)
{
auto child = static_cast<TraceSelectorTreeItem *>(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<TraceSelectorTreeItem *>(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<QTreeWidgetItem *> TraceSelectedTree::clonedItems() const
{
std::vector<QTreeWidgetItem *> clonedTopLevelItems;
for (unsigned int i = 0; i < topLevelItemCount(); i++)
{
clonedTopLevelItems.push_back(topLevelItem(i)->clone());
}
return clonedTopLevelItems;
}
void TraceSelectedTree::setItems(const std::vector<QTreeWidgetItem *> &items)
{
for (unsigned int i = topLevelItemCount(); i--;)
takeTopLevelItem(i);
for (auto item : items)
addTopLevelItem(item);
emit itemsChanged();
}
QMimeData *TraceSelectedTree::mimeData(const QList<QTreeWidgetItem *> items) const
{
QByteArray traceLineData;
QDataStream dataStream(&traceLineData, QIODevice::WriteOnly);
for (QTreeWidgetItem *item : items)
{
TraceSelectorTreeItem *treeSelectorItem = static_cast<TraceSelectorTreeItem *>(item);
dataStream << static_cast<int>(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<QTreeWidgetItem *> droppedItems;
while (!dataStream.atEnd())
{
TraceSelectorTreeItem::Type currentType;
int currentTypeNum;
unsigned int currentRank, currentBankGroup, currentBank;
dataStream >> currentTypeNum
>> currentRank
>> currentBankGroup
>> currentBank;
currentType = static_cast<TraceSelectorTreeItem::Type>(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<TraceSelectorTreeItem *>(item);
auto clonedItem = new TraceSelectorTreeItem(*traceSelectorItem);
for (int i = 0; i < traceSelectorItem->childCount(); i++)
{
auto child = static_cast<TraceSelectorTreeItem *>(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<QTreeWidgetItem *> TraceSelector::getTraceSelectorState() const
{
return selectedTree->clonedItems();
}
void TraceSelector::restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &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<TraceSelectorTreeItem *> clonedChildren;
for (unsigned int i = 0; i < childCount(); i++)
{
clonedChildren.push_back(static_cast<TraceSelectorTreeItem *>(child(i)->clone()));
}
for (auto child : clonedChildren)
cloned->addChild(child);
return cloned;
}

View File

@@ -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 <QWidget>
#include <QAbstractItemModel>
#include <QTreeWidget>
#include <memory>
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<QTreeWidgetItem *> 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<QTreeWidgetItem *> clonedItems() const;
void setItems(const std::vector<QTreeWidgetItem *> &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<QTreeWidgetItem *> 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<QTreeWidgetItem *> getTraceSelectorState() const;
void restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &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

View File

@@ -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 <QPushButton>
#include <qwt_plot.h>
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<TracePlotFirstRankLine> 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();
}

View File

@@ -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 <QObject>
#include <QString>
#include <QHash>
#include <memory>
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<TracePlotFirstRankLine> firstRankLine);
TracePlotBankLine(unsigned int rank, unsigned int group, unsigned int bank);
~TracePlotBankLine() = default;
virtual bool isCollapsed() const override;
std::shared_ptr<TracePlotFirstRankLine> getFirstRankLine() const {
return firstRankLine.lock();
}
const unsigned int rank;
const unsigned int group;
const unsigned int bank;
private:
std::weak_ptr<TracePlotFirstRankLine> 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

View File

@@ -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<TracePlotLineVector> 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<std::shared_ptr<TracePlotLine>> commandBusLines;
for (auto line : *tracePlotLines)
{
auto commandBusLine = std::dynamic_pointer_cast<TracePlotCommandBusLine>(line);
if (commandBusLine)
commandBusLines.push_back(commandBusLine);
}
commandBusLinesCache = commandBusLines;
return commandBusLines;
}
TracePlotLineVector TracePlotLineCache::getDataBusLines() const
{
if (dataBusLinesCache.size() != 0)
return dataBusLinesCache;
std::vector<std::shared_ptr<TracePlotLine>> dataBusLines;
for (auto line : *tracePlotLines)
{
auto dataBusLine = std::dynamic_pointer_cast<TracePlotDataBusLine>(line);
if (dataBusLine)
dataBusLines.push_back(dataBusLine);
}
dataBusLinesCache = dataBusLines;
return dataBusLines;
}
TracePlotLineVector TracePlotLineCache::getRequestLines() const
{
if (requestLinesCache.size() != 0)
return requestLinesCache;
std::vector<std::shared_ptr<TracePlotLine>> requestLines;
for (auto line : *tracePlotLines)
{
auto requestLine = std::dynamic_pointer_cast<TracePlotRequestLine>(line);
if (requestLine)
requestLines.push_back(requestLine);
}
requestLinesCache = requestLines;
return requestLines;
}
TracePlotLineVector TracePlotLineCache::getResponseLines() const
{
if (responseLinesCache.size() != 0)
return responseLinesCache;
std::vector<std::shared_ptr<TracePlotLine>> responseLines;
for (auto line : *tracePlotLines)
{
auto responseLine = std::dynamic_pointer_cast<TracePlotResponseLine>(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<std::shared_ptr<TracePlotLine>> firstRankLines;
for (auto line : *tracePlotLines)
{
auto firstRankLine = std::dynamic_pointer_cast<TracePlotFirstRankLine>(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<std::shared_ptr<TracePlotLine>> bankLines;
for (auto line : *tracePlotLines)
{
auto bankLine = std::dynamic_pointer_cast<TracePlotBankLine>(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<int, int> bankLinesTuple {rank, group};
if (bankLinesFromGroupCache.find(bankLinesTuple) != bankLinesFromGroupCache.end())
return bankLinesFromGroupCache[bankLinesTuple];
std::vector<std::shared_ptr<TracePlotLine>> bankLines;
for (auto line : *tracePlotLines)
{
auto bankLine = std::dynamic_pointer_cast<TracePlotBankLine>(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<int, int, int> bankLinesTuple {rank, group, bank};
if (bankLinesCache.find(bankLinesTuple) != bankLinesCache.end())
return bankLinesCache[bankLinesTuple];
std::vector<std::shared_ptr<TracePlotLine>> bankLines;
for (auto line : *tracePlotLines)
{
auto bankLine = std::dynamic_pointer_cast<TracePlotBankLine>(line);
if (bankLine && bankLine->rank == rank && bankLine->group == group && bankLine->bank == bank)
bankLines.push_back(bankLine);
}
bankLinesCache[bankLinesTuple] = bankLines;
return bankLines;
}

View File

@@ -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 <memory>
#include <vector>
#include <map>
class TracePlotLine;
using TracePlotLineVector = std::vector<std::shared_ptr<TracePlotLine>>;
struct TracePlotLineCache
{
TracePlotLineCache(std::shared_ptr<TracePlotLineVector> 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<TracePlotLineVector> tracePlotLines;
unsigned int numberOfRanks;
unsigned int groupsPerRank;
unsigned int banksPerGroup;
mutable std::map<std::tuple<int, int, int>, std::vector<std::shared_ptr<TracePlotLine>>> bankLinesCache;
mutable std::map<std::tuple<int, int>, std::vector<std::shared_ptr<TracePlotLine>>> bankLinesFromGroupCache;
mutable std::map<int, std::vector<std::shared_ptr<TracePlotLine>>> bankLinesFromRankCache;
mutable std::map<int, std::vector<std::shared_ptr<TracePlotLine>>> firstRankLinesCache;
mutable std::vector<std::shared_ptr<TracePlotLine>> requestLinesCache;
mutable std::vector<std::shared_ptr<TracePlotLine>> responseLinesCache;
mutable std::vector<std::shared_ptr<TracePlotLine>> commandBusLinesCache;
mutable std::vector<std::shared_ptr<TracePlotLine>> dataBusLinesCache;
};
#endif // TRACELOTLINECACHE_H

View File

@@ -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() + ")"

View File

@@ -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);

View File

@@ -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<TraceSelector *>(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<QTreeWidgetItem *> TraceFileTab::saveTraceSelectorState() const
std::shared_ptr<AbstractTracePlotLineModel::Node> TraceFileTab::saveTraceSelectorState() const
{
TraceSelector *selector = static_cast<TraceSelector *>(ui->tabCustomizePlot);
return selector->getTraceSelectorState();
return selectedRowsModel->getClonedRootNode();
}
void TraceFileTab::restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &items)
void TraceFileTab::restoreTraceSelectorState(std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode)
{
TraceSelector *selector = static_cast<TraceSelector *>(ui->tabCustomizePlot);
selector->restoreTraceSelectorState(items);
selectedRowsModel->setRootNode(std::move(rootNode));
}
class ItemDelegate: public QItemDelegate

View File

@@ -40,15 +40,19 @@
#ifndef TRACEFILETAB_H
#define TRACEFILETAB_H
#include <QWidget>
#include <QString>
#include <QFileSystemWatcher>
#include "businessObjects/traceplotlinemodel.h"
#include "presentation/tracenavigator.h"
#include "presentation/traceplot.h"
#include "presentation/tracescroller.h"
#include "businessObjects/configmodels.h"
#include <QFileSystemWatcher>
#include <QString>
#include <QTreeWidget>
#include <QWidget>
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<QTreeWidgetItem *> saveTraceSelectorState() const;
void restoreTraceSelectorState(const std::vector<QTreeWidgetItem *> &items);
std::shared_ptr<AbstractTracePlotLineModel::Node> saveTraceSelectorState() const;
void restoreTraceSelectorState(std::shared_ptr<AbstractTracePlotLineModel::Node> 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;

View File

@@ -197,10 +197,69 @@
</item>
</layout>
</widget>
<widget class="TraceSelector" name="tabCustomizePlot">
<widget class="QWidget" name="tabCustomizePlot">
<attribute name="title">
<string>Customize Plot</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="customizePlotDescription">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;To customize the displayed rows double click or drag and drop items from the upper list to the lower list.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="availableTreeView">
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="selectedTreeView">
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabDepInfos">
@@ -377,6 +436,7 @@
<class>QwtPlot</class>
<extends>QFrame</extends>
<header>qwt_plot.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TracePlot</class>
@@ -393,12 +453,6 @@
<extends>QTreeWidget</extends>
<header>presentation/selectedtransactiontreewidget.h</header>
</customwidget>
<customwidget>
<class>TraceSelector</class>
<extends>QWidget</extends>
<header>presentation/traceselector.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>