diff --git a/DRAMSys/traceAnalyzer/CMakeLists.txt b/DRAMSys/traceAnalyzer/CMakeLists.txt index 543bb2e2..28e71f52 100644 --- a/DRAMSys/traceAnalyzer/CMakeLists.txt +++ b/DRAMSys/traceAnalyzer/CMakeLists.txt @@ -32,6 +32,7 @@ # Matthias Jung # Lukas Steiner # Derek Christ +# Iron Prando da Silva cmake_minimum_required(VERSION 3.12) @@ -90,6 +91,8 @@ add_executable(TraceAnalyzer businessObjects/tracetestresults.cpp presentation/tracemetrictreewidget.cpp businessObjects/phases/phase.cpp + businessObjects/phases/phasedependency.cpp + businessObjects/phases/dependencyinfos.cpp presentation/tracedrawingproperties.cpp presentation/util/traceplotline.cpp presentation/util/traceplotlinecache.cpp diff --git a/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp b/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp index 94fe6ddd..149ccf8d 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/configmodels.cpp @@ -31,6 +31,7 @@ * * Authors: * Derek Christ + * Iron Prando da Silva */ #include "configmodels.h" @@ -282,3 +283,142 @@ QModelIndex MemSpecModel::parent(const QModelIndex &index) const return createIndex(parentNode->getRow(), 0, const_cast(parentNode)); } + +DependencyInfosModel::DependencyInfosModel(TraceDB &traceFile, QObject *parent) : QAbstractItemModel(parent) +{ + mDepInfosDepType = traceFile.getDependencyInfos(DependencyInfos::Type::DependencyType); + mDepInfosTimeDep = traceFile.getDependencyInfos(DependencyInfos::Type::TimeDependency); + mDepInfosDelPhase = traceFile.getDependencyInfos(DependencyInfos::Type::DelayedPhase); + mDepInfosDepPhase = traceFile.getDependencyInfos(DependencyInfos::Type::DependencyPhase); + + if (traceFile.checkDependencyTableExists()) + { + parseInfos(); + } +} + +int DependencyInfosModel::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::unique_ptr &node) { return node.get() == this; }); + + Q_ASSERT(siblingsIt != siblings.end()); + + return std::distance(siblings.begin(), siblingsIt); +} + +void DependencyInfosModel::parseInfos() +{ + + std::vector> infos = {{"Dependency Granularity", mDepInfosDepType}, + {"Time Dependencies", mDepInfosTimeDep}, + {"Delayed Phases", mDepInfosDelPhase}, + {"Dependency Phases", mDepInfosDepPhase}}; + + for (auto pair : infos) + { + std::unique_ptr node = std::unique_ptr(new Node({pair.first, ""}, rootNode.get())); + + for (auto v : pair.second.getInfos()) + { + QString value = QString::number(v.value) + " %"; + node->children.push_back(std::move(std::unique_ptr(new Node({v.id, value}, node.get())))); + } + + rootNode->children.push_back(std::move(node)); + } +} + +int DependencyInfosModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + + const Node *parentNode; + + if (!parent.isValid()) + parentNode = rootNode.get(); + else + parentNode = static_cast(parent.internalPointer()); + + return parentNode->childCount(); +} + +int DependencyInfosModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return 2; +} + +QVariant DependencyInfosModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role != Qt::DisplayRole && role != Qt::ToolTipRole) + return QVariant(); + + auto *node = static_cast(index.internalPointer()); + + if (index.column() == 0) + return QVariant(node->data.first); + else + return QVariant(node->data.second); +} + +QVariant DependencyInfosModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + { + switch (section) + { + case 0: + return "Field"; + case 1: + return "Percentage"; + default: + break; + } + } + + return QVariant(); +} + +QModelIndex DependencyInfosModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + const Node *parentNode; + + if (!parent.isValid()) + parentNode = rootNode.get(); + else + parentNode = static_cast(parent.internalPointer()); + + const Node *node = parentNode->children[row].get(); + + return createIndex(row, column, const_cast(node)); +} + +QModelIndex DependencyInfosModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + const Node *childNode = static_cast(index.internalPointer()); + const Node *parentNode = childNode->parent; + + if (!parentNode) + return QModelIndex(); + + return createIndex(parentNode->getRow(), 0, const_cast(parentNode)); +} diff --git a/DRAMSys/traceAnalyzer/businessObjects/configmodels.h b/DRAMSys/traceAnalyzer/businessObjects/configmodels.h index f2a77a87..7408db5c 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/configmodels.h +++ b/DRAMSys/traceAnalyzer/businessObjects/configmodels.h @@ -31,12 +31,14 @@ * * Authors: * Derek Christ + * Iron Prando da Silva */ #ifndef CONFIGMODELS_H #define CONFIGMODELS_H #include "../data/tracedb.h" +#include "phases/dependencyinfos.h" #include #include @@ -122,4 +124,59 @@ private: std::unique_ptr rootNode = std::unique_ptr(new Node); }; +class DependencyInfosModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit DependencyInfosModel(TraceDB &traceFile, QObject *parent = nullptr); + ~DependencyInfosModel() + { + } + +protected: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex parent(const QModelIndex &index) const override; + +private: + DependencyInfos mDepInfosDepType; + DependencyInfos mDepInfosTimeDep; + DependencyInfos mDepInfosDelPhase; + DependencyInfos mDepInfosDepPhase; + + void parseInfos(); + struct Node + { + using NodeData = std::pair; + + Node() + { + } + 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(); + } + + NodeData data; + + const Node *parent = nullptr; + std::vector> children; + }; + + std::unique_ptr rootNode = std::unique_ptr(new Node); +}; + #endif // CONFIGMODELS_H diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/dependencyinfos.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/dependencyinfos.cpp new file mode 100644 index 00000000..04eb74bd --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/dependencyinfos.cpp @@ -0,0 +1,54 @@ +/* + * 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: + * Iron Prando da Silva + */ + +#include "dependencyinfos.h" + +DependencyInfos::DependencyInfos(Type type) : mType(type) +{ +} + +DependencyInfos::DependencyInfos() +{ + mType = DependencyType; +} + +DependencyInfos::~DependencyInfos() +{ +} + +void DependencyInfos::addInfo(DependencyInfo info) +{ + mInfos.push_back(info); +} diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/dependencyinfos.h b/DRAMSys/traceAnalyzer/businessObjects/phases/dependencyinfos.h new file mode 100644 index 00000000..2fda0e83 --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/dependencyinfos.h @@ -0,0 +1,82 @@ +/* + * 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: + * Iron Prando da Silva + */ + +#pragma once + +#include + +#include + +struct DependencyInfo +{ + QString id; + float value; +}; + +class DependencyInfos +{ +public: + enum Type + { + DependencyType, + TimeDependency, + DelayedPhase, + DependencyPhase + }; + +public: + DependencyInfos(Type); + DependencyInfos(); + ~DependencyInfos(); + + void setType(Type type) + { + mType = type; + } + void addInfo(DependencyInfo); + + const std::vector &getInfos() const + { + return mInfos; + } + size_t size() const + { + return mInfos.size(); + } + +private: + Type mType; + std::vector mInfos; +}; diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp index 4f89bf0f..15ec782a 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #include "phase.h" @@ -68,8 +69,22 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, for (auto line : getTracePlotLines(drawingProperties)) { if (!line->isCollapsed()) + { drawPhaseSymbol(span.Begin(), span.End(), line->getYVal(), drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap); + + if (getGranularity() == Granularity::Bankwise) + { + + 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); + } + } + } } for (Timespan span : spansOnCommandBus) @@ -116,6 +131,52 @@ void Phase::drawPhaseSymbol(traceTime begin, traceTime end, double y, static_cast(yVal + symbolHeight / 2)), TextPositioning::bottomRight); } +void Phase::drawPhaseDependencies(traceTime begin, traceTime end, double y, + const TraceDrawingProperties &drawingProperties, QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap) const +{ + QPen pen; + pen.setWidth(2); + + painter->save(); + painter->setPen(pen); + painter->setRenderHint(QPainter::Antialiasing); + + double yVal = yMap.transform(y); + double symbolHeight = yMap.transform(0) - yMap.transform(hexagonHeight); + + traceTime offset = (begin == end) ? static_cast(0.05 * clk) : 0; + + size_t invisibleDeps = 0; + + QPoint depLineTo(static_cast(xMap.transform(begin /* + (end + offset - begin)/4*/)), static_cast(yVal)); + + for (auto dep : mDependencies) + { + bool visible = false; + if (dep->isVisible()) + { + if (!dep->draw(depLineTo, drawingProperties, painter, xMap, yMap)) + { + invisibleDeps += 1; + } + } + else + { + invisibleDeps += 1; + } + } + + if (invisibleDeps > 0) + { + QPoint invisibleDepsPoint(static_cast(xMap.transform(begin + (end + offset - begin) / 2)), + static_cast(yVal + 0.1 * symbolHeight)); + drawText(painter, QString::number(invisibleDeps), invisibleDepsPoint, TextPositioning::centerCenter); + } + + painter->restore(); +} + QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const { switch (drawingProperties.colorGrouping) { @@ -123,8 +184,11 @@ QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const return getPhaseColor(); break; case ColorGrouping::Thread: - return ColorGenerator::getColor(static_cast - (transaction.lock()->thread)); + return ColorGenerator::getColor(static_cast(transaction.lock()->thread)); + break; + case ColorGrouping::AlphaTransaction: + return ColorGenerator::getAlphaColored(transaction.lock()->id); + break; case ColorGrouping::Transaction: default: @@ -197,3 +261,8 @@ std::vector> Phase::getTracePlotLines(const Trace % drawingProperties.banksPerGroup); } } + +void Phase::addDependency(std::shared_ptr dependency) +{ + mDependencies.push_back(dependency); +} diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index df6185aa..feb7b99a 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -34,18 +34,20 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #ifndef BANKPHASE_H #define BANKPHASE_H -#include "presentation/util/colorgenerator.h" -#include "presentation/tracedrawingproperties.h" +#include "businessObjects/phases/phasedependency.h" #include "businessObjects/timespan.h" -#include +#include "presentation/tracedrawingproperties.h" +#include "presentation/util/colorgenerator.h" #include +#include +#include #include #include -#include typedef unsigned int ID; //enum TextPositioning; @@ -75,6 +77,8 @@ public: } virtual QString Name() const = 0; + void addDependency(std::shared_ptr dependency); + protected: ID id; Timespan span; @@ -82,6 +86,8 @@ protected: std::weak_ptr transaction; std::vector spansOnCommandBus; std::shared_ptr spanOnDataBus; + std::vector> mDependencies; + double hexagonHeight; TextPositioning captionPosition; @@ -94,6 +100,9 @@ protected: virtual void drawPhaseSymbol(traceTime begin, traceTime end, double y, bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap) const; + virtual void drawPhaseDependencies(traceTime begin, traceTime end, double y, + const TraceDrawingProperties &drawingProperties, QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap) const; virtual std::vector> getTracePlotLines(const TraceDrawingProperties &drawingProperties) const; @@ -103,6 +112,8 @@ protected: { return Granularity::Bankwise; } + + friend class PhaseDependency; }; class REQ : public Phase diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.cpp new file mode 100644 index 00000000..e76d0f8e --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.cpp @@ -0,0 +1,132 @@ +/* + * 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: + * Iron Prando da Silva + */ + +#include "phasedependency.h" +#include "phase.h" +#include + +PhaseDependency::PhaseDependency(DependencyType type, QString timeDependency, std::shared_ptr dependency) +{ + mType = type; + mTimeDependency = timeDependency; + mDependency = dependency; +} + +PhaseDependency::PhaseDependency(DependencyType type, QString timeDependency) +{ + mType = type; + mTimeDependency = timeDependency; + mDependency = nullptr; + mIsInvisible = true; +} + +PhaseDependency::~PhaseDependency() +{ +} + +bool PhaseDependency::draw(QPoint &end, const TraceDrawingProperties &drawingProperties, QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap) +{ + if (mIsInvisible) + return false; + + traceTime depBegin = mDependency->span.Begin(); + traceTime depEnd = mDependency->span.End(); + + if (xMap.transform(depEnd) < 0) + return false; + + bool drawn = false; + for (auto line : mDependency->getTracePlotLines(drawingProperties)) + { + if (!line->isCollapsed()) + { + mDraw(end, line->getYVal(), drawingProperties, painter, xMap, yMap); + drawn = true; + } + } + + return drawn; +} + +void PhaseDependency::mDraw(QPoint &end, double depY, const TraceDrawingProperties &drawingProperties, + QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap) +{ + traceTime depBegin = mDependency->span.Begin(); + traceTime depEnd = mDependency->span.End(); + + traceTime depOffset = (depBegin == depEnd) ? static_cast(0.05 * mDependency->clk) : 0; + + double depYVal = yMap.transform(depY); + double depSymbolHeight = yMap.transform(0) - yMap.transform(mDependency->hexagonHeight); + QPoint depLineFrom(static_cast(xMap.transform(depBegin /* + (depEnd + depOffset - depBegin)/4*/)), + static_cast(depYVal)); + + QLineF line(depLineFrom, end); + double angle = std::atan2(-line.dy(), line.dx()); + + qreal arrowSize = 10; + QPointF arrowP1 = line.p2() - QPointF(sin(angle + M_PI / 3) * arrowSize, cos(angle + M_PI / 3) * arrowSize); + QPointF arrowP2 = + line.p2() - QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize, cos(angle + M_PI - M_PI / 3) * arrowSize); + QPolygonF arrowHead; + arrowHead << line.p2() << arrowP1 << arrowP2; + + QColor color = mDependency->getColor(drawingProperties); + painter->setBrush(QBrush(color, mDependency->getBrushStyle())); + + painter->drawLine(line); + painter->drawPolygon(arrowHead); + + if (drawingProperties.drawDependenciesOption.text == DependencyTextOption::Enabled) + { + QPoint textPosition(line.x1() + (line.x2() - line.x1()) / 2, line.y1() + (line.y2() - line.y1()) / 2); + auto alignment = TextPositioning::topRight; + + if (textPosition.y() == line.y1()) + { + alignment = TextPositioning::topCenter; + } + else if (textPosition.x() == line.x1()) + { + if (line.y1() > line.y2()) + { + alignment = TextPositioning::bottomRight; + } + } + + drawText(painter, mTimeDependency, textPosition, alignment); + } +} \ No newline at end of file diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.h new file mode 100644 index 00000000..41be1c1e --- /dev/null +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasedependency.h @@ -0,0 +1,80 @@ +/* + * 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: + * Iron Prando da Silva + */ + +#pragma once + +#include "businessObjects/timespan.h" +#include "presentation/tracedrawingproperties.h" + +#include +#include +#include +#include +#include + +class Phase; + +enum DependencyType +{ + Bank, + Rank, + InterRank +}; + +class PhaseDependency +{ +public: + PhaseDependency(DependencyType type, QString timeDependency, std::shared_ptr dependency); + PhaseDependency(DependencyType type, QString timeDependency); + ~PhaseDependency(); + + bool isVisible() + { + return !mIsInvisible; + } + + bool draw(QPoint &end, const TraceDrawingProperties &drawingProperties, QPainter *painter, const QwtScaleMap &xMap, + const QwtScaleMap &yMap); + +protected: + DependencyType mType; + QString mTimeDependency; + std::shared_ptr mDependency; + + bool mIsInvisible = false; + + void mDraw(QPoint &end, double depY, const TraceDrawingProperties &drawingProperties, QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap); +}; diff --git a/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp b/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp index 87a46f99..11f188f7 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp @@ -33,12 +33,15 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Iron Prando da Silva */ #include "transaction.h" using namespace std; +unsigned int Transaction::mSNumTransactions = 0; + Transaction::Transaction(ID id, unsigned int address, unsigned int burstlength, unsigned int thread, unsigned int channel, unsigned int rank, unsigned int bankgroup, unsigned int bank, unsigned int row, unsigned int column, diff --git a/DRAMSys/traceAnalyzer/businessObjects/transaction.h b/DRAMSys/traceAnalyzer/businessObjects/transaction.h index ef489083..d2c97990 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/transaction.h +++ b/DRAMSys/traceAnalyzer/businessObjects/transaction.h @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Iron Prando da Silva */ #ifndef TRANSACTION_H @@ -74,6 +75,19 @@ public: { return phases; } + +public: + static void setNumTransactions(const unsigned int numTransactions) + { + mSNumTransactions = numTransactions; + } + static unsigned int getNumTransactions(const unsigned int numTransactions) + { + return mSNumTransactions; + } + +private: + static unsigned int mSNumTransactions; }; #endif // TRANSACTION_H diff --git a/DRAMSys/traceAnalyzer/data/QueryTexts.h b/DRAMSys/traceAnalyzer/data/QueryTexts.h index 4101d106..361ec855 100644 --- a/DRAMSys/traceAnalyzer/data/QueryTexts.h +++ b/DRAMSys/traceAnalyzer/data/QueryTexts.h @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Iron Prando da Silva */ #ifndef QUERYTEXTS_H @@ -42,6 +43,9 @@ struct TransactionQueryTexts { QString queryHead; QString selectTransactionsByTimespan, selectTransactionById; + QString checkDependenciesExist, selectDependenciesByTimespan; + QString selectDependencyTypePercentages, selectTimeDependencyPercentages, selectDelayedPhasePercentages, + selectDependencyPhasePercentages; TransactionQueryTexts() { @@ -53,6 +57,74 @@ struct TransactionQueryTexts { " WHERE Ranges.end >= :begin AND Ranges.begin <= :end"; selectTransactionById = queryHead + " WHERE Transactions.ID = :id"; + checkDependenciesExist = "SELECT CASE WHEN 0 < (SELECT count(*) FROM sqlite_master WHERE type = 'table' AND " + "name = 'DirectDependencies') THEN 1 ELSE 0 END AS result"; + selectDependenciesByTimespan = + "WITH timespanTransactions AS (" + selectTransactionsByTimespan + + ") SELECT * from DirectDependencies WHERE DelayedPhaseID IN (" + " SELECT DirectDependencies.DelayedPhaseID FROM DirectDependencies JOIN timespanTransactions " + " ON DirectDependencies.DelayedPhaseID = timespanTransactions.PhaseID )"; + + // For some reason I could not use a parameter for these below + selectDependencyTypePercentages = + "WITH TotalDeps (total) AS ( " + "SELECT COUNT(*) FROM DirectDependencies " + "), " + "DependencyTypeDeps (param, ndeps) AS ( " + "SELECT " + "DependencyType, " + "COUNT(*) " + "FROM DirectDependencies " + "GROUP BY \"DependencyType\" " + ") " + "SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage " + "FROM DependencyTypeDeps " + "ORDER BY percentage DESC "; + + selectTimeDependencyPercentages = + "WITH TotalDeps (total) AS ( " + "SELECT COUNT(*) FROM DirectDependencies " + "), " + "DependencyTypeDeps (param, ndeps) AS ( " + "SELECT " + "TimeDependency, " + "COUNT(*) " + "FROM DirectDependencies " + "GROUP BY \"TimeDependency\" " + ") " + "SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage " + "FROM DependencyTypeDeps " + "ORDER BY percentage DESC "; + + selectDelayedPhasePercentages = + "WITH TotalDeps (total) AS ( " + "SELECT COUNT(*) FROM DirectDependencies " + "), " + "DependencyTypeDeps (param, ndeps) AS ( " + "SELECT " + "DelayedPhaseName, " + "COUNT(*) " + "FROM DirectDependencies " + "GROUP BY \"DelayedPhaseName\" " + ") " + "SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage " + "FROM DependencyTypeDeps " + "ORDER BY percentage DESC "; + + selectDependencyPhasePercentages = + "WITH TotalDeps (total) AS ( " + "SELECT COUNT(*) FROM DirectDependencies " + "), " + "DependencyTypeDeps (param, ndeps) AS ( " + "SELECT " + "DependencyPhaseName, " + "COUNT(*) " + "FROM DirectDependencies " + "GROUP BY \"DependencyPhaseName\" " + ") " + "SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage " + "FROM DependencyTypeDeps " + "ORDER BY percentage DESC "; } }; diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index a30c3c77..98fa0978 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #include @@ -85,11 +86,24 @@ void TraceDB::prepareQueries() selectDebugMessagesByTimespan.prepare("SELECT time, Message FROM DebugMessages WHERE :begin <= time AND time <= :end "); selectDebugMessagesByTimespanWithLimit = QSqlQuery(database); selectDebugMessagesByTimespanWithLimit.prepare("SELECT time, Message FROM DebugMessages WHERE :begin <= time AND time <= :end LIMIT :limit"); + + checkDependenciesExist = QSqlQuery(database); + checkDependenciesExist.prepare(queryTexts.checkDependenciesExist); + selectDependenciesByTimespan = QSqlQuery(database); + selectDependenciesByTimespan.prepare(queryTexts.selectDependenciesByTimespan); + + selectDependencyTypePercentages = QSqlQuery(database); + selectDependencyTypePercentages.prepare(queryTexts.selectDependencyTypePercentages); + selectTimeDependencyPercentages = QSqlQuery(database); + selectTimeDependencyPercentages.prepare(queryTexts.selectTimeDependencyPercentages); + selectDelayedPhasePercentages = QSqlQuery(database); + selectDelayedPhasePercentages.prepare(queryTexts.selectDelayedPhasePercentages); + selectDependencyPhasePercentages = QSqlQuery(database); + selectDependencyPhasePercentages.prepare(queryTexts.selectDependencyPhasePercentages); } void TraceDB::updateComments(const std::vector &comments) { - QSqlQuery query(database); query.prepare("DELETE FROM Comments"); executeQuery(query); @@ -127,15 +141,33 @@ vector> TraceDB::getTransactionsWithCustomQuery( return parseTransactionsFromQuery(query); } -vector> TraceDB::getTransactionsInTimespan( - const Timespan &span) +vector> TraceDB::getTransactionsInTimespan(const Timespan &span, bool updateVisiblePhases) { selectTransactionsByTimespan.bindValue(":begin", span.Begin()); selectTransactionsByTimespan.bindValue(":end", span.End()); executeQuery(selectTransactionsByTimespan); - return parseTransactionsFromQuery(selectTransactionsByTimespan); + return parseTransactionsFromQuery(selectTransactionsByTimespan, updateVisiblePhases); } +bool TraceDB::checkDependencyTableExists() +{ + executeQuery(checkDependenciesExist); + if (checkDependenciesExist.next() && checkDependenciesExist.value(0).toInt() == 1) + return true; + + return false; +} + +void TraceDB::updateDependenciesInTimespan(const Timespan &span) +{ + if (checkDependencyTableExists()) + { + selectDependenciesByTimespan.bindValue(":begin", span.Begin()); + selectDependenciesByTimespan.bindValue(":end", span.End()); + executeQuery(selectDependenciesByTimespan); + mUpdateDependenciesFromQuery(selectDependenciesByTimespan); + } +} //TODO Remove exception shared_ptr TraceDB::getTransactionByID(ID id) @@ -359,6 +391,37 @@ vector TraceDB::getDebugMessagesInTimespan(const Timespan return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit); } +DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType) +{ + DependencyInfos dummy; + executeQuery(checkDependenciesExist); + if (!checkDependenciesExist.next() || checkDependenciesExist.value(0).toInt() != 1) + { + return dummy; + } + + switch (infoType) + { + case DependencyInfos::Type::DependencyType: + executeQuery(selectDependencyTypePercentages); + return parseDependencyInfos(selectDependencyTypePercentages, infoType); + + case DependencyInfos::Type::TimeDependency: + executeQuery(selectTimeDependencyPercentages); + return parseDependencyInfos(selectTimeDependencyPercentages, infoType); + + case DependencyInfos::Type::DelayedPhase: + executeQuery(selectDelayedPhasePercentages); + return parseDependencyInfos(selectDelayedPhasePercentages, infoType); + + case DependencyInfos::Type::DependencyPhase: + executeQuery(selectDependencyPhasePercentages); + return parseDependencyInfos(selectDependencyPhasePercentages, infoType); + } + + return dummy; +} + QSqlDatabase TraceDB::getDatabase() const { return database; @@ -380,9 +443,13 @@ shared_ptr TraceDB::parseTransactionFromQuery(QSqlQuery &query) return shared_ptr(); } -vector> TraceDB::parseTransactionsFromQuery( - QSqlQuery &query) +vector> TraceDB::parseTransactionsFromQuery(QSqlQuery &query, bool updateVisiblePhases) { + if (updateVisiblePhases) + { + _visiblePhases.clear(); + } + vector> result; bool firstIteration = true; @@ -416,12 +483,64 @@ vector> TraceDB::parseTransactionsFromQuery( unsigned int phaseID = query.value(14).toInt(); QString phaseName = query.value(15).toString(); Timespan span(query.value(16).toLongLong(), query.value(17).toLongLong()); - result.at(result.size() - 1)->addPhase(PhaseFactory::CreatePhase(phaseID, - phaseName, span, result.at(result.size() - 1), *this)); + auto phase = PhaseFactory::CreatePhase(phaseID, phaseName, span, result.at(result.size() - 1), *this); + result.at(result.size() - 1)->addPhase(phase); + + if (updateVisiblePhases) + { + _visiblePhases[phaseID] = phase; + } } return result; } +void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery &query) +{ + DependencyType type; + while (query.next()) + { + ID delayedID = query.value(0).toInt(); + ID dependencyID = query.value(4).toInt(); + + QString dependencyTypeStr = query.value(2).toString(); + if (dependencyTypeStr == "bank") + { + type = DependencyType::Bank; + } + else if (dependencyTypeStr == "rank") + { + type = DependencyType::Rank; + } + else if (dependencyTypeStr == "interRank") + { + type = DependencyType::InterRank; + } + + QString timeDependencyStr = query.value(3).toString(); + + if (_visiblePhases.count(delayedID) > 0) + { + + if (_visiblePhases.count(dependencyID) > 0) + { + + _visiblePhases[delayedID]->addDependency(std::shared_ptr( + new PhaseDependency(type, timeDependencyStr, _visiblePhases[dependencyID]))); + } + else + { + + _visiblePhases[delayedID]->addDependency( + std::shared_ptr(new PhaseDependency(type, timeDependencyStr))); + } + } + else + { + // TODO delayed phase not visible? + } + } +} + vector TraceDB::parseCommentsFromQuery(QSqlQuery &query) { vector result; @@ -432,6 +551,18 @@ vector TraceDB::parseCommentsFromQuery(QSqlQuery &query) return result; } +DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery &query, const DependencyInfos::Type infoType) +{ + DependencyInfos infos(infoType); + + while (query.next()) + { + infos.addInfo({query.value(0).toString(), query.value(1).toFloat()}); + } + + return infos; +} + void TraceDB::executeQuery(QSqlQuery query) { diff --git a/DRAMSys/traceAnalyzer/data/tracedb.h b/DRAMSys/traceAnalyzer/data/tracedb.h index 18abb1ae..525824b8 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.h +++ b/DRAMSys/traceAnalyzer/data/tracedb.h @@ -34,25 +34,26 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #ifndef TRACEDB_H #define TRACEDB_H -#include -#include -#include +#include "QueryTexts.h" +#include "businessObjects/commandlengths.h" +#include "businessObjects/commentmodel.h" +#include "businessObjects/generalinfo.h" +#include "businessObjects/phases/dependencyinfos.h" +#include "businessObjects/phases/phasefactory.h" +#include "businessObjects/transaction.h" #include #include #include -#include +#include +#include #include -#include "businessObjects/transaction.h" -#include "businessObjects/generalinfo.h" -#include "businessObjects/commandlengths.h" -#include "businessObjects/phases/phasefactory.h" -#include "businessObjects/commentmodel.h" -#include "QueryTexts.h" +#include /* TraceDB handles the connection to a SQLLite database containing trace data. * A TraceDB object always holds an open connection to a valid database. @@ -71,6 +72,7 @@ public: void updateComments(const std::vector &comments); void updateFileDescription(const QString &description); + void updateDependenciesInTimespan(const Timespan &span); void refreshData(); const GeneralInfo &getGeneralInfo() const @@ -85,8 +87,8 @@ public: std::vector> getTransactionsWithCustomQuery( QString queryText); - std::vector> getTransactionsInTimespan( - const Timespan &span); + std::vector> getTransactionsInTimespan(const Timespan &span, + bool updateVisiblePhases = false); std::shared_ptr getNextPrecharge(traceTime time); std::shared_ptr getNextActivate(traceTime time); std::shared_ptr getNextRefresh(traceTime time); @@ -104,6 +106,9 @@ public: std::vector getDebugMessagesInTimespan(const Timespan &span, unsigned int limit); + bool checkDependencyTableExists(); + DependencyInfos getDependencyInfos(DependencyInfos::Type infoType); + QSqlDatabase getDatabase() const; private: @@ -118,16 +123,25 @@ private: QSqlQuery selectTransactionById; QSqlQuery selectDebugMessagesByTimespan; QSqlQuery selectDebugMessagesByTimespanWithLimit; + QSqlQuery checkDependenciesExist; + QSqlQuery selectDependenciesByTimespan; + QSqlQuery selectDependencyTypePercentages; + QSqlQuery selectTimeDependencyPercentages; + QSqlQuery selectDelayedPhasePercentages; + QSqlQuery selectDependencyPhasePercentages; TransactionQueryTexts queryTexts; void prepareQueries(); void executeQuery(QSqlQuery query); QString queryToString(QSqlQuery query); std::shared_ptr parseTransactionFromQuery(QSqlQuery &query); - std::vector> parseTransactionsFromQuery( - QSqlQuery &query); + std::vector> parseTransactionsFromQuery(QSqlQuery &query, + bool updateVisiblePhases = false); std::vector parseCommentsFromQuery(QSqlQuery &query); + void mUpdateDependenciesFromQuery(QSqlQuery &query); + DependencyInfos parseDependencyInfos(QSqlQuery &query, const DependencyInfos::Type infoType); + void executeScriptFile(QString fileName); void dropAndCreateTables(); @@ -135,6 +149,8 @@ private: GeneralInfo *getGeneralInfoFromDB(); CommandLengths getCommandLengthsFromDB(); unsigned int getLengthOfCommandFromDB(const std::string& command); + + std::map> _visiblePhases; // Updated at parseTransactionsFromQuery }; diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp index 95c0a4cd..8a1971d4 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp @@ -31,6 +31,7 @@ * * Author: * Derek Christ + * Iron Prando da Silva */ #include "tracedrawingproperties.h" @@ -40,11 +41,10 @@ #include "util/traceplotlinecache.h" #include "traceselector.h" -TraceDrawingProperties::TraceDrawingProperties(bool drawText, bool drawBorder, - ColorGrouping colorGrouping) : - drawText(drawText), - drawBorder(drawBorder), - colorGrouping(colorGrouping) +TraceDrawingProperties::TraceDrawingProperties(bool drawText, bool drawBorder, DependencyOptions drawDependenciesOption, + ColorGrouping colorGrouping) + : drawText(drawText), drawBorder(drawBorder), drawDependenciesOption(drawDependenciesOption), + colorGrouping(colorGrouping) { } diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h index c51ee834..2573606e 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #ifndef TRACECOLLECTIONDRAWINGPROPERTIES_H @@ -51,13 +52,37 @@ #include "util/togglecollapsedaction.h" #include "traceselector.h" -enum class ColorGrouping {PhaseType, Transaction, Thread}; +enum class ColorGrouping +{ + PhaseType, + Transaction, + Thread, + AlphaTransaction +}; class TracePlot; class TracePlotLineCache; using TracePlotLineVector = std::vector>; +enum class DependencyOption +{ + Disabled, + Selected, + All +}; +enum class DependencyTextOption +{ + Enabled, + Disabled +}; + +struct DependencyOptions +{ + DependencyOption draw; + DependencyTextOption text; +}; + class TraceDrawingProperties : public QObject { Q_OBJECT @@ -65,6 +90,7 @@ class TraceDrawingProperties : public QObject public: bool drawText; bool drawBorder; + DependencyOptions drawDependenciesOption; ColorGrouping colorGrouping; unsigned int numberOfRanks; @@ -74,8 +100,9 @@ public: unsigned int groupsPerRank; unsigned int banksPerGroup; - TraceDrawingProperties(bool drawText = true, - bool drawBorder = true, + TraceDrawingProperties(bool drawText = true, bool drawBorder = true, + DependencyOptions drawDependenciesOption = {DependencyOption::Disabled, + DependencyTextOption::Enabled}, ColorGrouping colorGrouping = ColorGrouping::PhaseType); ~TraceDrawingProperties(); diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp index f5ab5a0b..ae236ad2 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #include "tracenavigator.h" @@ -57,6 +58,8 @@ TraceNavigator::TraceNavigator(QString path, CommentModel *commentModel, QObject QObject::connect(commentModel, &CommentModel::dataChanged, this, &TraceNavigator::traceFileModified); QObject::connect(commentModel, &CommentModel::rowsRemoved, this, &TraceNavigator::traceFileModified); + Transaction::setNumTransactions(GeneralTraceInfo().numberOfTransactions); + tracePlotLineCache = std::make_shared(getTracePlotLines(), GeneralTraceInfo().numberOfRanks, GeneralTraceInfo().groupsPerRank, GeneralTraceInfo().banksPerGroup); diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp index 93168f55..f1ecc997 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #include @@ -149,6 +150,11 @@ void TracePlot::setUpActions() QObject::connect(setColorGroupingTransaction, SIGNAL(triggered()), this, SLOT(on_colorGroupingTransaction())); + setColorGroupingAlphaTransaction = new QAction("Group by Transaction - Alpha Colored", this); + addAction(setColorGroupingAlphaTransaction); + QObject::connect(setColorGroupingAlphaTransaction, SIGNAL(triggered()), this, + SLOT(on_colorGroupingAlphaTransaction())); + setColorGroupingThread = new QAction("Group by Thread", this); setColorGroupingThread->setCheckable(true); addAction(setColorGroupingThread); @@ -171,6 +177,50 @@ void TracePlot::setUpActions() SLOT(on_toggleCollapsedState())); toggleCollapsedState->setShortcut(Qt::CTRL + Qt::Key_X); + disabledDependencies = new QAction("Disabled", this); + selectedDependencies = new QAction("Selected transactions", this); + allDependencies = new QAction("All transactions", this); + switchDrawDependencyTextsOption = new QAction("Draw Texts", this); + + disabledDependencies->setCheckable(true); + selectedDependencies->setCheckable(true); + allDependencies->setCheckable(true); + switchDrawDependencyTextsOption->setCheckable(true); + + switchDrawDependencyTextsOption->setChecked(true); + disabledDependencies->setChecked(true); + + QObject::connect(disabledDependencies, &QAction::triggered, this, [&]() { + drawingProperties.drawDependenciesOption.draw = DependencyOption::Disabled; + currentTraceTimeChanged(); + }); + QObject::connect(selectedDependencies, &QAction::triggered, this, [&]() { + drawingProperties.drawDependenciesOption.draw = DependencyOption::Selected; + currentTraceTimeChanged(); + }); + QObject::connect(allDependencies, &QAction::triggered, this, [&]() { + drawingProperties.drawDependenciesOption.draw = DependencyOption::All; + currentTraceTimeChanged(); + }); + QObject::connect(switchDrawDependencyTextsOption, &QAction::triggered, this, [&]() { + if (drawingProperties.drawDependenciesOption.text == DependencyTextOption::Disabled) + { + drawingProperties.drawDependenciesOption.text = DependencyTextOption::Enabled; + switchDrawDependencyTextsOption->setChecked(true); + } + else + { + drawingProperties.drawDependenciesOption.text = DependencyTextOption::Disabled; + switchDrawDependencyTextsOption->setChecked(false); + } + currentTraceTimeChanged(); + }); + + QActionGroup *dependenciesGroup = new QActionGroup(this); + dependenciesGroup->addAction(disabledDependencies); + dependenciesGroup->addAction(selectedDependencies); + dependenciesGroup->addAction(allDependencies); + setUpContextMenu(); } @@ -180,9 +230,15 @@ void TracePlot::setUpContextMenu() contextMenu->addActions({deselectAll}); QMenu *colorGroupingSubMenu = new QMenu("Group by", contextMenu); - colorGroupingSubMenu->addActions({setColorGroupingPhase, setColorGroupingTransaction, setColorGroupingThread}); + colorGroupingSubMenu->addActions( + {setColorGroupingPhase, setColorGroupingTransaction, setColorGroupingThread, setColorGroupingAlphaTransaction}); contextMenu->addMenu(colorGroupingSubMenu); + dependenciesSubMenu = new QMenu("Show dependencies", contextMenu); + dependenciesSubMenu->addActions( + {disabledDependencies, selectedDependencies, allDependencies, switchDrawDependencyTextsOption}); + contextMenu->addMenu(dependenciesSubMenu); + QMenu *goToSubMenu = new QMenu("Go to", contextMenu); goToSubMenu->addActions({goToPhase, goToTransaction, goToTime}); contextMenu->addMenu(goToSubMenu); @@ -228,6 +284,8 @@ void TracePlot::init(TraceNavigator *navigator, QScrollBar *scrollBar, CommentMo updateScrollbar(); + dependenciesSubMenu->setEnabled(navigator->TraceFile().checkDependencyTableExists()); + replot(); } @@ -455,8 +513,14 @@ void TracePlot::setZoomLevel(traceTime newZoomLevel) void TracePlot::currentTraceTimeChanged() { - transactions = navigator->TraceFile().getTransactionsInTimespan( - GetCurrentTimespan()); + bool drawDependencies = getDrawingProperties().drawDependenciesOption.draw != DependencyOption::Disabled; + + transactions = navigator->TraceFile().getTransactionsInTimespan(GetCurrentTimespan(), drawDependencies); + if (drawDependencies) + { + navigator->TraceFile().updateDependenciesInTimespan(GetCurrentTimespan()); + } + setAxisScale(xBottom, GetCurrentTimespan().Begin(), GetCurrentTimespan().End()); replot(); } @@ -531,6 +595,13 @@ void TracePlot::on_colorGroupingTransaction() replot(); } +void TracePlot::on_colorGroupingAlphaTransaction() +{ + drawingProperties.colorGrouping = ColorGrouping::AlphaTransaction; + Q_EMIT(colorGroupingChanged(ColorGrouping::AlphaTransaction)); + replot(); +} + void TracePlot::on_colorGroupingThread() { drawingProperties.colorGrouping = ColorGrouping::Thread; diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.h b/DRAMSys/traceAnalyzer/presentation/traceplot.h index 5fff9b23..c3ec388c 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.h +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.h @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #ifndef TRACEPLOT_H @@ -107,6 +108,7 @@ private Q_SLOTS: void on_colorGroupingPhase(); void on_colorGroupingTransaction(); void on_colorGroupingThread(); + void on_colorGroupingAlphaTransaction(); void on_goToTransaction(); void on_goToPhase(); void on_deselectAll(); @@ -179,9 +181,16 @@ private: QAction *setColorGroupingPhase; QAction *setColorGroupingTransaction; QAction *setColorGroupingThread; + QAction *setColorGroupingAlphaTransaction; QAction *exportToPdf; ToggleCollapsedAction *toggleCollapsedState; + QMenu *dependenciesSubMenu; + QAction *disabledDependencies; + QAction *selectedDependencies; + QAction *allDependencies; + QAction *switchDrawDependencyTextsOption; + TracePlotMouseLabel *mouseLabel; void openContextMenu(const QPoint &pos, const QPoint &mouseDown); diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp index 564df655..50d5dbd6 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp @@ -43,9 +43,10 @@ #include "traceplotitem.h" #include "util/engineeringScaleDraw.h" -TraceScroller::TraceScroller(QWidget *parent): - QwtPlot(parent), isInitialized(false), drawingProperties(false, false, - ColorGrouping::PhaseType) +TraceScroller::TraceScroller(QWidget *parent) + : QwtPlot(parent), isInitialized(false), + drawingProperties(false, false, {DependencyOption::Disabled, DependencyTextOption::Disabled}, + ColorGrouping::PhaseType) { setAxisScaleDraw(xBottom, new EngineeringScaleDraw); canvas()->setCursor(Qt::ArrowCursor); @@ -192,10 +193,18 @@ void TraceScroller::colorGroupingChanged(ColorGrouping colorGrouping) void TraceScroller::currentTraceTimeChanged() { + bool drawDependencies = drawingProperties.drawDependenciesOption.draw != DependencyOption::Disabled; + Timespan spanOnTracePlot = tracePlot->GetCurrentTimespan(); canvasClip->setInterval(spanOnTracePlot.Begin(), spanOnTracePlot.End()); Timespan span = GetCurrentTimespan(); - transactions = navigator->TraceFile().getTransactionsInTimespan(span); + transactions = navigator->TraceFile().getTransactionsInTimespan(span, drawDependencies); + + if (drawDependencies) + { + navigator->TraceFile().updateDependenciesInTimespan(span); + } + setAxisScale(xBottom, span.Begin(), span.End()); replot(); } diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.h b/DRAMSys/traceAnalyzer/presentation/tracescroller.h index 310d46d1..ad7b01eb 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.h +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.h @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #ifndef TRACESCROLLER_H diff --git a/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.cpp b/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.cpp index 2dc133a5..ae3070a6 100644 --- a/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.cpp +++ b/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.cpp @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Iron Prando da Silva */ #include "colorgenerator.h" @@ -102,3 +103,14 @@ QColor ColorGenerator::getColor(unsigned int i) return result; } +QColor ColorGenerator::getAlphaColored(unsigned int i) +{ + static ColorGenerator gen; + const int minAlpha = 25; + const int alphaLevels = 40 - 255 / minAlpha; + int alpha = minAlpha + (int)(((255. - minAlpha) / alphaLevels) * (i % alphaLevels)); + i = (i / alphaLevels) % 16; + QColor result(gen.r[i], gen.g[i], gen.b[i]); + result.setAlpha(alpha); + return result; +} diff --git a/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.h b/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.h index 5b7b22dd..35941474 100644 --- a/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.h +++ b/DRAMSys/traceAnalyzer/presentation/util/colorgenerator.h @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Iron Prando da Silva */ #ifndef COLORGENERATOR_H @@ -52,6 +53,7 @@ private: public: static QColor getColor(unsigned int i); + static QColor getAlphaColored(unsigned int i); }; diff --git a/DRAMSys/traceAnalyzer/tracefiletab.cpp b/DRAMSys/traceAnalyzer/tracefiletab.cpp index 0db0d23c..bd6e72cb 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.cpp +++ b/DRAMSys/traceAnalyzer/tracefiletab.cpp @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #include "tracefiletab.h" @@ -71,7 +72,8 @@ 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) + memSpecModel(new MemSpecModel(navigator->TraceFile(), this)), savingChangesToDB(false), + depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)) { ui->setupUi(this); this->path = path; @@ -91,6 +93,9 @@ TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) ui->memSpecView->setModel(memSpecModel); ui->memSpecView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui->depInfosView->setModel(depInfosView); + ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + tracefileChanged(); } diff --git a/DRAMSys/traceAnalyzer/tracefiletab.h b/DRAMSys/traceAnalyzer/tracefiletab.h index 4fafc317..a345bbc1 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.h +++ b/DRAMSys/traceAnalyzer/tracefiletab.h @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Derek Christ + * Iron Prando da Silva */ #ifndef TRACEFILETAB_H @@ -102,6 +103,8 @@ private: QAbstractItemModel *mcConfigModel; QAbstractItemModel *memSpecModel; + QAbstractItemModel *depInfosView; + void setUpQueryEditor(QString path); bool savingChangesToDB; diff --git a/DRAMSys/traceAnalyzer/tracefiletab.ui b/DRAMSys/traceAnalyzer/tracefiletab.ui index 6a8594d2..22a0a210 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.ui +++ b/DRAMSys/traceAnalyzer/tracefiletab.ui @@ -202,6 +202,22 @@ Customize Plot + + + + Dependency Information + + + + + + true + + + + + + Comments