From 54c2bcb54c3f6779d8326dbb050c85bfbac0dd48 Mon Sep 17 00:00:00 2001 From: tony <292224750@qq.com> Date: Fri, 26 May 2023 11:02:48 +0800 Subject: [PATCH 1/2] 1. add pure c++ algorithms 2. add normalized error and error bound evaluation at benchmark 3. update scripts --- Doxyfile | 2 +- benchmark/config_threads16.csv | 8 + .../threads/MM/10/config_threads10.csv | 8 + .../threads/MM/12/config_threads12.csv | 8 + .../threads/MM/14/config_threads14.csv | 8 + .../threads/MM/16/config_threads16.csv | 8 + .../results/threads/MM/2/config_threads2.csv | 8 + .../results/threads/MM/4/config_threads4.csv | 8 + .../results/threads/MM/6/config_threads6.csv | 8 + .../results/threads/MM/8/config_threads8.csv | 8 + benchmark/scripts/scanACol/OoOCommon.py | 125 ++++++ benchmark/scripts/scanACol/accuBar.py | 328 ++++++++++++++++ benchmark/scripts/scanACol/autoParase.py | 87 +++++ benchmark/scripts/scanACol/config_BCoAMM.csv | 6 + benchmark/scripts/scanACol/config_BerCRS.csv | 6 + benchmark/scripts/scanACol/config_CRS.csv | 6 + benchmark/scripts/scanACol/config_CoAMM.csv | 6 + .../scripts/scanACol/config_CounterSketch.csv | 6 + benchmark/scripts/scanACol/config_EWS.csv | 6 + .../scanACol/config_FDAMM.csv} | 2 +- benchmark/scripts/scanACol/config_RAWMM.csv | 6 + benchmark/scripts/scanACol/config_WCR.csv | 6 + benchmark/scripts/scanACol/drawTogether.py | 182 +++++++++ benchmark/scripts/scanACol/groupBar.py | 236 +++++++++++ benchmark/scripts/scanACol/groupBar2.py | 232 +++++++++++ benchmark/scripts/scanACol/groupLine.py | 366 ++++++++++++++++++ benchmark/scripts/scanACol/perfRu.csv | 7 + benchmark/scripts/scanARank/config_BerCRS.csv | 8 + benchmark/scripts/scanARank/config_CRS.csv | 8 + .../scanARank/config_CounterSketch.csv | 8 + benchmark/scripts/scanARank/config_EWS.csv | 8 + benchmark/scripts/scanARank/config_WCR.csv | 8 + .../scripts/scanASparse/config_BerCRS.csv | 8 + benchmark/scripts/scanASparse/config_CRS.csv | 8 + .../scanASparse/config_CounterSketch.csv | 8 + benchmark/scripts/scanASparse/config_EWS.csv | 8 + benchmark/scripts/scanASparse/config_WCR.csv | 8 + .../scripts/scanThreads/config_CPPCRS.csv | 9 + .../scripts/scanThreads/config_CPPMM.csv | 9 + .../scanThreads/config_CounterSketch.csv | 8 + benchmark/scripts/scanThreads/drawTogether.py | 53 ++- benchmark/src/Benchmark.cpp | 23 +- commit.sh | 2 +- commit_info | 5 +- include/AMMBench.h | 26 +- include/CPPAlgos/AbstractCPPAlgo.h | 59 +++ include/CPPAlgos/CPPAlgoTable.h | 59 +++ include/CPPAlgos/CRSCPPAlgo.h | 56 +++ .../Parallelization/BlockPartitionRunner.h | 4 + include/Utils/UtilityFunctions.h | 16 + src/CMakeLists.txt | 1 + src/CPPAlgos/AbstractCPPAlgo.cpp | 10 + src/CPPAlgos/CMakeLists.txt | 5 + src/CPPAlgos/CPPAlgoTable.cpp | 13 + src/CPPAlgos/CRSCPPAlgo.cpp | 33 ++ src/Parallelization/BlockPartitionRunner.cpp | 32 +- test/SystemTest/CRSTest.cpp | 11 + 57 files changed, 2171 insertions(+), 30 deletions(-) create mode 100644 benchmark/config_threads16.csv create mode 100644 benchmark/results/threads/MM/10/config_threads10.csv create mode 100644 benchmark/results/threads/MM/12/config_threads12.csv create mode 100644 benchmark/results/threads/MM/14/config_threads14.csv create mode 100644 benchmark/results/threads/MM/16/config_threads16.csv create mode 100644 benchmark/results/threads/MM/2/config_threads2.csv create mode 100644 benchmark/results/threads/MM/4/config_threads4.csv create mode 100644 benchmark/results/threads/MM/6/config_threads6.csv create mode 100644 benchmark/results/threads/MM/8/config_threads8.csv create mode 100755 benchmark/scripts/scanACol/OoOCommon.py create mode 100755 benchmark/scripts/scanACol/accuBar.py create mode 100755 benchmark/scripts/scanACol/autoParase.py create mode 100644 benchmark/scripts/scanACol/config_BCoAMM.csv create mode 100644 benchmark/scripts/scanACol/config_BerCRS.csv create mode 100644 benchmark/scripts/scanACol/config_CRS.csv create mode 100644 benchmark/scripts/scanACol/config_CoAMM.csv create mode 100644 benchmark/scripts/scanACol/config_CounterSketch.csv create mode 100644 benchmark/scripts/scanACol/config_EWS.csv rename benchmark/{config.csv => scripts/scanACol/config_FDAMM.csv} (87%) create mode 100644 benchmark/scripts/scanACol/config_RAWMM.csv create mode 100644 benchmark/scripts/scanACol/config_WCR.csv create mode 100755 benchmark/scripts/scanACol/drawTogether.py create mode 100755 benchmark/scripts/scanACol/groupBar.py create mode 100755 benchmark/scripts/scanACol/groupBar2.py create mode 100755 benchmark/scripts/scanACol/groupLine.py create mode 100644 benchmark/scripts/scanACol/perfRu.csv create mode 100644 benchmark/scripts/scanARank/config_BerCRS.csv create mode 100644 benchmark/scripts/scanARank/config_CRS.csv create mode 100644 benchmark/scripts/scanARank/config_CounterSketch.csv create mode 100644 benchmark/scripts/scanARank/config_EWS.csv create mode 100644 benchmark/scripts/scanARank/config_WCR.csv create mode 100644 benchmark/scripts/scanASparse/config_BerCRS.csv create mode 100644 benchmark/scripts/scanASparse/config_CRS.csv create mode 100644 benchmark/scripts/scanASparse/config_CounterSketch.csv create mode 100644 benchmark/scripts/scanASparse/config_EWS.csv create mode 100644 benchmark/scripts/scanASparse/config_WCR.csv create mode 100644 benchmark/scripts/scanThreads/config_CPPCRS.csv create mode 100644 benchmark/scripts/scanThreads/config_CPPMM.csv create mode 100644 benchmark/scripts/scanThreads/config_CounterSketch.csv create mode 100644 include/CPPAlgos/AbstractCPPAlgo.h create mode 100644 include/CPPAlgos/CPPAlgoTable.h create mode 100644 include/CPPAlgos/CRSCPPAlgo.h create mode 100644 src/CPPAlgos/AbstractCPPAlgo.cpp create mode 100644 src/CPPAlgos/CMakeLists.txt create mode 100644 src/CPPAlgos/CPPAlgoTable.cpp create mode 100644 src/CPPAlgos/CRSCPPAlgo.cpp diff --git a/Doxyfile b/Doxyfile index f369e258..f495eaab 100755 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "AMMBench" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.1.3 +PROJECT_NUMBER = 0.1.4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/benchmark/config_threads16.csv b/benchmark/config_threads16.csv new file mode 100644 index 00000000..cda63c1a --- /dev/null +++ b/benchmark/config_threads16.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,16,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/10/config_threads10.csv b/benchmark/results/threads/MM/10/config_threads10.csv new file mode 100644 index 00000000..a104a25f --- /dev/null +++ b/benchmark/results/threads/MM/10/config_threads10.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,10,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/12/config_threads12.csv b/benchmark/results/threads/MM/12/config_threads12.csv new file mode 100644 index 00000000..a0bfc782 --- /dev/null +++ b/benchmark/results/threads/MM/12/config_threads12.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,12,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/14/config_threads14.csv b/benchmark/results/threads/MM/14/config_threads14.csv new file mode 100644 index 00000000..a68477f1 --- /dev/null +++ b/benchmark/results/threads/MM/14/config_threads14.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,14,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/16/config_threads16.csv b/benchmark/results/threads/MM/16/config_threads16.csv new file mode 100644 index 00000000..cda63c1a --- /dev/null +++ b/benchmark/results/threads/MM/16/config_threads16.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,16,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/2/config_threads2.csv b/benchmark/results/threads/MM/2/config_threads2.csv new file mode 100644 index 00000000..05e02bb2 --- /dev/null +++ b/benchmark/results/threads/MM/2/config_threads2.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,2,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/4/config_threads4.csv b/benchmark/results/threads/MM/4/config_threads4.csv new file mode 100644 index 00000000..f01b4594 --- /dev/null +++ b/benchmark/results/threads/MM/4/config_threads4.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,4,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/6/config_threads6.csv b/benchmark/results/threads/MM/6/config_threads6.csv new file mode 100644 index 00000000..7a0c4007 --- /dev/null +++ b/benchmark/results/threads/MM/6/config_threads6.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,6,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/results/threads/MM/8/config_threads8.csv b/benchmark/results/threads/MM/8/config_threads8.csv new file mode 100644 index 00000000..bc25d541 --- /dev/null +++ b/benchmark/results/threads/MM/8/config_threads8.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,8,U64 +ptFile,torchscripts/RAWMM.pt,String diff --git a/benchmark/scripts/scanACol/OoOCommon.py b/benchmark/scripts/scanACol/OoOCommon.py new file mode 100755 index 00000000..70f4cf33 --- /dev/null +++ b/benchmark/scripts/scanACol/OoOCommon.py @@ -0,0 +1,125 @@ +import csv +import numpy as np +import matplotlib.pyplot as plt +import itertools as it +import os + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator +import os +import pandas as pd +import sys +import matplotlib.ticker as mtick + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 22 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 30 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (['*', '|', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#FFFFFF', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = (["////", "o", "", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + + +def editConfig(src, dest, key, value): + df = pd.read_csv(src, header=None) + rowIdx = 0 + idxt = 0 + for cell in df[0]: + # print(cell) + if (cell == key): + rowIdx = idxt + break + idxt = idxt + 1 + df[1][rowIdx] = str(value) + df.to_csv(dest, index=False, header=False) + + +def readConfig(src, key): + df = pd.read_csv(src, header=None) + rowIdx = 0 + idxt = 0 + for cell in df[0]: + # print(cell) + if (cell == key): + rowIdx = idxt + break + idxt = idxt + 1 + return df[1][rowIdx] + + +def draw2yLine(NAME, Com, R1, R2, l1, l2, m1, m2, fname): + fig, ax1 = plt.subplots(figsize=(10, 6.4)) + lines = [None] * 2 + # ax1.set_ylim(0, 1) + print(Com) + print(R1) + lines[0], = ax1.plot(Com, R1, color=LINE_COLORS[0], \ + linewidth=LINE_WIDTH, marker=MARKERS[0], \ + markersize=MARKER_SIZE + # + ) + + # plt.show() + ax1.set_ylabel(m1, fontproperties=LABEL_FP) + ax1.set_xlabel(NAME, fontproperties=LABEL_FP) + # ax1.set_xticklabels(ax1.get_xticklabels()) # 设置共用的x轴 + plt.xticks(rotation=0, size=TICK_FONT_SIZE) + plt.yticks(rotation=0, size=TICK_FONT_SIZE) + plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 + ax2 = ax1.twinx() + + # ax2.set_ylabel('latency/us') + # ax2.set_ylim(0, 0.5) + lines[1], = ax2.plot(Com, R2, color=LINE_COLORS[1], \ + linewidth=LINE_WIDTH, marker=MARKERS[1], \ + markersize=MARKER_SIZE) + + ax2.set_ylabel(m2, fontproperties=LABEL_FP) + # ax2.vlines(192000, min(R2)-1, max(R2)+1, colors = "GREEN", linestyles = "dashed",label='total L1 size') + # plt.grid(axis='y', color='gray') + + # style = dict(size=10, color='black') + # ax2.hlines(tset, 0, x2_list[len(x2_list)-1]+width, colors = "r", linestyles = "dashed",label="tset") + # ax2.text(4, tset, "$T_{set}$="+str(tset)+"us", ha='right', **style) + + # plt.xlabel('batch', fontproperties=LABEL_FP) + + # plt.xscale('log') + # figure.xaxis.set_major_locator(LinearLocator(5)) + ax1.yaxis.set_major_locator(LinearLocator(5)) + ax2.yaxis.set_major_locator(LinearLocator(5)) + ax1.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + ax1.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + plt.legend(lines, + [l1, l2], + prop=LEGEND_FP, + loc='upper center', + ncol=1, + bbox_to_anchor=(0.55, 1.3 + ), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=-1.5, handlelength=1.2, + handletextpad=0.1, + labelspacing=0.1) + plt.yticks(rotation=0, size=TICK_FONT_SIZE) + plt.tight_layout() + + plt.savefig(fname + ".pdf") diff --git a/benchmark/scripts/scanACol/accuBar.py b/benchmark/scripts/scanACol/accuBar.py new file mode 100755 index 00000000..638c8a60 --- /dev/null +++ b/benchmark/scripts/scanACol/accuBar.py @@ -0,0 +1,328 @@ +import getopt +import os +import sys + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LinearLocator, LogLocator, MaxNLocator, ScalarFormatter +from numpy import double + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 24 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 26 +TITLE_FRONT_SIZE = 32 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) +TITLE_FP = FontProperties(style='normal', size=TITLE_FRONT_SIZE) +MARKERS = (['o', 's', 'v', "^", "h", "v", ">", "x", "d", "<", "|", "", "|", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ('#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = (["\\", "///", "o", "||", "\\\\", "\\\\", "//////", "//////", ".", "\\\\\\", "\\\\\\"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 0.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +exp_dir = "/data1/xtra" + +FIGURE_FOLDER = exp_dir + '/results/figure' + + +# there are some embedding problems if directly exporting the pdf figure using matplotlib. +# so we generate the eps format first and convert it to pdf. +def ConvertEpsToPdf(dir_filename): + os.system("epstopdf --outfile " + dir_filename + ".pdf " + dir_filename + ".eps") + os.system("rm -rf " + dir_filename + ".eps") + + +class ScalarFormatterForceFormat(ScalarFormatter): + def _set_format(self): # Override function that finds format to use. + self.format = "%1.1f" # Give format here + + +# draw a line chart +def DrawFigure(x_values, y_values, legend_labels, x_label, y_label, filename, allow_legend, title): + # you may change the figure size on your own. + + fig = plt.figure(figsize=(16, 9)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # if not os.path.exists(FIGURE_FOLDER): + # os.makedirs(FIGURE_FOLDER) + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.5 + # draw the bars + bottom_base = np.zeros(len(y_values[0])) + bars = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + bars[i] = plt.bar(index + width / 2, y_values[i], width, hatch=PATTERNS[i], color=LINE_COLORS[i], + label=FIGURE_LABEL[i], bottom=bottom_base, edgecolor='black', linewidth=3) + bottom_base = np.array(y_values[i]) + bottom_base + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL + # mode='expand', + # shadow=False, + # columnspacing=0.25, + # labelspacing=-2.2, + # borderpad=5, + # bbox_transform=ax.transAxes, + # frameon=False, + # columnspacing=5.5, + # handlelength=2, + ) + if allow_legend == True: + handles, labels = figure.get_legend_handles_labels() + if allow_legend == True: + leg = plt.legend(handles[::-1], labels[::-1], + loc='upper center', + # prop=#LEGEND_FP, + # ncol=3, + # bbox_to_anchor=(0.5, 1.25), + # bbox_to_anchor=(1.17, 0.5), + # handletextpad=0.1, + # borderaxespad=0.0, + # handlelength=1.8, + # labelspacing=0.3, + # columnspacing=0.3, + ) + leg.get_frame().set_linewidth(2) + leg.get_frame().set_edgecolor("black") + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index + 0.6 * width, x_values) + yfmt = ScalarFormatterForceFormat() + yfmt.set_powerlimits((0, 0)) + figure.get_yaxis().set_major_formatter(yfmt) + plt.ticklabel_format(axis="y", style="sci", scilimits=(0, 0), useMathText=True) + plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(3)) + # figure.yaxis.set_major_locator(LogLocator(base=10)) + # figure.yaxis.set_major_locator(LinearLocator(6)) + + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + plt.title(title, fontproperties=TITLE_FP) + plt.savefig(filename + ".pdf", bbox_inches='tight', format='pdf') + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LEGEND_FP = FontProperties(style='normal', size=26) + + bars = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + width = 0.3 + for i in range(len(FIGURE_LABEL)): + bars[i] = ax1.bar(x_values, data, width, hatch=PATTERNS[i], color=LINE_COLORS[i], + linewidth=0.2) + + # LEGEND + figlegend = pylab.figure(figsize=(11, 0.5)) + figlegend.legend(bars, FIGURE_LABEL, prop=LEGEND_FP, \ + loc=9, + bbox_to_anchor=(0, 0.4, 1, 1), + ncol=len(FIGURE_LABEL), mode="expand", shadow=False, \ + frameon=False, handlelength=1.1, handletextpad=0.2, columnspacing=0.1) + + figlegend.savefig(FIGURE_FOLDER + '/' + filename + '.pdf') + + +def normalize(y_values): + y_total_values = np.zeros(len(y_values[0])) + + for i in range(len(y_values)): + y_total_values += np.array(y_values[i]) + y_norm_values = [] + + for i in range(len(y_values)): + y_norm_values.append(np.array(y_values[i]) / (y_total_values) * 100) + return y_norm_values + + +# example for reading csv file +def ReadFile(id): + # Creates a list containing w lists, each of h items, all set to 0 + w, h = 5, 3 + y = [[0 for x in range(w)] for y in range(h)] + # print(matches) + max_value = 0 + j = 0 + bound = id + 1 * w + for i in range(id, bound, 1): + cnt = 0 + print(i) + f = open(exp_dir + "/results/breakdown/PMJ_JBCR_NP_{}.txt".format(i), "r") + read = f.readlines() + others = 0 + for x in read: + value = double(x.strip("\n")) + if value > max_value: + max_value = value + elif cnt == 3: # sort + y[0][j] = value + elif cnt == 4: # merge + y[1][j] = value + elif cnt == 5: # join + y[2][j] = value + else: + others += value + # if cnt == 6: + # y[2][j] = others + cnt += 1 + j += 1 + print(y) + return y, max_value + + +if __name__ == "__main__": + id = 119 + try: + opts, args = getopt.getopt(sys.argv[1:], '-i:h', ['test id', 'help']) + except getopt.GetoptError: + print('breakdown.py -id testid') + sys.exit(2) + for opt, opt_value in opts: + if opt in ('-h', '--help'): + print("[*] Help info") + exit() + elif opt == '-i': + print('Test ID:', opt_value) + id = (int)(opt_value) + + x_values = ['10%', '20%', '30%', '40%', '50%'] # sorting step size + + y_values, max_value = ReadFile(id) # 55 + + # y_norm_values = normalize(y_values) + + # break into 4 parts + legend_labels = ['sort', 'merge', 'join'] # , 'others' + + DrawFigure(x_values, y_values, legend_labels, + 'sorting step size', 'cycles per input tuple', + 'breakdown_sort_figure', True) + + # DrawLegend(legend_labels, 'breakdown_radix_legend') + + +def DrawPercentageFigure(x_values, y_values, legend_labels, x_label, y_label, filename, allow_legend, title): + # you may change the figure size on your own. + fig = plt.figure(figsize=(9, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.5 + # draw the bars + bottom_base = np.zeros(len(y_values[0])) + bars = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + bars[i] = plt.bar(index + width / 2, y_values[i], width, hatch=PATTERNS[i], color=LINE_COLORS[i], + label=FIGURE_LABEL[i], bottom=bottom_base, edgecolor='black', linewidth=3) + bottom_base = np.array(y_values[i]) + bottom_base + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL + # mode='expand', + # shadow=False, + # columnspacing=0.25, + # labelspacing=-2.2, + # borderpad=5, + # bbox_transform=ax.transAxes, + # frameon=False, + # columnspacing=5.5, + # handlelength=2, + ) + if allow_legend == True: + handles, labels = figure.get_legend_handles_labels() + if allow_legend == True: + print(handles[::-1], labels[::-1]) + leg = plt.legend(handles[::-1], labels[::-1], + loc='center', + prop=LEGEND_FP, + ncol=3, + bbox_to_anchor=(0.5, 1.2), + handletextpad=0.1, + borderaxespad=0.0, + handlelength=1.8, + labelspacing=0.3, + columnspacing=0.3, + ) + leg.get_frame().set_linewidth(2) + leg.get_frame().set_edgecolor("black") + + # sometimes you may not want to draw legends. + # if allow_legend == True: + # leg=plt.legend(bars, + # FIGURE_LABEL, + # prop=LEGEND_FP, + # loc='right', + # ncol=1, + # # mode='expand', + # bbox_to_anchor=(0.45, 1.1), shadow=False, + # columnspacing=0.1, + # frameon=True, borderaxespad=0.0, handlelength=1.5, + # handletextpad=0.1, + # labelspacing=0.1) + # leg.get_frame().set_linewidth(2) + # leg.get_frame().set_edgecolor("black") + + plt.ylim(0, 100) + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index + 0.5 * width, x_values) + plt.xticks(rotation=30) + + # plt.xlim(0,) + # plt.ylim(0,1) + + plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(6)) + + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + plt.savefig(filename + ".pdf", bbox_inches='tight', format='pdf') diff --git a/benchmark/scripts/scanACol/autoParase.py b/benchmark/scripts/scanACol/autoParase.py new file mode 100755 index 00000000..9375c8e0 --- /dev/null +++ b/benchmark/scripts/scanACol/autoParase.py @@ -0,0 +1,87 @@ +import csv + + +def paraseValidStageNames(a): + nameList = [] + with open(a, 'r') as f: + reader = csv.reader(f) + # reader = [each for each in csv.DictReader(f, delimiter=',')] + result = list(reader) + rows = len(result) + # print('rows=',rows) + firstRow = result[0] + # print(firstRow) + index = 0 + # define what may attract our interest + idxCpu = 0 + idxName = 0 + for i in firstRow: + # print(i) + if (i == 'cpu'): + idxCpu = index + if (i == 'name'): + idxName = index + index = index + 1 + # read the valid stages + vdataEntries = 0 + + for k in range(1, rows): + if (result[k][idxCpu] != 'NA'): + R1 = ((result[k][idxName])) + nameList.append(R1) + return nameList + + +def paraseValidColums(a, nameList, colTitle): + with open(a, 'r') as f: + reader = csv.reader(f) + # reader = [each for each in csv.DictReader(f, delimiter=',')] + result = list(reader) + rows = len(result) + # print('rows=',rows) + firstRow = result[0] + # print(firstRow) + index = 0 + # define what may attract our interest + idxCpu = 0 + idxName = 0 + idxTitle = 0 + for i in firstRow: + # print(i) + if (i == 'cpu'): + idxCpu = index + if (i == 'name'): + idxName = index + if (i == colTitle): + idxTitle = index + index = index + 1 + # read the valid stages + vdataEntries = 0 + ru = [] + for k in range(1, rows): + if (result[k][idxCpu] != 'NA'): + R1 = ((result[k][idxName])) + for j in range(len(nameList)): + if (R1 == nameList[j]): + s = int(result[k][idxTitle]) + ru.append(s) + break + return ru + + +def maxInList(a): + # a in [[1,2] [3,4]] + inLen = len(a[0]) + ru = [] + index = [] + ti = 0 + for i in range(len(a[0])): + ts = 0 + ti = 0 + for k in range(len(a)): + if (a[k][i] > ts): + ts = a[k][i] + ti = k + ru.append(ts) + index.append(ti) + return ru, index diff --git a/benchmark/scripts/scanACol/config_BCoAMM.csv b/benchmark/scripts/scanACol/config_BCoAMM.csv new file mode 100644 index 00000000..aa481d3d --- /dev/null +++ b/benchmark/scripts/scanACol/config_BCoAMM.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/BetaCoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanACol/config_BerCRS.csv b/benchmark/scripts/scanACol/config_BerCRS.csv new file mode 100644 index 00000000..14a0cdc1 --- /dev/null +++ b/benchmark/scripts/scanACol/config_BerCRS.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/BernoulliCRS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanACol/config_CRS.csv b/benchmark/scripts/scanACol/config_CRS.csv new file mode 100644 index 00000000..620247f2 --- /dev/null +++ b/benchmark/scripts/scanACol/config_CRS.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/CRS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanACol/config_CoAMM.csv b/benchmark/scripts/scanACol/config_CoAMM.csv new file mode 100644 index 00000000..765e54de --- /dev/null +++ b/benchmark/scripts/scanACol/config_CoAMM.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/CoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanACol/config_CounterSketch.csv b/benchmark/scripts/scanACol/config_CounterSketch.csv new file mode 100644 index 00000000..79eabd46 --- /dev/null +++ b/benchmark/scripts/scanACol/config_CounterSketch.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/CountSketch.pt,String diff --git a/benchmark/scripts/scanACol/config_EWS.csv b/benchmark/scripts/scanACol/config_EWS.csv new file mode 100644 index 00000000..0a752db9 --- /dev/null +++ b/benchmark/scripts/scanACol/config_EWS.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/EWS.pt,String \ No newline at end of file diff --git a/benchmark/config.csv b/benchmark/scripts/scanACol/config_FDAMM.csv similarity index 87% rename from benchmark/config.csv rename to benchmark/scripts/scanACol/config_FDAMM.csv index 18b9efde..2dac7db7 100644 --- a/benchmark/config.csv +++ b/benchmark/scripts/scanACol/config_FDAMM.csv @@ -1,5 +1,5 @@ key,value,type -aRow,100,U64 +aRow,1000,U64 aCol,1000,U64 bCol,500,U64 sketchDimension,25,U64 diff --git a/benchmark/scripts/scanACol/config_RAWMM.csv b/benchmark/scripts/scanACol/config_RAWMM.csv new file mode 100644 index 00000000..57e126f7 --- /dev/null +++ b/benchmark/scripts/scanACol/config_RAWMM.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/RAWMM.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanACol/config_WCR.csv b/benchmark/scripts/scanACol/config_WCR.csv new file mode 100644 index 00000000..a2b6b73c --- /dev/null +++ b/benchmark/scripts/scanACol/config_WCR.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/WeightedCR.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanACol/drawTogether.py b/benchmark/scripts/scanACol/drawTogether.py new file mode 100755 index 00000000..2222a7b6 --- /dev/null +++ b/benchmark/scripts/scanACol/drawTogether.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 +import csv +import numpy as np +import accuBar as accuBar +import groupBar as groupBar +import groupBar2 as groupBar2 +import groupLine as groupLine +from autoParase import * +import itertools as it +import os + +import matplotlib +import numpy as np +import pylab +import matplotlib.font_manager as fm +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator +import os +import pandas as pd +import sys +from OoOCommon import * +import time + +# OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 22 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 30 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (['*', '|', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#FFFFFF', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = (["////", "o", "", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +scanTag = "aCol" + + +def singleRun(exePath, singleValue, resultPath, configTemplate): + # resultFolder="singleValueTests" + configFname = "config_" + scanTag + str(singleValue) + ".csv" + # configTemplate = "config.csv" + # clear old files + os.system("cd " + exePath + "&& sudo rm *.csv") + + # editConfig(configTemplate, exePath + configFname, "earlierEmitMs", 0) + editConfig(configTemplate, exePath + configFname, scanTag, singleValue) + # prepare new file + # run + os.system("cd " + exePath + "&& sudo ./benchmark " + configFname) + # copy result + os.system("sudo rm -rf " + resultPath + "/" + str(singleValue)) + os.system("sudo mkdir " + resultPath + "/" + str(singleValue)) + os.system("cd " + exePath + "&& sudo cp *.csv " + resultPath + "/" + str(singleValue)) + + +def runScanVector(exePath, singleValueVec, resultPath, templateName="config.csv"): + for i in singleValueVec: + singleRun(exePath, i, resultPath, templateName) + + +def readResultSingle(singleValue, resultPath): + resultFname = resultPath + "/" + str(singleValue) + "/default.csv" + elapsedTime = readConfig(resultFname, "perfElapsedTime") + cacheMiss = readConfig(resultFname, "cacheMiss") + cacheRefs = readConfig(resultFname, "cacheRefs") + return elapsedTime, cacheMiss, cacheRefs + + +def cleanPath(path): + os.system("sudo rm -rf " + path) + os.system("sudo mkdir " + path) + + +def readResultVector(singleValueVec, resultPath): + elapseTimeVec = [] + cacheMissVec = [] + cacheRefVec = [] + for i in singleValueVec: + elapsedTime, cacheMiss, cacheRefs = readResultSingle(i, resultPath) + elapseTimeVec.append(float(elapsedTime) / 1000.0) + cacheMissVec.append(float(cacheMiss)) + cacheRefVec.append(float(cacheRefs)) + return np.array(elapseTimeVec), np.array(cacheMissVec), np.array(cacheRefVec) + + +def compareMethod(exeSpace, commonPathBase, resultPaths, csvTemplates, periodVec, reRun=1): + elapsedTimeAll = [] + cacheMissAll = [] + cacheRefAll = [] + periodAll = [] + for i in range(len(csvTemplates)): + resultPath = commonPathBase + resultPaths[i] + if (reRun == 1): + os.system("sudo rm -rf " + resultPath) + os.system("sudo mkdir " + resultPath) + runScanVector(exeSpace, periodVec, resultPath, csvTemplates[i]) + elapsedTime, cacheMiss, cacheRef = readResultVector(periodVec, resultPath) + elapsedTimeAll.append(elapsedTime) + cacheMissAll.append(cacheMiss) + cacheRefAll.append(cacheRef) + periodAll.append(periodVec) + cacheMissRateAll = np.array(cacheMissAll) / np.array(cacheRefAll) * 100.0 + # periodAll.append(periodVec) + return np.array(elapsedTimeAll), cacheMissRateAll, periodAll + + +def main(): + exeSpace = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/" + commonBase = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag + "/" + figPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/figures/" + scanTag + methodTags = ["FD-AMM", "Co-AMM", "BCo-AMM", "Couter-sketch", "MM"] + resultPaths = ["fd", "co", "co", "cs", "mm"] + csvTemplates = ["config_FDAMM.csv", "config_CoAMM.csv", "config_BCoAMM.csv", "config_CounterSketch.csv", + "config_RAWMM.csv"] + valueVec = [100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000] + valueVecDisp = np.array(valueVec) + # run + reRun = 0 + if (len(sys.argv) < 2): + os.system("mkdir ../../results") + os.system("mkdir ../../figures") + os.system("mkdir " + figPath) + os.system("sudo rm -rf " + commonBase) + os.system("sudo mkdir " + commonBase) + reRun = 1 + # skech + elapsedTimeAll, cacheMissAll, periodAll = compareMethod(exeSpace, commonBase, resultPaths, csvTemplates, valueVec, + reRun) + groupLine.DrawFigure(periodAll, elapsedTimeAll, + methodTags, + "# A's col", "elapsed time (ms)", 0, 1, + figPath + "/" + scanTag + "sketch_elapsedTime", + True) + groupLine.DrawFigureYnormal(periodAll, cacheMissAll, + methodTags, + "# A's col", "cacheMiss (%)", 0, 1, + figPath + "/" + scanTag + "sketch_cacheMiss", + True) + # sampling + resultPaths = ["crs", "bcrs", "ews", "mm"] + csvTemplates = ["config_CRS.csv", "config_BerCRS.csv", "config_EWS.csv", "config_RAWMM.csv"] + methodTags = ["CRS", "Ber-CRS", "EWS", "MM"] + elapsedTimeAll, cacheMissAll, periodAll = compareMethod(exeSpace, commonBase, resultPaths, csvTemplates, valueVec, + reRun) + groupLine.DrawFigure(periodAll, elapsedTimeAll, + methodTags, + "# A's col", "elapsed time (ms)", 0, 1, + figPath + "/" + scanTag + "sampling_elapsedTime", + True) + groupLine.DrawFigureYnormal(periodAll, cacheMissAll, + methodTags, + "# A's col", "cacheMiss (%)", 0, 1, + figPath + "/" + scanTag + "sampling_cacheMiss", + True) + # draw2yLine("watermark time (ms)",singleValueVecDisp,lat95Vec,errVec,"95% Latency (ms)","Error","ms","",figPath+"wm_lat") + # draw2yLine("watermark time (ms)",singleValueVecDisp,thrVec,errVec,"Throughput (KTp/s)","Error","KTp/s","",figPath+"wm_thr") + # draw2yLine("watermark time (ms)",singleValueVecDisp,lat95Vec,compVec,"95% Latency (ms)","Completeness","ms","",figPath+"wm_omp") + # groupLine.DrawFigureYnormal([singleValueVec,singleValueVec],[errVec,aqpErrVec],['w/o aqp',"w/ MeanAqp"],"watermark time (ms)","Error",0,1,figPath+"wm_MeanAqp",True) + # print(errVec) + # print(aqpErrVec) + # print(elapseTimeVecFD) + # readResultsingleValue(50,resultPath) + + +if __name__ == "__main__": + main() diff --git a/benchmark/scripts/scanACol/groupBar.py b/benchmark/scripts/scanACol/groupBar.py new file mode 100755 index 00000000..ef2d9842 --- /dev/null +++ b/benchmark/scripts/scanACol/groupBar.py @@ -0,0 +1,236 @@ +import itertools as it +import os + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 24 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 15 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (["", 'o', 's', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#7FFFFF', '#B03A2E', '#2874A6', '#FFFFFF', '#7FFFFF', '#B03A2E', '#2874A6', '#FFFFFF', '#F5CBA7', '#82E0AA', + '#AEB6BF', + '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = ( + ["////", "\\\\", "//", "o", "*", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +exp_dir = "/data1/xtra" + +FIGURE_FOLDER = exp_dir + '/results/figure' + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LEGEND_FP = FontProperties(style='normal', size=26) + figlegend = pylab.figure(figsize=(16, 0.5)) + bars = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + width = 0.3 + for i in range(len(FIGURE_LABEL)): + bars[i] = ax1.bar(x_values, data, width, + hatch=PATTERNS[i], + color=LINE_COLORS[i], + label=FIGURE_LABEL[i], + edgecolor='black', linewidth=3) + + # LEGEND + + figlegend.legend(bars, FIGURE_LABEL, prop=LEGEND_FP, \ + loc=1, ncol=len(FIGURE_LABEL), mode="expand", shadow=True, \ + frameon=True, handlelength=2, handletextpad=0.3, columnspacing=0.5, + borderaxespad=-0.2, fancybox=True + ) + figlegend.savefig(FIGURE_FOLDER + '/' + filename + '.pdf') + + +# draw a bar chart +def DrawFigure(x_values, y_values, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.08 + # draw the bars + bars = [] + ts = 0 + pos = 0 + gl = len(y_values[0]) + for i in range(len(y_values)): + pos = pos + 3 * width + for j in range(len(y_values[i])): + pos = pos + width + bar = plt.bar(pos, y_values[i][j], width, hatch=PATTERNS[j], color=LINE_COLORS[j], label=FIGURE_LABEL[j], + edgecolor='black', linewidth=3) + bars.append(bar) + ts = ts + 1 + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL, + prop=LEGEND_FP, + ncol=4, + loc='upper center', + # mode='expand', + shadow=False, + bbox_to_anchor=(0.45, 1.6), + columnspacing=0.1, + handletextpad=0.2, + # bbox_transform=ax.transAxes, + # frameon=True, + # columnspacing=5.5, + # handlelength=2, + ) + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index, x_values) + # plt.ticklabel_format(axis="y", style="sci", scilimits=(0, 0)) + # plt.grid(axis='y', color='gray') + # figure.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter()) + + # you may need to tune the xticks position to get the best figure. + # plt.yscale('log') + # + # plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(5)) + # figure.xaxis.set_major_locator(LinearLocator(5)) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + plt.ylim(y_min, y_max) + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# example for reading csv file +def ReadFile(): + y = [] + col1 = [] + col2 = [] + col3 = [] + col4 = [] + col5 = [] + col6 = [] + col7 = [] + col8 = [] + col9 = [] + + for id in it.chain(range(38, 42)): + col9.append(0) + y.append(col9) # this is a lz4_pipe2 empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/NPJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col1.append(x) + y.append(col1) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PRJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col2.append(x) + y.append(col2) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MWAY_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col3.append(x) + y.append(col3) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MPASS_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col4.append(x) + y.append(col4) + + y.append(col9) # this is a lz4_pipe2 empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col5.append(x) + y.append(col5) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col6.append(x) + y.append(col6) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col7.append(x) + y.append(col7) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col8.append(x) + y.append(col8) + return y + + +if __name__ == "__main__": + x_values = ["Stock", "Rovio", "YSB", "DEBS"] + + y_values = ReadFile() + + legend_labels = ['Lazy:', 'NPJ', 'PRJ', 'MWAY', 'MPASS', + 'Eager:', 'SHJ$^{JM}$', 'SHJ$^{JB}$', 'PMJ$^{JM}$', 'PMJ$^{JB}$'] + print(y_values) + DrawFigure(x_values, y_values, legend_labels, + '', 'Latency (ms)', 0, + 400, 'latency_figure_app', False) + + # DrawLegend(legend_labels, 'latency_legend') diff --git a/benchmark/scripts/scanACol/groupBar2.py b/benchmark/scripts/scanACol/groupBar2.py new file mode 100755 index 00000000..31155695 --- /dev/null +++ b/benchmark/scripts/scanACol/groupBar2.py @@ -0,0 +1,232 @@ +import itertools as it +import os + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 24 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 30 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (["", 'o', 's', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#FFFFFF', '#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#00FFFF', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', + '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = ( + ["", "////", "\\\\", "//", "o", "", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", + "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +exp_dir = "/data1/xtra" + +FIGURE_FOLDER = exp_dir + '/results/figure' + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LEGEND_FP = FontProperties(style='normal', size=26) + figlegend = pylab.figure(figsize=(16, 0.5)) + bars = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + width = 0.3 + for i in range(len(FIGURE_LABEL)): + bars[i] = ax1.bar(x_values, data, width, + hatch=PATTERNS[i], + color=LINE_COLORS[i], + label=FIGURE_LABEL[i], + edgecolor='black', linewidth=3) + + # LEGEND + + figlegend.legend(bars, FIGURE_LABEL, prop=LEGEND_FP, \ + loc=1, ncol=len(FIGURE_LABEL), mode="expand", shadow=True, \ + frameon=True, handlelength=2, handletextpad=0.3, columnspacing=0.5, + borderaxespad=-0.2, fancybox=True + ) + figlegend.savefig(FIGURE_FOLDER + '/' + filename + '.pdf') + + +# draw a bar chart +def DrawFigure(x_values, y_values, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.12 + # draw the bars + bars = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + bars[i] = plt.bar(index + i * width + width / 2, + y_values[i], width, + hatch=PATTERNS[i], + color=LINE_COLORS[i], + label=FIGURE_LABEL[i], edgecolor='black', linewidth=3) + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL, + prop=LEGEND_FP, + ncol=3, + loc='upper center', + # mode='expand', + shadow=False, + bbox_to_anchor=(0.45, 1.7), + columnspacing=0.1, + handletextpad=0.2, + # bbox_transform=ax.transAxes, + # frameon=True, + # columnspacing=5.5, + # handlelength=2, + ) + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index + 3 * width, x_values, rotation=30) + + # plt.ticklabel_format(axis="y", style="sci", scilimits=(0, 0)) + # plt.grid(axis='y', color='gray') + # figure.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter()) + + # you may need to tune the xticks position to get the best figure. + # plt.yscale('log') + # + # plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(10)) + # figure.xaxis.set_major_locator(LinearLocator(5)) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# example for reading csv file +def ReadFile(): + y = [] + col1 = [] + col2 = [] + col3 = [] + col4 = [] + col5 = [] + col6 = [] + col7 = [] + col8 = [] + col9 = [] + + for id in it.chain(range(38, 42)): + col9.append(0) + y.append(col9) # this is a fake empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/NPJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col1.append(x) + y.append(col1) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PRJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col2.append(x) + y.append(col2) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MWAY_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col3.append(x) + y.append(col3) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MPASS_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col4.append(x) + y.append(col4) + + y.append(col9) # this is a fake empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col5.append(x) + y.append(col5) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col6.append(x) + y.append(col6) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col7.append(x) + y.append(col7) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col8.append(x) + y.append(col8) + return y + + +if __name__ == "__main__": + x_values = ["Stock", "Rovio", "YSB", "DEBS"] + + y_values = ReadFile() + + legend_labels = ['Lazy:', 'NPJ', 'PRJ', 'MWAY', 'MPASS', + 'Eager:', 'SHJ$^{JM}$', 'SHJ$^{JB}$', 'PMJ$^{JM}$', 'PMJ$^{JB}$'] + print(y_values) + DrawFigure(x_values, y_values, legend_labels, + '', 'Latency (ms)', 0, + 400, 'latency_figure_app', False) + + # DrawLegend(legend_labels, 'latency_legend') diff --git a/benchmark/scripts/scanACol/groupLine.py b/benchmark/scripts/scanACol/groupLine.py new file mode 100755 index 00000000..8110fd3b --- /dev/null +++ b/benchmark/scripts/scanACol/groupLine.py @@ -0,0 +1,366 @@ +import itertools as it +import os +import matplotlib.pyplot as plt +import matplotlib.font_manager as fm +import matplotlib +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import MaxNLocator +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LinearLocator, LogLocator, MaxNLocator, ScalarFormatter +from numpy import double + +# 获取系统中可用的字体路径 +# font_paths = fm.findSystemFonts() +# OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 20 +LABEL_FONT_SIZE = 20 +LEGEND_FONT_SIZE = 20 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (['o', 's', 'v', "^", "h", "v", ">", "x", "d", "<", "|", "p", "+", "_", "%", "|", "|", "|", "|", "|"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#F15854', '#5DA5DA', '#60BD68', '#B276B2', '#DECF3F', '#F17CB0', '#B2912F', '#FAA43A', '#AFAFAF', '#087878', + '#783456', + '#560012', '#431256', "#00AABB", "#AA00BB") +# you may want to change the patterns for different figures +PATTERNS = (["|", "\\", "/", "+", "-", ".", "*", "x", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 13.0 +MARKER_FREQUENCY = 1000 + +# matplotlib.rcParams['ps.useafm'] = True +# matplotlib.rcParams['pdf.use14corefonts'] = True +# matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +# matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +# 创建字体列表 +# Explicitly specify the font path +# 获取系统中可用的字体路径 +font_paths = fm.findSystemFonts() + +# 创建字体列表 +font_list = [] +for font_path in font_paths: + try: + font_name = fm.FontProperties(fname=font_path).get_name() + if font_name not in font_list: + font_list.append(font_name) + except: + pass + +# 配置 matplotlib 使用系统中可用的字体 +plt.rcParams['font.family'] = font_list[0] + +FIGURE_FOLDER = '/data1/xtra/results/figure' + + +# there are some embedding problems if directly exporting the pdf figure using matplotlib. +# so we generate the eps format first and convert it to pdf. +def ConvertEpsToPdf(dir_filename): + os.system("epstopdf --outfile " + dir_filename + ".pdf " + dir_filename + ".eps") + os.system("rm -rf " + dir_filename + ".eps") + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LINE_WIDTH = 8.0 + MARKER_SIZE = 12.0 + LEGEND_FP = FontProperties(style='normal', size=26) + + figlegend = pylab.figure(figsize=(12, 0.5)) + idx = 0 + lines = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + idx = 0 + for group in range(len(FIGURE_LABEL)): + lines[idx], = ax1.plot(x_values, data, + color=LINE_COLORS[idx], linewidth=LINE_WIDTH, + marker=MARKERS[idx], markersize=MARKER_SIZE, label=str(group)) + idx = idx + 1 + + # LEGEND + figlegend.legend(lines, FIGURE_LABEL, prop=LEGEND_FP, + loc=1, ncol=len(FIGURE_LABEL), mode="expand", shadow=False, + frameon=False, borderaxespad=0.0, handlelength=2) + + if not os.path.exists(FIGURE_FOLDER): + os.makedirs(FIGURE_FOLDER) + # no need to export eps in this case. + figlegend.savefig(filename + '.pdf') + + +# draw a line chart +def DrawFigure(xvalues, yvalues, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + x_values = xvalues + y_values = yvalues + + lines = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + lines[i], = figure.plot(x_values[i], y_values[i], color=LINE_COLORS[i], \ + linewidth=LINE_WIDTH, marker=MARKERS[i], \ + markersize=MARKER_SIZE, label=FIGURE_LABEL[i]) + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(lines, + FIGURE_LABEL, + prop=LEGEND_FP, + loc='upper center', + ncol=3, + # mode='expand', + bbox_to_anchor=(0.55, 1.6), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=0.0, handlelength=1.5, + handletextpad=0.1, + labelspacing=0.1) + plt.xscale('log') + plt.yscale('log') + # plt.yscale('log') + + # you may control the limits on your own. + + # plt.ylim(y_min, y_max) + + plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LogLocator(base=10)) + figure.xaxis.set_major_locator(LogLocator(base=10)) + + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + # plt.show() + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# draw a line chart +def DrawFigureXYnormal(xvalues, yvalues, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + x_values = xvalues + y_values = yvalues + + lines = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + lines[i], = figure.plot(x_values[i], y_values[i], color=LINE_COLORS[i], \ + linewidth=LINE_WIDTH, marker=MARKERS[i], \ + markersize=MARKER_SIZE, label=FIGURE_LABEL[i], markeredgecolor='k') + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(lines, + FIGURE_LABEL, + prop=LEGEND_FP, + loc='upper center', + ncol=3, + bbox_to_anchor=(0.55, 1.5), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=0, handlelength=1.2, + handletextpad=0.1, + labelspacing=0.1) + # plt.xscale('log') + # plt.yscale('log') + # plt.yscale('log') + + # you may control the limits on your own. + + # plt.ylim(y_min, y_max) + + plt.grid(axis='y', color='gray') + plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 + # figure.yaxis.set_major_locator(LogLocator(base=10)) + # figure.xaxis.set_major_locator(LogLocator(base=10)) + plt.xticks(rotation=0, fontsize=TICK_FONT_SIZE) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + # plt.show() + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# draw a line chart +def DrawFigureYnormal(xvalues, yvalues, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + x_values = xvalues + y_values = yvalues + + lines = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + lines[i], = figure.plot(x_values[i], y_values[i], color=LINE_COLORS[i], \ + linewidth=LINE_WIDTH, marker=MARKERS[i], \ + markersize=MARKER_SIZE, label=FIGURE_LABEL[i], markeredgecolor='k') + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(lines, + FIGURE_LABEL, + prop=LEGEND_FP, + loc='upper center', + ncol=3, + bbox_to_anchor=(0.55, 1.5), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=0, handlelength=1.2, + handletextpad=0.1, + labelspacing=0.1) + plt.xscale('log') + # plt.yscale('log') + # plt.yscale('log') + + # you may control the limits on your own. + + # plt.ylim(y_min, y_max) + + plt.grid(axis='y', color='gray') + plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 + # figure.yaxis.set_major_locator(LogLocator(base=10)) + # figure.xaxis.set_major_locator(LogLocator(base=10)) + plt.xticks(rotation=0, fontsize=TICK_FONT_SIZE) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + # plt.show() + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# example for reading csv file +def ReadFile(): + y = [] + col1 = [] + col2 = [] + col3 = [] + col4 = [] + col5 = [] + col6 = [] + col7 = [] + col8 = [] + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/PRJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col1.append(value) + y.append(col1) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/NPJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col2.append(value) + y.append(col2) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/MPASS_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col3.append(value) + y.append(col3) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/MWAY_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col4.append(value) + y.append(col4) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/SHJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col5.append(value) + y.append(col5) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/SHJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col6.append(value) + y.append(col6) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/PMJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col7.append(value) + y.append(col7) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/PMJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col8.append(value) + y.append(col8) + return y + + +if __name__ == "__main__": + # x_values = ['Unique', 'Zipf(0)', 'Zipf(0.2)', 'Zipf(0.4)', 'Zipf(0.8)', 'Zipf(1)'] + x_values = [1600, 3200, 6400, 12800, 25600] + + y_values = ReadFile() + + legend_labels = ['NPJ', 'PRJ', 'MWAY', 'MPASS', 'SHJ$^{JM}$', 'SHJ$^{JB}$', 'PMJ$^{JM}$', + 'PMJ$^{JB}$'] + + DrawFigure(x_values, y_values, legend_labels, + 'Input arrival rate of R (e/ms)', 'Tpt. (#matches/ms)', x_values[0], + x_values[4], 'throughput_figure1_1', False) + +# DrawLegend(legend_labels, 'factor_legend') diff --git a/benchmark/scripts/scanACol/perfRu.csv b/benchmark/scripts/scanACol/perfRu.csv new file mode 100644 index 00000000..9ee43623 --- /dev/null +++ b/benchmark/scripts/scanACol/perfRu.csv @@ -0,0 +1,7 @@ +key,value,type +cacheMiss,12491377,U64 +cacheRefs,35327177,U64 +cpuClock,2478812100,U64 +cpuCycle,9889422467,U64 +instructions,16997458033,U64 +taskClock,2478813000,U64 diff --git a/benchmark/scripts/scanARank/config_BerCRS.csv b/benchmark/scripts/scanARank/config_BerCRS.csv new file mode 100644 index 00000000..c93329a4 --- /dev/null +++ b/benchmark/scripts/scanARank/config_BerCRS.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +ptFile,torchscripts/BernoulliCRS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/config_CRS.csv b/benchmark/scripts/scanARank/config_CRS.csv new file mode 100644 index 00000000..1673f294 --- /dev/null +++ b/benchmark/scripts/scanARank/config_CRS.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +ptFile,torchscripts/CRS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/config_CounterSketch.csv b/benchmark/scripts/scanARank/config_CounterSketch.csv new file mode 100644 index 00000000..b00e3f45 --- /dev/null +++ b/benchmark/scripts/scanARank/config_CounterSketch.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +ptFile,torchscripts/CountSketch.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/config_EWS.csv b/benchmark/scripts/scanARank/config_EWS.csv new file mode 100644 index 00000000..dcc5da3f --- /dev/null +++ b/benchmark/scripts/scanARank/config_EWS.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +ptFile,torchscripts/EWS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/config_WCR.csv b/benchmark/scripts/scanARank/config_WCR.csv new file mode 100644 index 00000000..9362de33 --- /dev/null +++ b/benchmark/scripts/scanARank/config_WCR.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +ptFile,torchscripts/WeightedCR.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/config_BerCRS.csv b/benchmark/scripts/scanASparse/config_BerCRS.csv new file mode 100644 index 00000000..ad415720 --- /dev/null +++ b/benchmark/scripts/scanASparse/config_BerCRS.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aDensity,1.0,Double +matrixLoaderTag,sparse,String +ptFile,torchscripts/BernoulliCRS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/config_CRS.csv b/benchmark/scripts/scanASparse/config_CRS.csv new file mode 100644 index 00000000..fd25bb29 --- /dev/null +++ b/benchmark/scripts/scanASparse/config_CRS.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aDensity,1.0,Double +matrixLoaderTag,sparse,String +ptFile,torchscripts/CRS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/config_CounterSketch.csv b/benchmark/scripts/scanASparse/config_CounterSketch.csv new file mode 100644 index 00000000..f87bdc6d --- /dev/null +++ b/benchmark/scripts/scanASparse/config_CounterSketch.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aDensity,1.0,Double +matrixLoaderTag,sparse,String +sketchDimension,25,U64 +ptFile,torchscripts/CountSketch.pt,String diff --git a/benchmark/scripts/scanASparse/config_EWS.csv b/benchmark/scripts/scanASparse/config_EWS.csv new file mode 100644 index 00000000..dd7479e7 --- /dev/null +++ b/benchmark/scripts/scanASparse/config_EWS.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aDensity,1.0,Double +matrixLoaderTag,sparse,String +ptFile,torchscripts/EWS.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/config_WCR.csv b/benchmark/scripts/scanASparse/config_WCR.csv new file mode 100644 index 00000000..f56a311e --- /dev/null +++ b/benchmark/scripts/scanASparse/config_WCR.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +aDensity,1.0,Double +matrixLoaderTag,sparse,String +ptFile,torchscripts/WeightedCR.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanThreads/config_CPPCRS.csv b/benchmark/scripts/scanThreads/config_CPPCRS.csv new file mode 100644 index 00000000..132e789a --- /dev/null +++ b/benchmark/scripts/scanThreads/config_CPPCRS.csv @@ -0,0 +1,9 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +threads,1,U64 +ptFile,torchscripts/CRS.pt,String +useCPP,1,U64 +cppAlgoTag,crs,String \ No newline at end of file diff --git a/benchmark/scripts/scanThreads/config_CPPMM.csv b/benchmark/scripts/scanThreads/config_CPPMM.csv new file mode 100644 index 00000000..ef200e05 --- /dev/null +++ b/benchmark/scripts/scanThreads/config_CPPMM.csv @@ -0,0 +1,9 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +threads,1,U64 +ptFile,torchscripts/RAWMM.pt,String +useCPP,1,U64 +cppAlgoTag,mm,String \ No newline at end of file diff --git a/benchmark/scripts/scanThreads/config_CounterSketch.csv b/benchmark/scripts/scanThreads/config_CounterSketch.csv new file mode 100644 index 00000000..1b3e6676 --- /dev/null +++ b/benchmark/scripts/scanThreads/config_CounterSketch.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,10000,U64 +aDensity,1.0,Double +matrixLoaderTag,sparse,String +sketchDimension,25,U64 +ptFile,torchscripts/CountSketch.pt,String diff --git a/benchmark/scripts/scanThreads/drawTogether.py b/benchmark/scripts/scanThreads/drawTogether.py index 0537294e..b8173658 100755 --- a/benchmark/scripts/scanThreads/drawTogether.py +++ b/benchmark/scripts/scanThreads/drawTogether.py @@ -79,7 +79,9 @@ def readResultSingle(singleValue, resultPath): elapsedTime = readConfig(resultFname, "perfElapsedTime") cacheMiss = readConfig(resultFname, "cacheMiss") cacheRefs = readConfig(resultFname, "cacheRefs") - return elapsedTime, cacheMiss, cacheRefs + froError = readConfig(resultFname, "froError") + errorBoundRatio=readConfig(resultFname, "errorBoundRatio") + return elapsedTime, cacheMiss, cacheRefs,froError,errorBoundRatio def cleanPath(path): @@ -91,12 +93,16 @@ def readResultVector(singleValueVec, resultPath): elapseTimeVec = [] cacheMissVec = [] cacheRefVec = [] + froErrorVec = [] + errorBoundRatioVec=[] for i in singleValueVec: - elapsedTime, cacheMiss, cacheRefs = readResultSingle(i, resultPath) + elapsedTime, cacheMiss, cacheRefs,froError,errorBoundRatio = readResultSingle(i, resultPath) elapseTimeVec.append(float(elapsedTime) / 1000.0) cacheMissVec.append(float(cacheMiss)) cacheRefVec.append(float(cacheRefs)) - return np.array(elapseTimeVec), np.array(cacheMissVec), np.array(cacheRefVec) + froErrorVec.append(float(froError)) + errorBoundRatioVec.append(float(errorBoundRatio)) + return np.array(elapseTimeVec), np.array(cacheMissVec), np.array(cacheRefVec),np.array(froErrorVec),np.array(errorBoundRatioVec) def compareMethod(exeSpace, commonPathBase, resultPaths, csvTemplates, periodVec, reRun=1): @@ -104,20 +110,24 @@ def compareMethod(exeSpace, commonPathBase, resultPaths, csvTemplates, periodVec cacheMissAll = [] cacheRefAll = [] periodAll = [] + froAll=[] + errorBoundRatioAll=[] for i in range(len(csvTemplates)): resultPath = commonPathBase + resultPaths[i] if (reRun == 1): os.system("sudo rm -rf " + resultPath) os.system("sudo mkdir " + resultPath) runScanVector(exeSpace, periodVec, resultPath, csvTemplates[i]) - elapsedTime, cacheMiss, cacheRef = readResultVector(periodVec, resultPath) + elapsedTime, cacheMiss, cacheRef,fro,eb = readResultVector(periodVec, resultPath) elapsedTimeAll.append(elapsedTime) cacheMissAll.append(cacheMiss) cacheRefAll.append(cacheRef) periodAll.append(periodVec) cacheMissRateAll = np.array(cacheMissAll) / np.array(cacheRefAll) * 100.0 + froAll.append(fro) + errorBoundRatioAll.append(eb) # periodAll.append(periodVec) - return np.array(elapsedTimeAll), cacheMissRateAll, periodAll + return np.array(elapsedTimeAll), cacheMissRateAll, periodAll,np.array(froAll),np.array(errorBoundRatioAll) def main(): @@ -126,10 +136,10 @@ def main(): figPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/figures/" + scanTag configTemplate = exeSpace + "config.csv" commonBase = resultPath + "/" - resultPaths = ["MM"] - csvTemplates = ["config_RAWMM.csv"] - evaTypes = ['mm'] - valueVec = [2, 4, 6, 8, 10, 12, 14, 16] + resultPaths = ["CRS","CRSRAW","MM","MMRAW"] + csvTemplates = ["config_CPPCRS.csv","config_CRS.csv","config_RAWMM.csv","config_CPPMM.csv"] + evaTypes = ['crs-cpp','crs-pt','mm-pt','mm-cpp'] + valueVec = [2, 4, 6, 8, 10, 12] valueVecRun = valueVec print(configTemplate) reRun = 0 @@ -145,11 +155,17 @@ def main(): tRows = len(resultPaths) tCols = len(valueVec) elapseTimeAllSum = np.zeros((tRows, tCols)) + froErroAllSum = np.zeros((tRows, tCols)) + errorBoundRatioSum= np.zeros((tRows, tCols)) rounds = 1 for i in range(rounds): - elapseTimeAll, ch, periodAll = compareMethod(exeSpace, commonBase, resultPaths, csvTemplates, valueVec, reRun) + elapseTimeAll, ch, periodAll,fro,eb = compareMethod(exeSpace, commonBase, resultPaths, csvTemplates, valueVec, reRun) elapseTimeAllSum = elapseTimeAllSum + elapseTimeAll - elapseTimeAllSum = elapseTimeAllSum / float(rounds) + froErroAllSum = froErroAllSum + fro + errorBoundRatioSum = errorBoundRatioSum+eb + elapseTimeAllSum = elapseTimeAllSum / float(rounds) + froErroAllSum = froErroAllSum / float(rounds) + errorBoundRatioSum = errorBoundRatioSum/float(rounds) # evaTypes = ['FDAMM', 'MM', 'Co-FD', 'BCO-FD'] # elapseTimeVecFD, cacheMissVecFD, cacheRefVecFD = readResultVector(valueVecRun, resultPathFDAMM) @@ -158,11 +174,20 @@ def main(): # os.system("mkdir " + figPath) groupLine.DrawFigureXYnormal(periodAll, - elapseTimeAllSum, + 1/elapseTimeAllSum, evaTypes, - "#threads", "elapsed time (ms)", 0, 1, figPath + "threads" + "_elapsedTime", + "#threads", "1/elapsed time (1/ms)", 0, 1, figPath + "/"+"threads" + "_elapsedTime", + True) + groupLine.DrawFigureXYnormal(periodAll, + froErroAllSum*100.0, + evaTypes, + "#threads", "normalized error %", 0, 1, figPath + "/"+"threads" + "_froError", + True) + groupLine.DrawFigureXYnormal(periodAll, + errorBoundRatioSum*100.0, + evaTypes, + "#threads", "error bound ratio %", 0, 1, figPath + "/"+"threads" + "_ebRatio", True) - # draw2yLine("watermark time (ms)",singleValueVecDisp,lat95Vec,errVec,"95% Latency (ms)","Error","ms","",figPath+"wm_lat") # draw2yLine("watermark time (ms)",singleValueVecDisp,thrVec,errVec,"Throughput (KTp/s)","Error","KTp/s","",figPath+"wm_thr") # draw2yLine("watermark time (ms)",singleValueVecDisp,lat95Vec,compVec,"95% Latency (ms)","Completeness","ms","",figPath+"wm_omp") diff --git a/benchmark/src/Benchmark.cpp b/benchmark/src/Benchmark.cpp index 064e46b0..b2cf2d75 100644 --- a/benchmark/src/Benchmark.cpp +++ b/benchmark/src/Benchmark.cpp @@ -21,6 +21,7 @@ void runSingleThreadTest(std::string configName) { uint64_t coreBind = cfg->tryU64("coreBind", 0, true); uint64_t usingMeter = cfg->tryU64("usingMeter", 0, true); std::string meterTag = cfg->tryString("meterTag", "intelMsr", true); + uint64_t useCPP = cfg->tryU64("useCPP", 0, true); if (usingMeter) { eMeter = meterTable.findMeter(meterTag); if (eMeter != nullptr) { @@ -55,6 +56,7 @@ void runSingleThreadTest(std::string configName) { matLoaderPtr->setConfig(cfg); auto A = matLoaderPtr->getA(); auto B = matLoaderPtr->getB(); + torch::Tensor C; //555 /*torch::manual_seed(114514); //555 @@ -73,18 +75,26 @@ auto B = torch::rand({(long) aCol, (long) bCol});*/ eMeter->startMeter(); } pef.start(); - auto c = br.parallelForward(); + C = br.parallelForward(); pef.end(); if (eMeter != nullptr) { eMeter->stopMeter(); } } else { + AMMBench::CPPAlgoTable cppAlgoTable; + std::string cppAlgoTag = cfg->tryString("cppAlgoTag", "mm", true); + AMMBench::AbstractCPPAlgoPtr cppAlgoPtr = cppAlgoTable.findCppAlgo(cppAlgoTag); INTELLI_WARNING("single thread"); if (eMeter != nullptr) { eMeter->startMeter(); } pef.start(); - auto C =module.forward({A, B, (long) sketchDimension}).toTensor(); + if (useCPP && cppAlgoPtr) { + INTELLI_WARNING("this is pure c++"); + C = cppAlgoPtr->amm(A, B, sketchDimension); + } else { + C =module.forward({A, B, (long) sketchDimension}).toTensor(); + } pef.end(); if (eMeter != nullptr) { eMeter->stopMeter(); @@ -107,6 +117,15 @@ auto B = torch::rand({(long) aCol, (long) bCol});*/ INTELLI_WARNING("consider multithread elapsed time"); resultCsv->edit("perfElapsedTime", (uint64_t) br.getElapsedTime()); } + // error + INTELLI_WARNING("evaluating the error, may takes some time"); + torch::Tensor realC = torch::matmul(A, B); + double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, C); + double froBNormal = B.norm().item(); + double errorBoundRatio = froError / froBNormal; + INTELLI_INFO("B normal is " + to_string(froBNormal)); + resultCsv->edit("froError", (double) froError); + resultCsv->edit("errorBoundRatio", (double) errorBoundRatio); resultCsv->toFile(ruName + ".csv"); INTELLI_INFO("Done. here is result"); std::cout << resultCsv->toString() << endl; diff --git a/commit.sh b/commit.sh index 38f37374..17cba7b4 100755 --- a/commit.sh +++ b/commit.sh @@ -1,4 +1,4 @@ -BRANCH=NIGHTY_TEST +BRANCH=NIGHTLY_TEST git init git checkout -b $BRANCH git add . diff --git a/commit_info b/commit_info index 41cad1f1..123ecae8 100644 --- a/commit_info +++ b/commit_info @@ -1,2 +1,3 @@ -1. experimental support of parallelization -2. example scripts at benchmark/scripts/scanThreads +1. add pure c++ algorithms +2. add normalized error and error bound evaluation at benchmark +3. update scripts diff --git a/include/AMMBench.h b/include/AMMBench.h index af8778af..84e5da35 100755 --- a/include/AMMBench.h +++ b/include/AMMBench.h @@ -28,6 +28,9 @@ * - coreBind (U64) the specific core tor run this benchmark, default 0 * - ptFile (String) the path for the *.pt to be loaded, default torchscripts/FDAMM.pt * - matrixLoaderTag (String) the nameTag of matrix loader, see @ref MatrixLoaderTable, default is random + * - useCPP (U64) force the benchmark to use static and pure cpp implementation instead of pt, default 0 + * - cppAlgoTag (String) The algorithm tag to index a cpp algorithm, works only under useCPP=1, default "mm", + * see also @ref CPPAlgoTable * @note Additional tags for energy measurement (please validate usingMeter first) see also @ref INTELLI_UTIL_METER * - usingMeter (U64) set to 1 if you want to use some energy meter, default diabled * - meterTag (String) the tag of meter, see also @ref MeterTable, default is intelMsr @@ -35,11 +38,17 @@ * - meterAddress (String) set this to the file system path of the meter, if it is different from the meter's default * @warning For some platforms, the staticPower automatically measured by sleep is not accurate. Please do this mannulally. See also the template config.csv - * @section subsec_extend_operator How to extend a new algorithm + * @section subsec_extend_operator How to extend a new algorithm (pt-based) * - go to the benchmark/torchscripts * - find any .python as an example * - copy and modify it and generate the *pt, please make it under hump style of naming * - the system will then support it by using the name of your pt. + * @section subsec_extend_cpp_operator How to extend a new algorithm (pure static c++ based) + * - go to the src/CPPAlgos and include/CPPAlgos + * - copy the example class, such as CRSCPPAlgo, rename it, and implement your own @ref amm function + * - register tour function with a tag to src/CPPAlgos/CPPAlgoTable.cpp + * - edit the CMakelist.txt at src/CPPAlgos to include your new algo and recompile + * - remember to add a test bench, you can refer to CRSTest.cpp at test/SystemTest for example * @section subsec_edit_test How to add a single point test * - copy your config file to test/scripts, and your pt file to test/torchscripts * - follow and copy the SketchTest.cpp to create your own, say A.cpp @@ -78,6 +87,21 @@ #include /** * @} + * + */ +/** +* @subsection code_stru_cppalgo c++ algorithms +* This folder contains the agorithms implemented under pure c++ +* @defgroup AMMBENCH_CppAlgos The c++ amm algorithms +* @{ +* We define the c++ algorithm classes of AMM. here +**/ +#include +#include +#include +/** + * @} + * */ /*** * @subsection code_stru_utils Utils diff --git a/include/CPPAlgos/AbstractCPPAlgo.h b/include/CPPAlgos/AbstractCPPAlgo.h new file mode 100644 index 00000000..eebc94cb --- /dev/null +++ b/include/CPPAlgos/AbstractCPPAlgo.h @@ -0,0 +1,59 @@ +/*! \file AbstractCPPAlgo.h*/ +// +// Created by tony on 25/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_CPPALGOS_ABSTRACTCPPALGO_H_ +#define INTELLISTREAM_INCLUDE_CPPALGOS_ABSTRACTCPPALGO_H_ +#include +#include +#include +#include +#include +#include +namespace AMMBench { +/** + * @ingroup AMMBENCH_CppAlgos The algorithms writtrn in c++ + * @{ + */ +/** + * @class AbstractCPPAlgo CPPAlgos/AbstractCPPAlgo.h + * @brief The abstract class of c++ algos + */ +class AbstractCPPAlgo { + public: + AbstractCPPAlgo() { + + } + ~AbstractCPPAlgo() { + + } + /** + * @brief the virtual function provided for outside callers, rewrite in children classes + * @param A the A matrix + * @param B the B matrix + * @param sketchSize the size of sketc or sampling + * @return the output c matrix + */ + virtual torch::Tensor amm(torch::Tensor A, torch::Tensor B, uint64_t sketchSize); + +}; +/** + * @ingroup AMMBENCH_CppAlgos + * @typedef AbstractMatrixCppAlgoPtr + * @brief The class to describe a shared pointer to @ref AbstractCPPAlgo + + */ +typedef std::shared_ptr AbstractCPPAlgoPtr; +/** + * @ingroup AMMBENCH_CppAlgos + * @def newAbstractCppAlgo + * @brief (Macro) To creat a new @ref AbstractCppAlgounder shared pointer. + */ +#define newAbstractCPPAlgo std::make_shared +} +/** + * @} + */ + +#endif //INTELLISTREAM_INCLUDE_CPPALGOS_ABSTRACTCPPALGO_H_ diff --git a/include/CPPAlgos/CPPAlgoTable.h b/include/CPPAlgos/CPPAlgoTable.h new file mode 100644 index 00000000..2773557b --- /dev/null +++ b/include/CPPAlgos/CPPAlgoTable.h @@ -0,0 +1,59 @@ +/*! \file CPPAlgoTable.h*/ +// +// Created by tony on 25/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_CPPALGOS_CPPALGOTABLE_H_ +#define INTELLISTREAM_INCLUDE_CPPALGOS_CPPALGOTABLE_H_ + +#include +#include +namespace AMMBench { +/** + * @ingroup AMMBENCH_CppAlgos The algorithms writtrn in c++ + * @{ + */ +/** +* @class CPPAlgoTable CPPAlgos/CPPAlgoTable.h +* @brief The table to index cpp algos + * @note Default behavior +* - create +* - (optional) call @ref registerNewCppAlgo for new algo +* - find a loader by @ref findCppAlgo using its tag + * @note default tags + * - mm @ref AbstractCPPAlgo (default matmul) + * - crs @ref CRSCPPAlgo (the column-row-sampling, crs) +*/ +class CPPAlgoTable { + protected: + std::map algoMap; + public: + CPPAlgoTable(); + ~CPPAlgoTable() {} + /** + * @brief To register a new ALGO + * @param anew The new algo + * @param tag THe name tag + */ + void registerNewCppAlgo(AMMBench::AbstractCPPAlgoPtr anew, std::string tag) { + algoMap[tag] = anew; + } + + /** + * @brief find a dataloader in the table according to its name + * @param name The nameTag of loader + * @return The AbstractCppAlgoPtr, nullptr if not found + */ + AMMBench::AbstractCPPAlgoPtr findCppAlgo(std::string name) { + if (algoMap.count(name)) { + return algoMap[name]; + } + return nullptr; + } +}; +/** + * @} + */ +} // AMMBench + +#endif //INTELLISTREAM_INCLUDE_CPPALGOS_CPPALGOTABLE_H_ diff --git a/include/CPPAlgos/CRSCPPAlgo.h b/include/CPPAlgos/CRSCPPAlgo.h new file mode 100644 index 00000000..bbb7b6a6 --- /dev/null +++ b/include/CPPAlgos/CRSCPPAlgo.h @@ -0,0 +1,56 @@ +/*! \file CRSCPPAlgo.h*/ +// +// Created by tony on 25/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_CPPALGOS_CRSCppAlgo_H_ +#define INTELLISTREAM_INCLUDE_CPPALGOS_CRSCppAlgo_H_ +#include +namespace AMMBench { +/** + * @ingroup AMMBENCH_CppAlgos The algorithms writtrn in c++ + * @{ + */ +/** + * @class CRSCPPlgo CPPAlgos/CRSCPPAlgo.h + * @brief The cloumn row sampling (CRS) class of c++ algos + * + */ +class CRSCPPAlgo : public AMMBench::AbstractCPPAlgo { + public: + CRSCPPAlgo() { + + } + ~CRSCPPAlgo() { + + } + /** + * @brief the virtual function provided for outside callers, rewrite in children classes + * @param A the A matrix + * @param B the B matrix + * @param sketchSize the size of sketc or sampling + * @return the output c matrix + */ + virtual torch::Tensor amm(torch::Tensor A, torch::Tensor B, uint64_t sketchSize); + +}; +/** + * @ingroup AMMBENCH_CppAlgos + * @typedef AbstractMatrixCppAlgoPtr + * @brief The class to describe a shared pointer to @ref CRSCppAlgo + + */ +typedef std::shared_ptr CRSCPPAlgoPtr; +/** + * @ingroup AMMBENCH_CppAlgos + * @def newCRSCppAlgo + * @brief (Macro) To creat a new @ref CRSCppAlgounder shared pointer. + */ +#define newCRSCPPAlgo std::make_shared +} +/** + * @} + */ + +#endif //INTELLISTREAM_INCLUDE_CPPALGOS_CRSCppAlgo_H_ + diff --git a/include/Parallelization/BlockPartitionRunner.h b/include/Parallelization/BlockPartitionRunner.h index eb9a5edf..38e348c1 100644 --- a/include/Parallelization/BlockPartitionRunner.h +++ b/include/Parallelization/BlockPartitionRunner.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace AMMBench { #define newTensor make_shared @@ -28,7 +29,10 @@ typedef std::shared_ptr TensorPtr; class BlockPartitionWorker : public INTELLI::AbstractC20Thread { protected: virtual void inlineMain(); + AMMBench::CPPAlgoTable cppAlgoTable; struct timeval tstart, tend; + uint64_t useCPP = 0; + AMMBench::AbstractCPPAlgoPtr cppAlgoPtr = nullptr; /** * @brief Input matrix A */ diff --git a/include/Utils/UtilityFunctions.h b/include/Utils/UtilityFunctions.h index 090d5275..a57d467c 100755 --- a/include/Utils/UtilityFunctions.h +++ b/include/Utils/UtilityFunctions.h @@ -8,6 +8,7 @@ #include #include #include +#include //#include #include @@ -67,6 +68,21 @@ class UtilityFunctions { }*/ return ru; } + static double relativeFrobeniusNorm(torch::Tensor A, torch::Tensor B) { + torch::Tensor error = A - B; + double frobeniusNormA = A.norm().item(); + double frobeniusNormError = error.norm().item(); + + return frobeniusNormError / frobeniusNormA; + } + static double errorBoundRatio(torch::Tensor A, torch::Tensor B) { + torch::Tensor error = A - B; + double frobeniusNormA = A.norm().item(); + double frobeniusNormB = B.norm().item(); + double frobeniusNormError = error.norm().item(); + + return frobeniusNormError / frobeniusNormA / frobeniusNormB; + } }; } #endif //IntelliStream_SRC_UTILS_UTILITYFUNCTIONS_HPP_ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 898d56d6..618b6fa2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(Utils) add_subdirectory(MatrixLoader) add_subdirectory(Parallelization) +add_subdirectory(CPPAlgos) add_sources( myVecAdd.cpp ) \ No newline at end of file diff --git a/src/CPPAlgos/AbstractCPPAlgo.cpp b/src/CPPAlgos/AbstractCPPAlgo.cpp new file mode 100644 index 00000000..44e8a535 --- /dev/null +++ b/src/CPPAlgos/AbstractCPPAlgo.cpp @@ -0,0 +1,10 @@ +/*! \file AbstractMatrixLoader.h*/ +// +// Created by tony on 25/05/23. +// + +#include +torch::Tensor AMMBench::AbstractCPPAlgo::amm(torch::Tensor A, torch::Tensor B, uint64_t sketchSize) { + std::cout << sketchSize; + return torch::matmul(A, B); +} \ No newline at end of file diff --git a/src/CPPAlgos/CMakeLists.txt b/src/CPPAlgos/CMakeLists.txt new file mode 100644 index 00000000..f8805edd --- /dev/null +++ b/src/CPPAlgos/CMakeLists.txt @@ -0,0 +1,5 @@ +add_sources( + AbstractCPPAlgo.cpp + CRSCPPAlgo.cpp + CPPAlgoTable.cpp +) \ No newline at end of file diff --git a/src/CPPAlgos/CPPAlgoTable.cpp b/src/CPPAlgos/CPPAlgoTable.cpp new file mode 100644 index 00000000..572856a0 --- /dev/null +++ b/src/CPPAlgos/CPPAlgoTable.cpp @@ -0,0 +1,13 @@ +// +// Created by tony on 25/05/23. +// + +#include +#include +namespace AMMBench { +AMMBench::CPPAlgoTable::CPPAlgoTable() { + algoMap["mm"] = newAbstractCPPAlgo(); + algoMap["crs"] = newCRSCPPAlgo(); +} + +} // AMMBench \ No newline at end of file diff --git a/src/CPPAlgos/CRSCPPAlgo.cpp b/src/CPPAlgos/CRSCPPAlgo.cpp new file mode 100644 index 00000000..03a33021 --- /dev/null +++ b/src/CPPAlgos/CRSCPPAlgo.cpp @@ -0,0 +1,33 @@ +// +// Created by tony on 25/05/23. +// + +#include + +namespace AMMBench { +torch::Tensor AMMBench::CRSCPPAlgo::amm(torch::Tensor A, torch::Tensor B, uint64_t k) { + A = A.t(); + //INTELLI_INFO("I am CPP-CRS"); + int64_t n = A.size(0); + //int64_t m = A.size(1); + + assert(n == B.size(0)); + // Probability distribution + torch::Tensor probs = torch::ones(n) / n; // default: uniform + + // Sample k indices from range 0 to n for given probability distribution + torch::Tensor indices = torch::multinomial(probs, k, true); + + // Sample k columns from A + torch::Tensor A_sampled = A.index_select(0, indices); + int64_t ratio = std::ceil(static_cast(n) / k); + A_sampled = (A_sampled / (int) k).t().div(probs.index_select(0, torch::arange(0, n, ratio))); + + // Sample k rows from B + torch::Tensor B_sampled = B.index_select(0, indices); + + // Compute the matrix product + torch::Tensor result = torch::matmul(A_sampled, B_sampled); + return result; +} +} // AMMBench \ No newline at end of file diff --git a/src/Parallelization/BlockPartitionRunner.cpp b/src/Parallelization/BlockPartitionRunner.cpp index 4b46d206..35e7468b 100644 --- a/src/Parallelization/BlockPartitionRunner.cpp +++ b/src/Parallelization/BlockPartitionRunner.cpp @@ -8,19 +8,31 @@ void AMMBench::BlockPartitionWorker::setConfig(INTELLI::ConfigMapPtr _cfg) { cfg = _cfg; sketchDimension = cfg->tryU64("sketchDimension", 50, true); std::string ptFile = cfg->tryString("ptFile", "torchscripts/FDAMM.pt", true); - module = torch::jit::load(ptFile); + useCPP = cfg->tryU64("useCPP", 0, true); + if (useCPP) { + std::string cppAlgoTag = cfg->tryString("cppAlgoTag", "mm", true); + cppAlgoPtr = cppAlgoTable.findCppAlgo(cppAlgoTag); + } + if (!useCPP || (cppAlgoPtr == nullptr)) { + module = torch::jit::load(ptFile); + if (useCPP) { + INTELLI_ERROR("No cpp algorithm found, go back to pt module"); + useCPP = 0; + } + } + } void AMMBench::BlockPartitionWorker::setWorkParameters(uint64_t aStart, uint64_t aEnd, int mycore) { startRow = aStart; endRow = aEnd; coreBind = mycore; //matC=newTensor(torch::zeros({(long)(endRow+1-startRow),matB->size(1)})); - subA = matA->slice(0, startRow, endRow); + } void AMMBench::BlockPartitionWorker::setABC(AMMBench::TensorPtr A, AMMBench::TensorPtr B, AMMBench::TensorPtr C) { - matA = newTensor(*A); - matB = newTensor(*B);; + matA = A; + matB = B; matC = C; //assert(C); } @@ -40,9 +52,15 @@ void AMMBench::BlockPartitionWorker::inlineMain() { //torch::Tensor subC = module.forward({subA, *matB, (long) sketchDimension}).toTensor(); // Copy the results back to the output matrix C //matC->slice(0, startRow, endRow) = subC; - + subA = matA->slice(0, startRow, endRow); //irC=module.forward({subA, *matB, (long) sketchDimension}).toTensor(); - matC->slice(0, startRow, endRow) =module.forward({subA, *matB, (long) sketchDimension}).toTensor(); + if (useCPP) { + INTELLI_WARNING("USE CPP ALGO"); + matC->slice(0, startRow, endRow) = cppAlgoPtr->amm(subA, *matB, sketchDimension); + } else { + matC->slice(0, startRow, endRow) =module.forward({subA, *matB, (long) sketchDimension}).toTensor(); + } + gettimeofday(&tend, NULL); //std::cout<getElapsedTime(); uint64_t ti = 0; for (uint64_t i = 0; i < threads; i++) { ti += workers[i]->getElapsedTime(); - } return ti / threads; } \ No newline at end of file diff --git a/test/SystemTest/CRSTest.cpp b/test/SystemTest/CRSTest.cpp index f2afbf87..168cdd85 100644 --- a/test/SystemTest/CRSTest.cpp +++ b/test/SystemTest/CRSTest.cpp @@ -60,4 +60,15 @@ TEST_CASE("Test the COLUMN ROW SAMPLINGS, V2", "[short]") runSingleThreadTest("scripts/config_CRSV2.csv"); // place your test here REQUIRE(a == 0); +} +TEST_CASE("Test pure cpp versiom", "[short]") +{ + torch::manual_seed(114514); + AMMBench::CRSCPPAlgo crs; + auto A = torch::rand({400, 400}); + auto B = torch::rand({400, 400}); + auto realC = torch::matmul(A, B); + auto ammC = crs.amm(A, B, 20); + double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, ammC); + REQUIRE(froError < 0.5); } \ No newline at end of file From b0fd29b28964d44a082537ec3a264736797dc492 Mon Sep 17 00:00:00 2001 From: tony <292224750@qq.com> Date: Fri, 26 May 2023 11:08:04 +0800 Subject: [PATCH 2/2] 1. add pure c++ algorithms 2. add normalized error and error bound evaluation at benchmark 3. update scripts --- benchmark/{config_threads16.csv => config.csv} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename benchmark/{config_threads16.csv => config.csv} (100%) diff --git a/benchmark/config_threads16.csv b/benchmark/config.csv similarity index 100% rename from benchmark/config_threads16.csv rename to benchmark/config.csv