merge everything together

Merge branch 'master' of git.rhrk.uni-kl.de:EIT-Wehn/dram.vp.system
This commit is contained in:
Matthias Jung
2016-02-26 21:20:23 +01:00
11 changed files with 201 additions and 18 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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
View File

View File

@@ -118,4 +118,5 @@ FORMS += \
OTHER_FILES += \
common/static/createTraceDB.sql \
scripts/metrics.py \
scripts/tests.py
scripts/tests.py \
scripts/plots.py

View File

@@ -209,4 +209,3 @@ void TraceAnalyzer::on_actionMetrics_triggered()
evaluationTool.activateWindow();
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.toList());
}