merge everything together
Merge branch 'master' of git.rhrk.uni-kl.de:EIT-Wehn/dram.vp.system
This commit is contained in:
@@ -50,7 +50,9 @@ PythonCaller::PythonCaller() :
|
||||
testFunctionName("runTests"),
|
||||
metricModuleName("metrics"),
|
||||
metricFunctionName("calculateMetrics"),
|
||||
pathToScripts(QApplication::applicationDirPath().toStdString() + "/../../DRAMSys/analyzer/scripts/")
|
||||
pathToScripts(QApplication::applicationDirPath().toStdString() + "/../../DRAMSys/analyzer/scripts/"),
|
||||
plotsModuleName("plots"),
|
||||
plotsFunctionName("generatePlots")
|
||||
{
|
||||
Py_Initialize();
|
||||
PyObject *sysPath = PySys_GetObject((char*)"path");
|
||||
@@ -59,10 +61,13 @@ PythonCaller::PythonCaller() :
|
||||
Py_DECREF(path);
|
||||
|
||||
qDebug() << testModuleName.c_str() << testFunctionName.c_str();
|
||||
qDebug() << metricModuleName.c_str() << metricFunctionName.c_str();
|
||||
qDebug() << plotsModuleName.c_str() << plotsFunctionName.c_str();
|
||||
qDebug() << "XXX: " << pathToScripts.c_str();
|
||||
|
||||
pRunTestsFunction = loadFunctionFromModule(testModuleName, testFunctionName);
|
||||
pCalculateMetricsFunction = loadFunctionFromModule(metricModuleName, metricFunctionName);
|
||||
pGenPlotsFunction = loadFunctionFromModule(plotsModuleName, plotsFunctionName);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +98,7 @@ PythonCaller::~PythonCaller()
|
||||
{
|
||||
Py_DECREF(pRunTestsFunction);
|
||||
Py_DECREF(pCalculateMetricsFunction);
|
||||
Py_DECREF(pGenPlotsFunction);
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
@@ -149,3 +155,14 @@ TraceCalculatedMetrics PythonCaller::calculateMetricsOnTrace(QString pathToTrace
|
||||
Py_DECREF(pResult);
|
||||
return result;
|
||||
}
|
||||
|
||||
void PythonCaller::generatePlotsOnTrace(QString pathToTrace)
|
||||
{
|
||||
assert(PyCallable_Check(pGenPlotsFunction));
|
||||
|
||||
PyObject *pArgs = PyTuple_New(1);
|
||||
PyObject *pArgument = PyUnicode_FromString(pathToTrace.toStdString().c_str());
|
||||
PyTuple_SetItem(pArgs, 0, pArgument);
|
||||
PyObject_CallObject(pGenPlotsFunction, pArgs);
|
||||
Py_DECREF(pArgument);
|
||||
}
|
||||
|
||||
@@ -50,11 +50,16 @@ public:
|
||||
~PythonCaller();
|
||||
TraceTestResults runTestsOnTrace(QString pathToTrace);
|
||||
TraceCalculatedMetrics calculateMetricsOnTrace(QString pathToTrace);
|
||||
void generatePlotsOnTrace(QString pathToTrace);
|
||||
|
||||
private:
|
||||
PyObject *pRunTestsFunction, *pCalculateMetricsFunction;
|
||||
PyObject *pGenPlotsFunction;
|
||||
PyObject* loadFunctionFromModule(std::string moduleName, std::string functionName);
|
||||
std::string testModuleName, testFunctionName, metricModuleName, metricFunctionName, pathToScripts;
|
||||
std::string plotsModuleName;
|
||||
std::string plotsFunctionName;
|
||||
|
||||
PyObject *callFunctionWithStringArgument(PyObject *function, QString argument);
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
* Éder F. Zulian
|
||||
*/
|
||||
|
||||
#include <QFileInfo>
|
||||
@@ -203,3 +204,23 @@ void EvaluationTool::on_btn_exportCSV_clicked()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EvaluationTool::on_btn_genPlots_clicked()
|
||||
{
|
||||
genPlots();
|
||||
}
|
||||
|
||||
void EvaluationTool::genPlots()
|
||||
{
|
||||
ui->traceMetricTreeWidget->clear();
|
||||
|
||||
if(traceFilesModel->rowCount() == 0)
|
||||
return;
|
||||
|
||||
PythonCaller pythonCaller;
|
||||
for (int row = 0; row < traceFilesModel->rowCount(); ++row) {
|
||||
TraceFileItem *item = static_cast<TraceFileItem*>(traceFilesModel->item(row));
|
||||
pythonCaller.generatePlotsOnTrace(item->getPath());
|
||||
}
|
||||
ui->traceMetricTreeWidget->expandAll();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
* Éder F. Zulian
|
||||
*/
|
||||
|
||||
#ifndef EVALUATIONTOOL_H
|
||||
@@ -69,14 +70,16 @@ private Q_SLOTS:
|
||||
void on_btn_test_clicked();
|
||||
void setTestMessage(QString message);
|
||||
void on_btn_calculateMetrics_clicked();
|
||||
|
||||
void on_btn_exportCSV_clicked();
|
||||
void on_btn_genPlots_clicked();
|
||||
|
||||
|
||||
private:
|
||||
void fillFileList(QList<QString> paths);
|
||||
void runTests();
|
||||
void calculateMetrics();
|
||||
void cleanUpUI();
|
||||
void genPlots();
|
||||
|
||||
|
||||
Ui::EvaluationTool *ui;
|
||||
|
||||
@@ -137,6 +137,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_genPlots">
|
||||
<property name="text">
|
||||
<string>Generate plots</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_exportCSV">
|
||||
<property name="text">
|
||||
|
||||
14
DRAMSys/analyzer/scripts/memUtil.py
Normal file → Executable file
14
DRAMSys/analyzer/scripts/memUtil.py
Normal file → Executable file
@@ -55,3 +55,17 @@ def getNumberOfBanks(dbconnection):
|
||||
cursor.execute("SELECT NumberOfBanks FROM generalInfo")
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
|
||||
def maximum_data_rate(connection):
|
||||
memspec = MemSpec(connection)
|
||||
memoryType = memspec.getValue("memoryType")
|
||||
if (memoryType.find("DDR") != -1):
|
||||
width = 64
|
||||
else:
|
||||
if (memoryType.find("WIDEIO") != -1):
|
||||
width = memspec.getValue("width")
|
||||
clk = memspec.getValue("clkMhz")
|
||||
rate = memspec.getValue("dataRate")
|
||||
maxDataRate = float(clk)*float(width)*float(rate)
|
||||
return maxDataRate
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
import sqlite3
|
||||
from memUtil import *
|
||||
from math import *
|
||||
|
||||
metrics = []
|
||||
threadMetrics = []
|
||||
@@ -24,20 +25,6 @@ def getThreads(connection):
|
||||
result.append(currentRow[0])
|
||||
return result
|
||||
|
||||
|
||||
# @metric
|
||||
# def latency_histogram(connection):
|
||||
# cursor = connection.cursor()
|
||||
# cursor.execute("SELECT ((p2.PhaseEnd - p1.PhaseEnd)/1000) FROM Transactions t, Phases p1, Phases p2 WHERE t.id = p1.Transact and t.id = p2.Transact and p1.PhaseName = \"REQ\" and p2.PhaseName = \"RESP\" ")
|
||||
# result = cursor.fetchall()
|
||||
# #result.sort()
|
||||
# #print(max(result)[0])
|
||||
# import matplotlib.pyplot as plt
|
||||
# plt.hist(result, bins=max(result)[0], histtype='barstacked')
|
||||
# plt.savefig('hist.png')
|
||||
# return "Saved as hist.png"
|
||||
|
||||
|
||||
# @metric
|
||||
# def average_response_latency_in_ns(connection):
|
||||
# cursor = connection.cursor()
|
||||
@@ -115,6 +102,14 @@ def memory_utilisation_percent_new(connection):
|
||||
return (active/(total-idle))*100
|
||||
|
||||
|
||||
@metric
|
||||
def memory_utilisation_in_Gibps(connection):
|
||||
# This function calculates the memory utilisation in Gibit/s considering the memory_utilisation_percent_new function result.
|
||||
maxDataRate = maximum_data_rate(connection)
|
||||
memoryPercent = memory_utilisation_percent_new(connection)
|
||||
return (memoryPercent/100)*(maxDataRate/1024)
|
||||
|
||||
|
||||
@metric
|
||||
def memory_utilisation_percent_old(connection):
|
||||
cursor = connection.cursor()
|
||||
|
||||
121
DRAMSys/analyzer/scripts/plots.py
Normal file
121
DRAMSys/analyzer/scripts/plots.py
Normal file
@@ -0,0 +1,121 @@
|
||||
import sys
|
||||
import sqlite3
|
||||
from memUtil import *
|
||||
from math import *
|
||||
|
||||
plots = []
|
||||
|
||||
|
||||
def plot(function):
|
||||
plots.append(function)
|
||||
return function
|
||||
|
||||
|
||||
@plot
|
||||
def memory_utilisation_window(connection):
|
||||
# This function determines the average memory bandwidth over time in percentage and in Gbit/s.
|
||||
# The average bandwidth over time is done dividing the time into windows of the same length and getting the average bandwidth in each window.
|
||||
# Through the data from the database, DataStrobeEnd and DataStrobeBegin, it is possible to assess when a data transfer begins or ends.
|
||||
# Hence, it is possible to ckeck when a data transfer happens and if it occupies or is inside a time window. Then, it is possible to determine the average bandwidth in percentage.
|
||||
# Besides, extracting the data from the memory specs, it is possible to calculate the maximum data rate of the memory and then determine the bandwidth in Gbit/s.
|
||||
# The bandwidth data are then plotted in two graphics.
|
||||
|
||||
windowSize = 1000000
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """)
|
||||
total = cursor.fetchone()
|
||||
steps = ceil(float(total[0])/float(windowSize))
|
||||
# print(steps)
|
||||
# All possible cases of data transfers inside a time window
|
||||
queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin > ? and DataStrobeEnd < ?""" # The data transfer begins and ends inside the time window
|
||||
queryEnd = """ SELECT sum(DataStrobeEnd - ?) FROM transactions Where DataStrobeBegin < ? and DataStrobeEnd > ? and DataStrobeEnd <=?""" # Only the end of the data transfer is inside the time window
|
||||
queryBegin = """ SELECT sum(? - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeBegin < ? and DataStrobeEnd > ?""" # Only the beginning of the data transfer is inside the time window
|
||||
queryPart = """ SELECT DataStrobeBegin FROM transactions Where DataStrobeBegin <= ? and DataStrobeEnd >= ?""" # The data transfer occupies all the time window
|
||||
maxDataRate = maximum_data_rate(connection)
|
||||
# print(width)
|
||||
# print(clk)
|
||||
# print(rate)
|
||||
bandwidthPercentage = [0] * steps
|
||||
bandwidth = [0] * steps
|
||||
for i in range(steps):
|
||||
# print(i)
|
||||
bandwidthPercentage[i] = 0
|
||||
cursor.execute(queryPart, (i*windowSize, (i+1)*windowSize))
|
||||
result = cursor.fetchone()
|
||||
if(result is None):
|
||||
cursor.execute(queryFull, (i*windowSize, (i+1)*windowSize))
|
||||
result = cursor.fetchone()
|
||||
if(result[0] is not None):
|
||||
bandwidthPercentage[i] += int(result[0])
|
||||
# print(bandwidthPercentage[i])
|
||||
cursor.execute(queryEnd, (i*windowSize, i*windowSize, i*windowSize, (i+1)*windowSize))
|
||||
result = cursor.fetchone()
|
||||
if(result[0] is not None):
|
||||
bandwidthPercentage[i] += int(result[0])
|
||||
# print(bandwidthPercentage[i])
|
||||
cursor.execute(queryBegin, ((i+1)*windowSize, i*windowSize, (i+1)*windowSize, (i+1)*windowSize))
|
||||
result = cursor.fetchone()
|
||||
if(result[0] is not None):
|
||||
bandwidthPercentage[i] += int(result[0])
|
||||
# print(bandwidthPercentage[i])
|
||||
else:
|
||||
bandwidthPercentage[i] = windowSize
|
||||
# print(bandwidthPercentage[i])
|
||||
bandwidthPercentage[i] = float(bandwidthPercentage[i]/windowSize)
|
||||
bandwidth[i] = float(bandwidthPercentage[i])*float(maxDataRate)/1024
|
||||
bandwidthPercentage[i] *= 100
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
time = np.arange(0, steps*windowSize, windowSize)
|
||||
|
||||
plt.figure(1)
|
||||
plt.plot(time/1000, bandwidthPercentage)
|
||||
plt.xlabel('Time (ns)')
|
||||
plt.ylabel('Bandwidth (%)')
|
||||
plt.ylim(0, 120)
|
||||
plt.grid(True)
|
||||
windowPercentage = PdfPages('windowPercentage.pdf')
|
||||
windowPercentage.savefig()
|
||||
windowPercentage.close()
|
||||
|
||||
plt.figure(2)
|
||||
plt.plot(time/1000, bandwidth)
|
||||
plt.xlabel('Time (ns)')
|
||||
plt.ylabel('Bandwidth (Gibit/s)')
|
||||
plt.grid(True)
|
||||
window = PdfPages('window.pdf')
|
||||
window.savefig()
|
||||
window.close()
|
||||
|
||||
@plot
|
||||
def latency_histogram(connection):
|
||||
# This function plots an histogram with access latencys
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("SELECT ((p2.PhaseEnd - p1.PhaseEnd)/1000) FROM Transactions t, Phases p1, Phases p2 WHERE t.id = p1.Transact and t.id = p2.Transact and p1.PhaseName = \"REQ\" and p2.PhaseName = \"RESP\" ")
|
||||
result = cursor.fetchall()
|
||||
#result.sort()
|
||||
#print(max(result)[0])
|
||||
import matplotlib.pyplot as plt
|
||||
plt.hist(result, bins=max(result)[0], histtype='barstacked')
|
||||
plt.savefig('hist.png')
|
||||
return "Saved as hist.png"
|
||||
|
||||
|
||||
def generatePlots(pathToTrace):
|
||||
connection = sqlite3.connect(pathToTrace)
|
||||
|
||||
print("================================")
|
||||
print("Generating plots for {0}".format(pathToTrace))
|
||||
|
||||
for p in plots:
|
||||
p(connection)
|
||||
|
||||
connection.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
path = sys.argv[1]
|
||||
generatePlots(path)
|
||||
0
DRAMSys/analyzer/scripts/tests.py
Normal file → Executable file
0
DRAMSys/analyzer/scripts/tests.py
Normal file → Executable file
@@ -118,4 +118,5 @@ FORMS += \
|
||||
OTHER_FILES += \
|
||||
common/static/createTraceDB.sql \
|
||||
scripts/metrics.py \
|
||||
scripts/tests.py
|
||||
scripts/tests.py \
|
||||
scripts/plots.py
|
||||
|
||||
@@ -209,4 +209,3 @@ void TraceAnalyzer::on_actionMetrics_triggered()
|
||||
evaluationTool.activateWindow();
|
||||
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.toList());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user