Move Trace Analyzer to open source tree

Move the code for the Trace Analyzer to the open source tree and only
keep the extensions behind a compiler flag.
This commit is contained in:
2024-07-05 10:53:44 +02:00
parent cfd980373b
commit 82027bfa83
96 changed files with 679 additions and 1418 deletions

View File

@@ -91,10 +91,11 @@ set(DRAMSYS_EXTENSIONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extensions")
### Build options ###
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
option(DRAMSYS_VERBOSE_CMAKE_OUTPUT "Show detailed CMake output" OFF)
option(DRAMSYS_BUILD_TESTS "Build DRAMSys unit tests" OFF)
option(DRAMSYS_BUILD_BENCHMARKS "Build DRAMSys benchmarks" OFF)
option(DRAMSYS_VERBOSE_CMAKE_OUTPUT "Show detailed CMake output" OFF)
option(DRAMSYS_BUILD_CLI "Build DRAMSys Command Line Tool" ON)
option(DRAMSYS_BUILD_TRACE_ANALYZER "Build DRAMSys Trace Analyzer" OFF)
option(DRAMSYS_WITH_DRAMPOWER "Build with DRAMPower support enabled." OFF)
option(DRAMSYS_ENABLE_EXTENSIONS "Enable proprietary DRAMSys extensions." OFF)
option(DRAMSYS_USE_EXTERNAL_SYSTEMC "Use an external SystemC installation." OFF)
@@ -184,6 +185,10 @@ if(DRAMSYS_BUILD_CLI)
add_subdirectory(src/simulator)
endif()
if(DRAMSYS_BUILD_TRACE_ANALYZER)
add_subdirectory(src/traceAnalyzer)
endif()
if(DRAMSYS_ENABLE_EXTENSIONS)
dramsys_enable_extensions()
endif()
@@ -202,6 +207,6 @@ endif()
### Benchmark Directory ###
###############################################
if(DRAMSYS_BUILD_BENCHMARKS)
if(DRAMSYS_BUILD_BENCHMARKS)
add_subdirectory(benches)
endif()

View File

@@ -6,12 +6,11 @@
##############################################
##############################################
message(STATUS " Apps:")
##############################################
### TraceAnalyzer ###
##############################################
option(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE "Enable DRAMSys Trace Analyzer" ON)
if(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE)
message(STATUS " * Trace Analyzer")
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/traceAnalyzer")
add_subdirectory(traceAnalyzer)
endif()
ENDIF()

View File

@@ -1,8 +0,0 @@
[Dolphin]
Timestamp=2022,2,16,16,1,1.259
Version=4
ViewMode=1
VisibleRoles=Details_text,Details_type,Details_size,Details_modificationtime,CustomizedDetails
[Settings]
HiddenFilesShown=true

View File

@@ -1,102 +1,14 @@
# Copyright (c) 2020, RPTU Kaiserslautern-Landau
# 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:
# Matthias Jung
# Lukas Steiner
# Derek Christ
# Iron Prando da Silva
option(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE "Enable Trace Analyzer extension" ON)
########################################
### TraceAnalyzer ###
########################################
if(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE AND TARGET TraceAnalyzer)
message(STATUS " * Trace Analyzer")
project(TraceAnalyzer)
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp)
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp)
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
target_sources(TraceAnalyzer PRIVATE ${SOURCE_FILES} ${HEADER_FILES})
target_include_directories(TraceAnalyzer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(TraceAnalyzer PRIVATE EXTENSION_ENABLED)
# Add Python3 Dependency:
find_package(Python3 COMPONENTS Development Interpreter)
FetchContent_Declare(
pybind11
URL https://github.com/pybind/pybind11/archive/refs/tags/v2.10.4.zip
)
FetchContent_MakeAvailable(pybind11)
# Add QWT Dependency:
find_library(QWT_LIBRARY NAMES "qwt" "qwt-qt5" PATHS
"$ENV{QWT_HOME}/lib"
"/opt/homebrew/opt/qwt-qt5/lib"
)
find_path(QWT_INCLUDE_DIRS NAMES "qwt_plot.h" PATHS
"$ENV{QWT_HOME}/include"
"/usr/include/qwt-qt5"
"/usr/include/qwt"
"/opt/homebrew/opt/qwt-qt5/include"
"/opt/homebrew/opt/qwt-qt5/lib/qwt.framework/Headers"
)
# Add QT Library:
if (APPLE)
set(Qt5_DIR "/opt/homebrew/opt/qt@5/lib/cmake/Qt5")
endif(APPLE)
find_package(Qt5 COMPONENTS Core Gui Widgets Sql REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(TraceAnalyzer ${SOURCE_FILES} ${HEADER_FILES})
target_include_directories(TraceAnalyzer
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${QWT_INCLUDE_DIRS}
)
target_link_libraries(TraceAnalyzer
PRIVATE pybind11::embed
PRIVATE ${QWT_LIBRARY}
PRIVATE Qt5::Widgets
PRIVATE Qt5::Sql
PRIVATE DRAMSys::util
PRIVATE DRAMSys::config
)
set(DRAMSYS_TRACEANALYZER_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
target_compile_definitions(${PROJECT_NAME}
PUBLIC
DRAMSYS_TRACEANALYZER_DIR="${DRAMSYS_TRACEANALYZER_DIR}"
)
build_source_group()
build_source_group()
endif()

View File

@@ -35,7 +35,7 @@
#pragma once
#include "../data/tracedb.h"
#include "data/tracedb.h"
#include "phases/dependencyinfos.h"
#include <QAbstractTableModel>

View File

@@ -34,7 +34,7 @@
*/
#include "phasedependency.h"
#include "phase.h"
#include "businessObjects/phases/phase.h"
#include <iostream>
PhaseDependency::PhaseDependency(DependencyType type,

View File

@@ -1,400 +0,0 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* 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 "simulationdialog.h"
#include "DRAMSys/config/TraceSetup.h"
#include <QDateTime>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QRegularExpression>
#include <optional>
SimulationDialog::SimulationDialog(QWidget* parent) : QWidget(parent), ui(new Ui::SimulationDialog)
{
ui->setupUi(this);
showStopButton(false);
// Try to find path to DRAMSys
{
QFileInfo fileInfo;
fileInfo.setFile("../simulator/DRAMSys");
if (fileInfo.isFile())
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
fileInfo.setFile("../simulator/DRAMSys.exe");
if (fileInfo.isFile())
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
fileInfo.setFile("simulator/DRAMSys");
if (fileInfo.isFile())
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
fileInfo.setFile("simulator/DRAMSys.exe");
if (fileInfo.isFile())
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
}
ui->outputDirLineEdit->setText(QDir::currentPath());
}
void SimulationDialog::on_browseDramSysButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(
this, ui->browseDramSysButton->text(), {}, "DRAMSys executable (*)");
ui->dramSysPath->setText(fileName);
}
void SimulationDialog::on_browseConfigButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(
this, ui->browseConfigButton->text(), {}, "Configuration file (*.json)");
ui->jsonPath->setText(fileName);
loadConfigurationFromPath();
}
void SimulationDialog::on_browseOutputButton_clicked()
{
QString fileName = QFileDialog::getExistingDirectory(this, ui->browseOutputButton->text(), {});
ui->outputDirLineEdit->setText(fileName);
loadConfigurationFromPath();
}
void SimulationDialog::on_browseResourceDirButton_clicked()
{
QString fileName =
QFileDialog::getExistingDirectory(this, ui->browseResourceDirButton->text(), {});
ui->resourceDirLineEdit->setText(fileName);
loadConfigurationFromPath();
}
void SimulationDialog::on_simulateButton_clicked()
{
saveConfiguration(temporaryConfigurationFile);
ui->tabWidget->setCurrentWidget(ui->outputTab);
ui->progressBar->setEnabled(true);
ui->progressBar->setValue(0);
showStopButton(true);
// Spawn the DRAMSys process
simulatorProcess = new QProcess(this);
QObject::connect(simulatorProcess,
&QIODevice::readyRead,
this,
[=]
{
QByteArray msg = simulatorProcess->read(4096);
msg = msg.trimmed();
processMessage(msg.toStdString());
});
QObject::connect(simulatorProcess,
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this,
[=](int exitCode, QProcess::ExitStatus exitStatus)
{
Q_UNUSED(exitStatus)
showStopButton(false);
// Clear all the contents so that the user is not asked
// next time to overwrite the temp file.
temporaryConfigurationFile.resize(0);
if (exitCode == 0)
{
ui->progressBar->setValue(100);
QMessageBox msgBox;
msgBox.setText("Simulation done.");
msgBox.setInformativeText("Do you want to open the results?");
msgBox.setStandardButtons(QMessageBox::Open | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Open);
int ret = msgBox.exec();
if (ret == QMessageBox::Open)
{
auto results = getSimulationResults();
openSimulationResults(results);
}
}
});
QStringList argumentList;
argumentList << temporaryConfigurationFile.fileName();
if (!ui->resourceDirLineEdit->text().isEmpty())
argumentList << ui->resourceDirLineEdit->text();
simulatorProcess->setWorkingDirectory(ui->outputDirLineEdit->text());
simulatorProcess->start(ui->dramSysPath->text(), argumentList);
}
void SimulationDialog::on_reloadButton_clicked()
{
loadConfigurationFromPath();
ui->outputPlainTextEdit->clear();
}
void SimulationDialog::on_saveButton_clicked()
{
QFile file(ui->jsonPath->text());
saveConfiguration(file);
}
void SimulationDialog::on_stopButton_clicked()
{
if (simulatorProcess)
simulatorProcess->terminate();
}
void SimulationDialog::showStopButton(bool val)
{
ui->simulateButton->setVisible(!val);
ui->stopButton->setVisible(val);
}
void SimulationDialog::saveConfiguration(QFile& file)
{
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
return;
if (file.size() != 0)
{
QMessageBox msgBox;
msgBox.setText("The configuration file will be overwritten.");
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
if (ret != QMessageBox::Save)
return;
}
// Clear the file
file.resize(0);
QTextStream out(&file);
loadConfigurationFromTextFields();
std::string dump = nlohmann::json(configuration).dump(4);
out << dump.c_str();
}
void SimulationDialog::processMessage(const std::string& msg)
{
// Get percentages
QRegularExpression re("(\\d+(\\.\\d+)?|\\.\\d+) ?%");
QRegularExpressionMatch match = re.match(msg.c_str());
if (match.hasMatch())
{
unsigned int percentage = match.captured(1).toUInt();
ui->progressBar->setValue(percentage);
}
ui->outputPlainTextEdit->appendPlainText(msg.c_str());
}
void SimulationDialog::loadConfigurationFromTextFields()
{
using namespace DRAMSys::Config;
AddressMapping addressMapping;
McConfig mcConfig;
MemSpec memSpec;
SimConfig simConfig;
std::string simulationId;
std::vector<Initiator> traceSetup;
simulationId = ui->simulationIdLineEdit->text().toStdString();
try
{
nlohmann::json::parse(ui->addressMappingTextEdit->toPlainText().toStdString())
.get_to(addressMapping);
nlohmann::json::parse(ui->mcConfigTextEdit->toPlainText().toStdString()).get_to(mcConfig);
nlohmann::json::parse(ui->memSpecTextEdit->toPlainText().toStdString()).get_to(memSpec);
nlohmann::json::parse(ui->simConfigTextEdit->toPlainText().toStdString()).get_to(simConfig);
if (!ui->traceSetupTextEdit->toPlainText().toStdString().empty())
nlohmann::json::parse(ui->traceSetupTextEdit->toPlainText().toStdString())
.get_to(traceSetup);
}
catch (const std::exception& e)
{
qWarning() << "Error while parsing json:" << e.what();
return;
}
configuration = DRAMSys::Config::Configuration{
addressMapping,
mcConfig,
memSpec,
simConfig,
simulationId,
std::make_optional<std::vector<Initiator>>(std::move(traceSetup))};
loadConfiguration();
}
void SimulationDialog::loadConfigurationFromPath()
{
QFileInfo fileInfo(ui->jsonPath->text());
if (!fileInfo.isFile())
return;
try
{
configuration = DRAMSys::Config::from_path(ui->jsonPath->text().toStdString());
}
catch (const std::exception& e)
{
qWarning() << "Error while parsing json:" << e.what();
return;
}
loadConfiguration();
}
void SimulationDialog::loadConfiguration()
{
ui->simulationIdLabel->setEnabled(true);
ui->simulationId->setEnabled(true);
ui->simulationId->setText(configuration.simulationid.c_str());
ui->simulationIdLineEdit->setText(configuration.simulationid.c_str());
loadSimConfig();
loadMcConfig();
loadMemSpec();
loadAddressMapping();
loadTraceSetup();
loadPreview();
}
void SimulationDialog::loadSimConfig()
{
ui->simConfigTextEdit->clear();
std::string dump = nlohmann::json(configuration.simconfig).dump(4);
ui->simConfigTextEdit->setText(dump.c_str());
}
void SimulationDialog::loadMcConfig()
{
ui->mcConfigTextEdit->clear();
std::string dump = nlohmann::json(configuration.mcconfig).dump(4);
ui->mcConfigTextEdit->setText(dump.c_str());
}
void SimulationDialog::loadMemSpec()
{
ui->memSpecTextEdit->clear();
std::string dump = nlohmann::json(configuration.memspec).dump(4);
ui->memSpecTextEdit->setText(dump.c_str());
}
void SimulationDialog::loadAddressMapping()
{
ui->addressMappingTextEdit->clear();
std::string dump = nlohmann::json(configuration.addressmapping).dump(4);
ui->addressMappingTextEdit->setText(dump.c_str());
}
void SimulationDialog::loadTraceSetup()
{
ui->traceSetupTextEdit->clear();
if (const auto& traceSetup = configuration.tracesetup)
{
std::string dump = nlohmann::json(*traceSetup).dump(4);
ui->traceSetupTextEdit->setText(dump.c_str());
}
}
void SimulationDialog::loadPreview()
{
ui->previewTextEdit->clear();
std::string dump = nlohmann::json(configuration).dump(4);
ui->previewTextEdit->setText(dump.c_str());
}
QFileInfoList SimulationDialog::getSimulationResults()
{
QFileInfoList list;
// Get the path where the tracefiles are located
QDir baseDir(ui->outputDirLineEdit->text());
for (const auto& fileInfo : baseDir.entryInfoList())
{
if (fileInfo.baseName().startsWith(configuration.simulationid.c_str()))
{
// Dont open tracefiles that are older than a few seconds
if (fileInfo.metadataChangeTime().secsTo(QDateTime::currentDateTime()) > 30)
continue;
list << fileInfo;
}
}
return list;
}
void SimulationDialog::openSimulationResults(const QFileInfoList& fileInfos)
{
for (const auto& fileInfo : fileInfos)
openFileRequested(fileInfo.absoluteFilePath());
}

View File

@@ -1,394 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SimulationDialog</class>
<widget class="QWidget" name="SimulationDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>920</width>
<height>620</height>
</rect>
</property>
<property name="font">
<font/>
</property>
<property name="windowTitle">
<string>Simulation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Simulation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="browseLayout">
<item row="3" column="2">
<widget class="QLineEdit" name="resourceDirLineEdit">
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Path to resource directory... (optional)</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="browseOutputButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="configurationLabel">
<property name="text">
<string>Base configuration:</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="browseConfigButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="dramSysLabel">
<property name="text">
<string>DRAMSys:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="outputDirLabel">
<property name="text">
<string>Output directory:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="dramSysPath">
<property name="placeholderText">
<string>Path to DRAMSys...</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QPushButton" name="browseResourceDirButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="browseDramSysButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="outputDirLineEdit">
<property name="placeholderText">
<string>Path to output directory...</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="jsonPath">
<property name="placeholderText">
<string>Path to Json configuration...</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="resourceDirectoryLabel">
<property name="text">
<string>Resource directory:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="simulationIdLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Simulation Id:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="simulationId">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QProgressBar" name="progressBar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="simulateButton">
<property name="text">
<string>Start Simulation</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="text">
<string>Stop Simulation</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="simConfigTab">
<attribute name="title">
<string>SimConfig</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTextEdit" name="simConfigTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="mcConfigTab">
<attribute name="title">
<string>McConfig</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QTextEdit" name="mcConfigTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="memSpecTab">
<attribute name="title">
<string>MemSpec</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QTextEdit" name="memSpecTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="thermalConfigTab">
<attribute name="title">
<string>ThermalConfig</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QTextEdit" name="thermalConfigTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="traceSetupTab">
<attribute name="title">
<string>TraceSetup</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QTextEdit" name="traceSetupTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="addressMappingTab">
<attribute name="title">
<string>AddressMapping</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<widget class="QTextEdit" name="addressMappingTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="previewTab">
<attribute name="title">
<string>Preview Configuration</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<widget class="QTextEdit" name="previewTextEdit">
<property name="font">
<font/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="outputTab">
<attribute name="title">
<string>Output</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QPlainTextEdit" name="outputPlainTextEdit">
<property name="font">
<font/>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="reloadButton">
<property name="text">
<string>Reload</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="simulationIdLineEdit">
<property name="placeholderText">
<string>Simulation Id</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Save</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>dramSysPath</tabstop>
<tabstop>outputDirLineEdit</tabstop>
<tabstop>jsonPath</tabstop>
<tabstop>resourceDirLineEdit</tabstop>
<tabstop>browseDramSysButton</tabstop>
<tabstop>browseOutputButton</tabstop>
<tabstop>browseConfigButton</tabstop>
<tabstop>browseResourceDirButton</tabstop>
<tabstop>simulateButton</tabstop>
<tabstop>stopButton</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>reloadButton</tabstop>
<tabstop>simulationIdLineEdit</tabstop>
<tabstop>saveButton</tabstop>
<tabstop>closeButton</tabstop>
<tabstop>simConfigTextEdit</tabstop>
<tabstop>outputPlainTextEdit</tabstop>
<tabstop>memSpecTextEdit</tabstop>
<tabstop>thermalConfigTextEdit</tabstop>
<tabstop>traceSetupTextEdit</tabstop>
<tabstop>addressMappingTextEdit</tabstop>
<tabstop>mcConfigTextEdit</tabstop>
<tabstop>previewTextEdit</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>closeButton</sender>
<signal>clicked()</signal>
<receiver>SimulationDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>836</x>
<y>507</y>
</hint>
<hint type="destinationlabel">
<x>830</x>
<y>575</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -38,197 +38,16 @@
*/
#include "tracefiletab.h"
#include "businessObjects/commentmodel.h"
#include "businessObjects/configmodels.h"
#include "businessObjects/dramTimeDependencies/phasedependenciestracker.h"
#include "businessObjects/traceplotlinemodel.h"
#include "businessObjects/tracetime.h"
#include "queryeditor.h"
#include "traceanalyzer.h"
#include "ui_tracefiletab.h"
#include <QCloseEvent>
#include <QDebug>
#include <QFileDialog>
#include <QFileInfo>
#include "businessObjects/dramTimeDependencies/phasedependenciestracker.h"
#include <QItemDelegate>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QString>
#include <QTextStream>
#include <QtConcurrent/QtConcurrent>
#include <qwt_legend.h>
#include <qwt_plot_canvas.h>
#include <QStandardItem>
#include <qwt_plot_curve.h>
#include <qwt_plot_histogram.h>
#include <qwt_plot_magnifier.h>
#include <qwt_plot_panner.h>
#include <qwt_scale_draw.h>
#include <qwt_scale_widget.h>
#include <fstream>
#include <pybind11/pybind11.h>
TraceFileTab::TraceFileTab(std::string_view traceFilePath,
PythonCaller& pythonCaller,
QWidget* parent) :
QWidget(parent),
traceFilePath(traceFilePath),
ui(new Ui::TraceFileTab),
commentModel(new CommentModel(this)),
navigator(new TraceNavigator(traceFilePath.data(), commentModel, this)),
mcConfigModel(new McConfigModel(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)),
pythonCaller(pythonCaller),
savingChangesToDB(false)
{
ui->setupUi(this);
std::cout << "Opening new tab for \"" << traceFilePath << "\"" << std::endl;
ui->mcConfigView->setModel(mcConfigModel);
ui->mcConfigView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->memSpecView->setModel(memSpecModel);
ui->memSpecView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->depInfosView->setModel(depInfosView);
ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
setUpTraceSelector();
initNavigatorAndItsDependentWidgets();
setUpFileWatcher(traceFilePath.data());
setUpTraceplotScrollbar();
setUpCommentView();
setUpPossiblePhases();
tracefileChanged();
}
TraceFileTab::~TraceFileTab()
{
delete ui;
}
void TraceFileTab::commitChangesToDB()
{
savingChangesToDB = true;
navigator->commitChangesToDB();
}
void TraceFileTab::exportAsVCD()
{
std::string filename =
QFileDialog::getSaveFileName(this, "Export to VCD", "", "VCD files (*.vcd)").toStdString();
auto dump = PythonCaller::dumpVcd(traceFilePath);
std::ofstream file(filename);
file << dump;
Q_EMIT statusChanged(QString("VCD export finished."));
}
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)),
ui->traceplot,
SLOT(verticalScrollbarChanged(int)));
}
void TraceFileTab::initNavigatorAndItsDependentWidgets()
{
ui->traceplot->init(navigator, ui->traceplotScrollbar, tracePlotLineDataSource, commentModel);
ui->traceScroller->init(navigator, ui->traceplot, tracePlotLineDataSource);
connect(this,
SIGNAL(colorGroupingChanged(ColorGrouping)),
ui->traceScroller,
SLOT(colorGroupingChanged(ColorGrouping)));
ui->selectedTransactionTree->init(navigator);
// ui->debugMessages->init(navigator,ui->traceplot);
ui->bandwidthPlot->canvas()->installEventFilter(this);
ui->powerPlot->canvas()->installEventFilter(this);
ui->bufferPlot->canvas()->installEventFilter(this);
}
void TraceFileTab::setUpFileWatcher(QString path)
{
fileWatcher = new QFileSystemWatcher(QStringList(path), this);
QObject::connect(fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(tracefileChanged()));
}
void TraceFileTab::setUpCommentView()
{
ui->commentView->setModel(commentModel);
ui->commentView->setSelectionModel(commentModel->selectionModel());
ui->commentView->installEventFilter(commentModel);
ui->commentView->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(ui->commentView,
&QTableView::customContextMenuRequested,
commentModel,
&CommentModel::openContextMenu);
QObject::connect(commentModel,
&CommentModel::editTriggered,
ui->commentView,
[=](const QModelIndex& index)
{
ui->tabWidget->setCurrentWidget(ui->tabComments);
ui->commentView->edit(index);
ui->commentView->scrollTo(index);
});
QObject::connect(
ui->commentView, &QTableView::doubleClicked, commentModel, &CommentModel::rowDoubleClicked);
}
void TraceFileTab::setUpPossiblePhases()
{
@@ -244,94 +63,6 @@ void TraceFileTab::setUpPossiblePhases()
ConfigurationFactory::deviceSupported(navigator->TraceFile()));
}
void TraceFileTab::tracefileChanged()
{
if (savingChangesToDB == true)
{
// Database has changed due to user action (e.g., saving comments).
// No need to disable the "Save changes to DB" menu.
savingChangesToDB = false;
Q_EMIT statusChanged(QString("Changes saved "));
}
else
{
// External event changed the database file (e.g., the database file
// was overwritten when running a new test).
// The "Save changes to DB" menu must be disabled to avoid saving
// changes to a corrupted or inconsistent file.
Q_EMIT statusChanged(QString("At least one database has changed on disk "));
}
navigator->refreshData();
}
void TraceFileTab::closeEvent(QCloseEvent* event)
{
if (navigator->existChangesToCommit())
{
QMessageBox saveDialog;
saveDialog.setWindowTitle(QFileInfo(traceFilePath.data()).baseName());
saveDialog.setText("The trace file has been modified.");
saveDialog.setInformativeText(
"Do you want to save your changes?<br><b>Unsaved changes will be lost.</b>");
saveDialog.setStandardButtons(QMessageBox::Save | QMessageBox::Discard |
QMessageBox::Cancel);
saveDialog.setDefaultButton(QMessageBox::Save);
saveDialog.setIcon(QMessageBox::Warning);
int returnCode = saveDialog.exec();
switch (returnCode)
{
case QMessageBox::Cancel:
event->ignore();
break;
case QMessageBox::Discard:
event->accept();
break;
case QMessageBox::Save:
commitChangesToDB();
event->accept();
break;
};
}
else
event->accept();
}
traceTime TraceFileTab::getCurrentTraceTime() const
{
return navigator->CurrentTraceTime();
}
void TraceFileTab::navigateToTime(traceTime time)
{
navigator->navigateToTime(time);
}
traceTime TraceFileTab::getZoomLevel() const
{
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
return traceplot->ZoomLevel();
}
void TraceFileTab::setZoomLevel(traceTime zoomLevel)
{
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
TraceScroller* tracescroller = static_cast<TraceScroller*>(ui->traceScroller);
traceplot->setZoomLevel(zoomLevel);
tracescroller->tracePlotZoomChanged();
}
std::shared_ptr<AbstractTracePlotLineModel::Node> TraceFileTab::saveTraceSelectorState() const
{
return selectedRowsModel->getClonedRootNode();
}
void TraceFileTab::restoreTraceSelectorState(
std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode)
{
selectedRowsModel->setRootNode(std::move(rootNode));
}
class ItemDelegate : public QItemDelegate
{
public:
@@ -372,32 +103,6 @@ void TraceFileTab::on_latencyTreeView_doubleClicked(const QModelIndex& index)
}
}
bool TraceFileTab::eventFilter(QObject* object, QEvent* event)
{
if (auto canvas = qobject_cast<QwtPlotCanvas*>(object))
{
if (event->type() == QEvent::MouseButtonDblClick)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() != Qt::LeftButton)
return false;
QwtPlot* plot = canvas->plot();
double realTime = plot->invTransform(QwtPlot::xBottom, mouseEvent->x());
// Convert from seconds to picoseconds
traceTime time = realTime * 1000 * 1000 * 1000 * 1000;
navigator->navigateToTime(time);
return true;
}
}
return QWidget::eventFilter(object, event);
}
void TraceFileTab::on_calculateDependencies_clicked()
{
std::vector<QString> dependencyFilter;
@@ -490,7 +195,6 @@ void TraceFileTab::on_startLatencyAnalysis_clicked()
void TraceFileTab::on_startPowerAnalysis_clicked()
{
qDebug() << "Power Analysis";
QSqlDatabase db = navigator->TraceFile().getDatabase();
QSqlQuery query(db);
@@ -502,11 +206,13 @@ void TraceFileTab::on_startPowerAnalysis_clicked()
QwtPlotCurve* cur = new QwtPlotCurve("Speed");
QVector<QPointF>* samples = new QVector<QPointF>;
double maxPower = 0.0;
while (query.next())
{
double time = query.value(0).toDouble();
double power = query.value(1).toDouble();
samples->push_back(QPointF(time, power));
maxPower = std::max(maxPower, power);
}
// ui->powerPlot->setAxisTitle(QwtPlot::xBottom,"Time");
@@ -519,6 +225,12 @@ void TraceFileTab::on_startPowerAnalysis_clicked()
cur->attach(ui->powerPlot);
cur->setPen(QPen(QColor(255, 0, 0)));
ui->powerPlot->setAxisTitle(0, "Power [mW]");
ui->powerPlot->setAxisScale(0, 0.0, maxPower);
QwtText axisTitle0("Time [s]");
axisTitle0.setFont(ui->powerPlot->axisTitle(QwtPlot::xBottom).font());
ui->powerPlot->setAxisTitle(QwtPlot::xBottom, axisTitle0);
QwtPlotMagnifier* mag1 = new QwtPlotMagnifier(ui->powerPlot->canvas());
mag1->setAxisEnabled(QwtPlot::xBottom, true);
mag1->setAxisEnabled(QwtPlot::yLeft, false);

View File

@@ -6,4 +6,4 @@ FOREACH(sub_dir ${sub_dirs})
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${sub_dir}")
add_subdirectory(${sub_dir})
ENDIF()
ENDFOREACH()
ENDFOREACH()

View File

@@ -0,0 +1,104 @@
# Copyright (c) 2020, RPTU Kaiserslautern-Landau
# 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:
# Matthias Jung
# Lukas Steiner
# Derek Christ
# Iron Prando da Silva
########################################
### TraceAnalyzer ###
########################################
project(TraceAnalyzer)
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp)
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
# Add Python3 Dependency:
find_package(Python3 COMPONENTS Development Interpreter)
FetchContent_Declare(
pybind11
URL https://github.com/pybind/pybind11/archive/refs/tags/v2.13.1.zip
)
FetchContent_MakeAvailable(pybind11)
# Add QWT Dependency:
find_library(QWT_LIBRARY NAMES "qwt" "qwt-qt5" PATHS
"$ENV{QWT_HOME}/lib"
"/opt/homebrew/opt/qwt-qt5/lib"
)
find_path(QWT_INCLUDE_DIRS NAMES "qwt_plot.h" PATHS
"$ENV{QWT_HOME}/include"
"/usr/include/qwt-qt5"
"/usr/include/qwt"
"/opt/homebrew/opt/qwt-qt5/include"
"/opt/homebrew/opt/qwt-qt5/lib/qwt.framework/Headers"
)
# Add QT Library:
if (APPLE)
set(Qt5_DIR "/opt/homebrew/opt/qt@5/lib/cmake/Qt5")
endif(APPLE)
find_package(Qt5 COMPONENTS Core Gui Widgets Sql REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(TraceAnalyzer ${SOURCE_FILES} ${HEADER_FILES})
target_include_directories(TraceAnalyzer
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${QWT_INCLUDE_DIRS}
)
target_link_libraries(TraceAnalyzer
PRIVATE
pybind11::embed
${QWT_LIBRARY}
Qt5::Widgets
Qt5::Sql
DRAMSys::util
DRAMSys::config
)
set(DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR "${CMAKE_SOURCE_DIR}/extensions/apps/traceAnalyzer")
target_compile_definitions(${PROJECT_NAME}
PRIVATE
DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR="${DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR}"
)
build_source_group()

View File

@@ -36,8 +36,11 @@
#ifndef CONFIGMODELS_H
#define CONFIGMODELS_H
#include "../data/tracedb.h"
#include "phases/dependencyinfos.h"
#include "data/tracedb.h"
#ifdef EXTENSION_ENABLED
#include "businessObjects/phases/dependencyinfos.h"
#endif
#include <QAbstractTableModel>
#include <utility>

View File

@@ -217,6 +217,7 @@ void Phase::drawPhaseDependencies(traceTime begin,
QPoint depLineTo(static_cast<int>(xMap.transform(begin /* + (end + offset - begin)/4*/)),
static_cast<int>(yVal));
#ifdef EXTENSION_ENABLED
for (const auto& dep : mDependencies)
{
if (dep->isVisible())
@@ -231,6 +232,7 @@ void Phase::drawPhaseDependencies(traceTime begin,
invisibleDeps += 1;
}
}
#endif
if (invisibleDeps > 0)
{
@@ -418,7 +420,9 @@ Phase::PhaseSymbol Phase::getPhaseSymbol() const
return PhaseSymbol::Hexagon;
}
#ifdef EXTENSION_ENABLED
void Phase::addDependency(const std::shared_ptr<PhaseDependency>& dependency)
{
mDependencies.push_back(dependency);
}
#endif

View File

@@ -39,7 +39,11 @@
#ifndef BANKPHASE_H
#define BANKPHASE_H
#ifdef EXTENSION_ENABLED
#include "businessObjects/phases/phasedependency.h"
#endif
#include "businessObjects/timespan.h"
#include "presentation/tracedrawingproperties.h"
#include "presentation/util/colorgenerator.h"
@@ -141,7 +145,9 @@ public:
virtual QString Name() const = 0;
#ifdef EXTENSION_ENABLED
void addDependency(const std::shared_ptr<PhaseDependency>& dependency);
#endif
protected:
ID id;
@@ -152,7 +158,9 @@ protected:
traceTime clk;
std::weak_ptr<Transaction> transaction;
std::vector<Timespan> spansOnCommandBus;
#ifdef EXTENSION_ENABLED
std::vector<std::shared_ptr<PhaseDependency>> mDependencies;
#endif
double hexagonHeight;
TextPositioning captionPosition;

View File

@@ -167,6 +167,7 @@ bool TraceDB::checkDependencyTableExists()
return exists;
}
#ifdef EXTENSION_ENABLED
void TraceDB::updateDependenciesInTimespan(const Timespan& span)
{
if (checkDependencyTableExists())
@@ -177,6 +178,7 @@ void TraceDB::updateDependenciesInTimespan(const Timespan& span)
mUpdateDependenciesFromQuery(selectDependenciesByTimespan);
}
}
#endif
// TODO Remove exception
std::shared_ptr<Transaction> TraceDB::getTransactionByID(ID id)
@@ -498,6 +500,7 @@ std::vector<CommentModel::Comment> TraceDB::getDebugMessagesInTimespan(const Tim
return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit);
}
#ifdef EXTENSION_ENABLED
DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
{
DependencyInfos dummy;
@@ -551,6 +554,7 @@ DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
return dummy;
}
#endif
QSqlDatabase TraceDB::getDatabase() const
{
@@ -643,6 +647,7 @@ TraceDB::parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases)
return result;
}
#ifdef EXTENSION_ENABLED
void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
{
DependencyType type;
@@ -689,6 +694,7 @@ void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
}
}
}
#endif
std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& query)
{
@@ -701,6 +707,7 @@ std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& qu
return result;
}
#ifdef EXTENSION_ENABLED
DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
const DependencyInfos::Type infoType)
{
@@ -715,6 +722,7 @@ DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
return infos;
}
#endif
void TraceDB::executeQuery(QSqlQuery query)
{

View File

@@ -41,10 +41,14 @@
#define TRACEDB_H
#include "QueryTexts.h"
#ifdef EXTENSION_ENABLED
#include "businessObjects/phases/dependencyinfos.h"
#endif
#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 <QSqlDatabase>
@@ -69,11 +73,13 @@ public:
void updateComments(const std::vector<CommentModel::Comment>& comments);
void updateFileDescription(const QString& description);
void updateDependenciesInTimespan(const Timespan& span);
void refreshData();
const GeneralInfo& getGeneralInfo() const { return generalInfo; }
#ifdef EXTENSION_ENABLED
void updateDependenciesInTimespan(const Timespan& span);
#endif
const GeneralInfo& getGeneralInfo() const { return generalInfo; }
const CommandLengths& getCommandLengths() const { return commandLengths; }
std::vector<std::shared_ptr<Transaction>>
@@ -97,8 +103,9 @@ public:
unsigned int limit);
bool checkDependencyTableExists();
#ifdef EXTENSION_ENABLED
DependencyInfos getDependencyInfos(DependencyInfos::Type infoType);
#endif
QSqlDatabase getDatabase() const;
private:
@@ -129,9 +136,11 @@ private:
parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases = false);
static std::vector<CommentModel::Comment> parseCommentsFromQuery(QSqlQuery& query);
#ifdef EXTENSION_ENABLED
void mUpdateDependenciesFromQuery(QSqlQuery& query);
static DependencyInfos parseDependencyInfos(QSqlQuery& query,
const DependencyInfos::Type infoType);
#endif
void executeScriptFile(const QString& fileName);
void dropAndCreateTables();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,70 +33,32 @@
* Derek Christ
*/
#ifndef SIMULATIONDIALOG_H
#define SIMULATIONDIALOG_H
#ifndef EXTENSION_H
#define EXTENSION_H
#include "ui_simulationdialog.h"
#include <QLabel>
#include <QMessageBox>
#include "DRAMSys/config/DRAMSysConfiguration.h"
inline constexpr std::string_view EXTENSION_DISCLAIMER =
"This feature is part of the full version of Trace Analyzer. For more information, please "
"contact <a href=\"mailto:DRAMSys@iese.fraunhofer.de\">DRAMSys@iese.fraunhofer.de</a>.";
#include <QFileInfo>
#include <QPointer>
#include <QProcess>
#include <QSyntaxHighlighter>
#include <QTemporaryFile>
#include <QWidget>
namespace Ui
inline void showExtensionDisclaimerMessageBox()
{
class SimulationDialog;
QMessageBox box;
box.setText("Feature unavailable");
box.setInformativeText(EXTENSION_DISCLAIMER.data());
box.setIcon(QMessageBox::Information);
box.exec();
}
class SimulationDialog : public QWidget
inline QLabel* disclaimerLabel()
{
Q_OBJECT
auto* label = new QLabel;
label->setText(EXTENSION_DISCLAIMER.data());
label->setAlignment(Qt::AlignHCenter);
label->setWordWrap(true);
return label;
}
public:
explicit SimulationDialog(QWidget* parent = nullptr);
signals:
void openFileRequested(const QString& path);
private Q_SLOTS:
void on_browseDramSysButton_clicked();
void on_browseConfigButton_clicked();
void on_browseOutputButton_clicked();
void on_browseResourceDirButton_clicked();
void on_simulateButton_clicked();
void on_reloadButton_clicked();
void on_saveButton_clicked();
void on_stopButton_clicked();
private:
void loadConfigurationFromPath();
void loadConfigurationFromTextFields();
void loadConfiguration();
void loadSimConfig();
void loadMcConfig();
void loadMemSpec();
void loadAddressMapping();
void loadTraceSetup();
void loadPreview();
void showStopButton(bool val);
void saveConfiguration(QFile& file);
void processMessage(const std::string& msg);
QFileInfoList getSimulationResults();
void openSimulationResults(const QFileInfoList& fileInfos);
QTemporaryFile temporaryConfigurationFile;
DRAMSys::Config::Configuration configuration;
QPointer<QProcess> simulatorProcess;
Ui::SimulationDialog* ui;
};
#endif
#endif // EXTENSION_H

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -33,6 +33,7 @@
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#include "traceanalyzer.h"
@@ -48,16 +49,15 @@
int main(int argc, char* argv[])
{
std::cout << argv[0] << std::endl;
QApplication a(argc, argv);
QIcon icon(QStringLiteral(":/icon"));
a.setWindowIcon(icon);
a.setApplicationName(QStringLiteral("TraceAnalyzer"));
a.setApplicationDisplayName(QStringLiteral("Trace Analyzer"));
QApplication::setWindowIcon(icon);
QApplication::setApplicationName(QStringLiteral("TraceAnalyzer"));
QApplication::setApplicationDisplayName(QStringLiteral("Trace Analyzer"));
std::filesystem::path traceAnalyzerDir = DRAMSYS_TRACEANALYZER_DIR;
std::filesystem::path modulesDir = traceAnalyzerDir / "scripts";
std::filesystem::path extensionDir = DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR;
std::filesystem::path modulesDir = extensionDir / "scripts";
pybind11::scoped_interpreter guard;
@@ -92,12 +92,10 @@ int main(int argc, char* argv[])
TraceAnalyzer analyzer(arguments);
analyzer.show();
return a.exec();
}
else
{
TraceAnalyzer analyzer;
analyzer.show();
return a.exec();
return QApplication::exec();
}
TraceAnalyzer analyzer;
analyzer.show();
return QApplication::exec();
}

View File

@@ -286,6 +286,11 @@ void TracePlot::setUpActions()
dependenciesGroup->addAction(disabledDependencies);
dependenciesGroup->addAction(selectedDependencies);
dependenciesGroup->addAction(allDependencies);
dependenciesGroup->addAction(switchDrawDependencyTextsOption);
#ifndef EXTENSION_ENABLED
dependenciesGroup->setEnabled(false);
#endif
setUpContextMenu();
}
@@ -628,10 +633,13 @@ void TracePlot::currentTraceTimeChanged()
transactions =
navigator->TraceFile().getTransactionsInTimespan(GetCurrentTimespan(), drawDependencies);
#ifdef EXTENSION_ENABLED
if (drawDependencies)
{
navigator->TraceFile().updateDependenciesInTimespan(GetCurrentTimespan());
}
#endif
setAxisScale(xBottom, GetCurrentTimespan().Begin(), GetCurrentTimespan().End());

View File

@@ -220,10 +220,12 @@ void TraceScroller::currentTraceTimeChanged()
Timespan span = GetCurrentTimespan();
transactions = navigator->TraceFile().getTransactionsInTimespan(span, drawDependencies);
#ifdef EXTENSION_ENABLED
if (drawDependencies)
{
navigator->TraceFile().updateDependenciesInTimespan(span);
}
#endif
setAxisScale(xBottom, span.Begin(), span.End());
replot();

View File

@@ -37,7 +37,7 @@
*/
#include "traceanalyzer.h"
#include "simulationdialog.h"
#include "extensionDisclaimer.h"
#include "tracefiletab.h"
#include "ui_traceanalyzer.h"
@@ -53,7 +53,10 @@ void TraceAnalyzer::setUpStatusBar()
statusBar()->addWidget(statusLabel);
}
void TraceAnalyzer::setUpGui()
TraceAnalyzer::TraceAnalyzer(QWidget* parent) :
QMainWindow(parent),
evaluationTool(pythonCaller),
ui(new Ui::TraceAnalyzer)
{
ui->setupUi(this);
setUpStatusBar();
@@ -62,21 +65,8 @@ void TraceAnalyzer::setUpGui()
QObject::connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt);
}
TraceAnalyzer::TraceAnalyzer(QWidget* parent) :
QMainWindow(parent),
evaluationTool(pythonCaller),
ui(new Ui::TraceAnalyzer)
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, QWidget* parent) : TraceAnalyzer(parent)
{
setUpGui();
}
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, QWidget* parent) :
QMainWindow(parent),
evaluationTool(pythonCaller),
ui(new Ui::TraceAnalyzer)
{
setUpGui();
for (const QString& path : paths)
openTracefileTab(path);
}
@@ -99,7 +89,7 @@ void TraceAnalyzer::on_actionOpen_triggered()
TraceFileTab* TraceAnalyzer::createTraceFileTab(const QString& path)
{
TraceFileTab* traceFileTab = new TraceFileTab(path.toStdString(), pythonCaller, this);
auto* traceFileTab = new TraceFileTab(path.toStdString(), pythonCaller, this);
connect(traceFileTab, &TraceFileTab::statusChanged, this, &TraceAnalyzer::statusChanged);
@@ -131,7 +121,6 @@ void TraceAnalyzer::on_menuFile_aboutToShow()
ui->actionReload->setEnabled(tabsOpen);
ui->actionReload_all->setEnabled(tabsOpen);
ui->actionExportAsVCD->setEnabled(tabsOpen);
ui->actionTest->setEnabled(tabsOpen);
ui->actionMetrics->setEnabled(tabsOpen);
ui->actionClose->setEnabled(tabsOpen);
ui->actionClose_all->setEnabled(tabsOpen);
@@ -139,7 +128,7 @@ void TraceAnalyzer::on_menuFile_aboutToShow()
void TraceAnalyzer::closeTab(int index)
{
TraceFileTab* traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
if (traceFileTab->close())
{
@@ -169,7 +158,7 @@ void TraceAnalyzer::on_actionClose_all_triggered()
void TraceAnalyzer::reloadTab(int index)
{
auto traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
QString traceFile = traceFileTab->getPathToTraceFile();
traceTime time = traceFileTab->getCurrentTraceTime();
@@ -212,7 +201,7 @@ void TraceAnalyzer::on_actionReload_all_triggered()
void TraceAnalyzer::on_actionSave_triggered()
{
auto traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
traceFileTab->commitChangesToDB();
this->statusChanged(QString("Saved database ") +
@@ -226,14 +215,19 @@ void TraceAnalyzer::on_actionSave_all_triggered()
// Changes in the database files will trigger the file watchers from
// the TraceFileTab class. They generate signals connected to
// TraceAnalyzer::statusChanged().
TraceFileTab* traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
traceFileTab->commitChangesToDB();
}
}
void TraceAnalyzer::on_actionExportAsVCD_triggered()
{
TraceFileTab* traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
#ifndef EXTENSION_ENABLED
showExtensionDisclaimerMessageBox();
return;
#endif
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
traceFileTab->exportAsVCD();
}
@@ -244,6 +238,11 @@ void TraceAnalyzer::statusChanged(const QString& message)
void TraceAnalyzer::on_actionMetrics_triggered()
{
#ifndef EXTENSION_ENABLED
showExtensionDisclaimerMessageBox();
return;
#endif
evaluationTool.raise();
evaluationTool.activateWindow();
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.values());
@@ -254,12 +253,15 @@ void TraceAnalyzer::on_actionAbout_triggered()
QMessageBox::about(
this,
QStringLiteral("DRAMSys"),
QStringLiteral("<b>DRAMSys4.0</b> is a flexible DRAM subsystem design space exploration "
"framework based on SystemC "
"TLM-2.0. It was developed at the <a "
"href=\"https://ems.eit.uni-kl.de/en/start/\">Microelectronic Systems "
"Design Research Group</a> and <a "
"href=\"https://www.iese.fraunhofer.de/en.html\">Fraunhofer IESE</a>."));
QStringLiteral(
"<b>DRAMSys4.0</b> is a flexible DRAM subsystem design space exploration "
"framework based on SystemC "
"TLM-2.0. It was developed by the <a "
"href=\"https://ems.eit.uni-kl.de/en/start/\">Microelectronic Systems "
"Design Research Group</a>, by <a "
"href=\"https://www.iese.fraunhofer.de/en.html\">Fraunhofer IESE</a> and by the <a "
"href=\"https://www.informatik.uni-wuerzburg.de/ce\">Computer Engineering Group</a> at "
"<a href=\"https://www.uni-wuerzburg.de/en/home\">JMU Würzburg</a>."));
}
void TraceAnalyzer::closeEvent(QCloseEvent* event)
@@ -276,16 +278,3 @@ void TraceAnalyzer::closeEvent(QCloseEvent* event)
event->accept();
}
void TraceAnalyzer::on_actionSimulate_triggered()
{
SimulationDialog* simulationDialog = new SimulationDialog(this);
simulationDialog->setWindowFlag(Qt::Window);
QObject::connect(simulationDialog,
&SimulationDialog::openFileRequested,
this,
&TraceAnalyzer::openTracefileTab);
simulationDialog->show();
}

View File

@@ -63,7 +63,6 @@ public:
~TraceAnalyzer();
void setUpStatusBar();
void setUpGui();
protected:
void closeEvent(QCloseEvent* event) override;
@@ -93,7 +92,6 @@ private Q_SLOTS:
void on_actionClose_triggered();
void on_actionClose_all_triggered();
void on_actionAbout_triggered();
void on_actionSimulate_triggered();
public Q_SLOTS:
void statusChanged(const QString& message);

View File

@@ -49,7 +49,7 @@
<x>0</x>
<y>0</y>
<width>800</width>
<height>34</height>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -78,14 +78,7 @@
<addaction name="actionAbout"/>
<addaction name="actionAbout_Qt"/>
</widget>
<widget class="QMenu" name="menuRun">
<property name="title">
<string>&amp;Run</string>
</property>
<addaction name="actionSimulate"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuRun"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
@@ -133,32 +126,11 @@
<string>Ctrl+Shift+W</string>
</property>
</action>
<action name="actionInfo">
<property name="text">
<string>&amp;Info</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>&amp;About DRAMSys</string>
</property>
</action>
<action name="actionPreferences">
<property name="text">
<string>Preferences</string>
</property>
<property name="shortcut">
<string>Ctrl+P</string>
</property>
</action>
<action name="actionTest">
<property name="text">
<string>&amp;Test</string>
</property>
<property name="shortcut">
<string>Ctrl+T</string>
</property>
</action>
<action name="actionMetrics">
<property name="text">
<string>&amp;Metrics</string>
@@ -232,15 +204,6 @@
<string>Save &amp;as...</string>
</property>
</action>
<action name="actionSimulate">
<property name="icon">
<iconset theme="system-run">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Simulate...</string>
</property>
</action>
<action name="actionAbout_Qt">
<property name="text">
<string>About &amp;Qt</string>

View File

@@ -0,0 +1,364 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* 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:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#include "tracefiletab.h"
#include "businessObjects/pythoncaller.h"
#include "extensionDisclaimer.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
#include <QMouseEvent>
#include <qwt_plot_canvas.h>
#include <fstream>
TraceFileTab::TraceFileTab(std::string_view traceFilePath,
PythonCaller& pythonCaller,
QWidget* parent) :
QWidget(parent),
traceFilePath(traceFilePath),
ui(new Ui::TraceFileTab),
commentModel(new CommentModel(this)),
navigator(new TraceNavigator(traceFilePath.data(), commentModel, this)),
mcConfigModel(new McConfigModel(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)),
#ifdef EXTENSION_ENABLED
depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)),
#endif
pythonCaller(pythonCaller),
savingChangesToDB(false)
{
ui->setupUi(this);
std::cout << "Opening new tab for \"" << traceFilePath << "\"" << std::endl;
ui->mcConfigView->setModel(mcConfigModel);
ui->mcConfigView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->memSpecView->setModel(memSpecModel);
ui->memSpecView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
#ifdef EXTENSION_ENABLED
ui->depInfosView->setModel(depInfosView);
ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
#endif
setUpTraceSelector();
initNavigatorAndItsDependentWidgets();
setUpFileWatcher(traceFilePath.data());
setUpTraceplotScrollbar();
setUpCommentView();
#ifdef EXTENSION_ENABLED
setUpPossiblePhases();
#else
addDisclaimer();
#endif
tracefileChanged();
}
TraceFileTab::~TraceFileTab()
{
delete ui;
}
void TraceFileTab::commitChangesToDB()
{
savingChangesToDB = true;
navigator->commitChangesToDB();
}
void TraceFileTab::exportAsVCD()
{
std::string filename =
QFileDialog::getSaveFileName(this, "Export to VCD", "", "VCD files (*.vcd)").toStdString();
auto dump = PythonCaller::dumpVcd(traceFilePath);
std::ofstream file(filename);
file << dump;
Q_EMIT statusChanged(QString("VCD export finished."));
}
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)),
ui->traceplot,
SLOT(verticalScrollbarChanged(int)));
}
void TraceFileTab::initNavigatorAndItsDependentWidgets()
{
ui->traceplot->init(navigator, ui->traceplotScrollbar, tracePlotLineDataSource, commentModel);
ui->traceScroller->init(navigator, ui->traceplot, tracePlotLineDataSource);
connect(this,
SIGNAL(colorGroupingChanged(ColorGrouping)),
ui->traceScroller,
SLOT(colorGroupingChanged(ColorGrouping)));
ui->selectedTransactionTree->init(navigator);
// ui->debugMessages->init(navigator,ui->traceplot);
ui->bandwidthPlot->canvas()->installEventFilter(this);
ui->powerPlot->canvas()->installEventFilter(this);
ui->bufferPlot->canvas()->installEventFilter(this);
}
void TraceFileTab::setUpFileWatcher(QString path)
{
fileWatcher = new QFileSystemWatcher(QStringList(path), this);
QObject::connect(fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(tracefileChanged()));
}
void TraceFileTab::setUpCommentView()
{
ui->commentView->setModel(commentModel);
ui->commentView->setSelectionModel(commentModel->selectionModel());
ui->commentView->installEventFilter(commentModel);
ui->commentView->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(ui->commentView,
&QTableView::customContextMenuRequested,
commentModel,
&CommentModel::openContextMenu);
QObject::connect(commentModel,
&CommentModel::editTriggered,
ui->commentView,
[=](const QModelIndex& index)
{
ui->tabWidget->setCurrentWidget(ui->tabComments);
ui->commentView->edit(index);
ui->commentView->scrollTo(index);
});
QObject::connect(
ui->commentView, &QTableView::doubleClicked, commentModel, &CommentModel::rowDoubleClicked);
}
void TraceFileTab::addDisclaimer()
{
// Latency analysis
auto* latencyDisclaimerLabel = disclaimerLabel();
ui->latencyLayout->insertWidget(0, latencyDisclaimerLabel);
ui->latencyAnalysisProgressBar->setEnabled(false);
ui->startLatencyAnalysis->setEnabled(false);
ui->latencyPlot->setEnabled(false);
ui->latencyTreeView->setEnabled(false);
// Power analysis
auto* powerDisclaimerLabel = disclaimerLabel();
ui->powerLayout->insertWidget(0, powerDisclaimerLabel);
ui->startPowerAnalysis->setEnabled(false);
ui->powerBox->setEnabled(false);
ui->bandwidthBox->setEnabled(false);
ui->bufferBox->setEnabled(false);
// Dependencies
auto* dependenciesDisclaimerLabel = disclaimerLabel();
ui->verticalLayout_depInfos->insertWidget(0, dependenciesDisclaimerLabel);
ui->depInfoLabel->setEnabled(false);
ui->depInfosView->setEnabled(false);
ui->depTabPossiblePhases->setEnabled(false);
ui->calculateDependencies->setEnabled(false);
}
void TraceFileTab::tracefileChanged()
{
if (savingChangesToDB == true)
{
// Database has changed due to user action (e.g., saving comments).
// No need to disable the "Save changes to DB" menu.
savingChangesToDB = false;
Q_EMIT statusChanged(QString("Changes saved "));
}
else
{
// External event changed the database file (e.g., the database file
// was overwritten when running a new test).
// The "Save changes to DB" menu must be disabled to avoid saving
// changes to a corrupted or inconsistent file.
Q_EMIT statusChanged(QString("At least one database has changed on disk "));
}
navigator->refreshData();
}
void TraceFileTab::closeEvent(QCloseEvent* event)
{
if (navigator->existChangesToCommit())
{
QMessageBox saveDialog;
saveDialog.setWindowTitle(QFileInfo(traceFilePath.data()).baseName());
saveDialog.setText("The trace file has been modified.");
saveDialog.setInformativeText(
"Do you want to save your changes?<br><b>Unsaved changes will be lost.</b>");
saveDialog.setStandardButtons(QMessageBox::Save | QMessageBox::Discard |
QMessageBox::Cancel);
saveDialog.setDefaultButton(QMessageBox::Save);
saveDialog.setIcon(QMessageBox::Warning);
int returnCode = saveDialog.exec();
switch (returnCode)
{
case QMessageBox::Cancel:
event->ignore();
break;
case QMessageBox::Discard:
event->accept();
break;
case QMessageBox::Save:
commitChangesToDB();
event->accept();
break;
};
}
else
event->accept();
}
traceTime TraceFileTab::getCurrentTraceTime() const
{
return navigator->CurrentTraceTime();
}
void TraceFileTab::navigateToTime(traceTime time)
{
navigator->navigateToTime(time);
}
traceTime TraceFileTab::getZoomLevel() const
{
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
return traceplot->ZoomLevel();
}
void TraceFileTab::setZoomLevel(traceTime zoomLevel)
{
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
TraceScroller* tracescroller = static_cast<TraceScroller*>(ui->traceScroller);
traceplot->setZoomLevel(zoomLevel);
tracescroller->tracePlotZoomChanged();
}
std::shared_ptr<AbstractTracePlotLineModel::Node> TraceFileTab::saveTraceSelectorState() const
{
return selectedRowsModel->getClonedRootNode();
}
void TraceFileTab::restoreTraceSelectorState(
std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode)
{
selectedRowsModel->setRootNode(std::move(rootNode));
}
bool TraceFileTab::eventFilter(QObject* object, QEvent* event)
{
if (auto canvas = qobject_cast<QwtPlotCanvas*>(object))
{
if (event->type() == QEvent::MouseButtonDblClick)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() != Qt::LeftButton)
return false;
QwtPlot* plot = canvas->plot();
double realTime = plot->invTransform(QwtPlot::xBottom, mouseEvent->x());
// Convert from seconds to picoseconds
traceTime time = realTime * 1000 * 1000 * 1000 * 1000;
navigator->navigateToTime(time);
return true;
}
}
return QWidget::eventFilter(object, event);
}

View File

@@ -40,13 +40,17 @@
#ifndef TRACEFILETAB_H
#define TRACEFILETAB_H
#include "ui_tracefiletab.h"
#include "businessObjects/configmodels.h"
#ifdef EXTENSION_ENABLED
#include "businessObjects/dependencymodels.h"
#endif
#include "businessObjects/traceplotlinemodel.h"
#include "presentation/tracenavigator.h"
#include "presentation/traceplot.h"
#include "presentation/tracescroller.h"
#include "businessObjects/configmodels.h"
#include "businessObjects/dependencymodels.h"
#include <QFileSystemWatcher>
#include <QString>
#include <QTreeWidget>
@@ -57,11 +61,6 @@ class McConfigModel;
class MemSpecModel;
class PythonCaller;
namespace Ui
{
class TraceFileTab;
}
class TraceFileTab : public QWidget
{
Q_OBJECT
@@ -76,11 +75,15 @@ public:
void setUpTraceplotScrollbar();
void setUpCommentView();
void setUpTraceSelector();
void addDisclaimer();
#ifdef EXTENSION_ENABLED
void setUpPossiblePhases();
#endif
void initNavigatorAndItsDependentWidgets();
QString getPathToTraceFile() { return traceFilePath.data(); }
void commitChangesToDB(void);
void commitChangesToDB();
void exportAsVCD();
traceTime getCurrentTraceTime() const;
@@ -116,7 +119,9 @@ private:
SelectedTracePlotLineModel* selectedRowsModel;
TracePlotLineDataSource* tracePlotLineDataSource;
#ifdef EXTENSION_ENABLED
QAbstractItemModel* depInfosView;
#endif
PythonCaller& pythonCaller;
@@ -131,10 +136,12 @@ Q_SIGNALS:
void colorGroupingChanged(ColorGrouping colorgrouping);
private Q_SLOTS:
#ifdef EXTENSION_ENABLED
void on_latencyTreeView_doubleClicked(const QModelIndex& index);
void on_calculateDependencies_clicked();
void on_startLatencyAnalysis_clicked();
void on_startPowerAnalysis_clicked();
#endif
};
#endif // TRACEFILETAB_H

View File

@@ -261,33 +261,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tabDepInfos">
<attribute name="title">
<string>Dependency Information</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_depInfos">
<item>
<widget class="QTreeView" name="depInfosView">
<property name="uniformRowHeights">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="depTabPossiblePhases">
</widget>
</item>
<item>
<widget class="QPushButton" name="calculateDependencies">
<property name="text">
<string>Calculate Dependencies</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabComments">
<attribute name="title">
<string>Comments</string>
@@ -317,7 +290,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tabLatencyAnalysis">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
@@ -330,7 +302,7 @@
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_7">
<layout class="QVBoxLayout" name="latencyLayout">
<item>
<widget class="QPushButton" name="startLatencyAnalysis">
<property name="text">
@@ -366,7 +338,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tabPowerAnalysis">
<property name="enabled">
<bool>true</bool>
@@ -390,15 +361,15 @@
<string>Power and Bandwidth Analysis</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QPushButton" name="startPowerAnalysis">
<property name="text">
<string>Start Analysis</string>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item row="2" column="0">
<layout class="QVBoxLayout" name="powerLayout">
<item>
<widget class="QPushButton" name="startPowerAnalysis">
<property name="text">
<string>Start Analysis</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="powerBox">
<property name="title">
@@ -439,6 +410,43 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tabDepInfos">
<attribute name="title">
<string>Dependency Information</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_depInfos">
<item>
<widget class="QLabel" name="depInfoLabel">
<property name="text">
<string>To display timing dependencies between transaction phases, select the respective phases and press &quot;Calculate Dependencies&quot;. The dependencies can now be displayed in the trace view using the context menu.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="depInfosView">
<property name="uniformRowHeights">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="depTabPossiblePhases"/>
</item>
<item>
<widget class="QPushButton" name="calculateDependencies">
<property name="text">
<string>Calculate Dependencies</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>