diff --git a/CMakeLists.txt b/CMakeLists.txt index 26a43e4c..3f979b51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ add_subdirectory(src) # Add Library get_sources(IntelliStream_SOURCE_FILES) get_headers(IntelliStream_HEADER_FILES) -add_library(IntelliStream SHARED ${IntelliStream_SOURCE_FILES} ${IntelliStream_HEADER_FILES} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) +add_library(IntelliStream SHARED ${IntelliStream_SOURCE_FILES} ${IntelliStream_HEADER_FILES} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) set_property(TARGET IntelliStream PROPERTY CXX_STANDARD 20) target_include_directories(IntelliStream PUBLIC "include") diff --git a/Doxyfile b/Doxyfile index ebb39f68..e127a34a 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.0.1 +PROJECT_NUMBER = 0.1.0 # 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/scripts/scanARank/OoOCommon.py b/benchmark/scripts/scanARank/OoOCommon.py new file mode 100755 index 00000000..70f4cf33 --- /dev/null +++ b/benchmark/scripts/scanARank/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/scanARank/accuBar.py b/benchmark/scripts/scanARank/accuBar.py new file mode 100755 index 00000000..638c8a60 --- /dev/null +++ b/benchmark/scripts/scanARank/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/scanARank/autoParase.py b/benchmark/scripts/scanARank/autoParase.py new file mode 100755 index 00000000..9375c8e0 --- /dev/null +++ b/benchmark/scripts/scanARank/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/scanARank/config_BCoAMM.csv b/benchmark/scripts/scanARank/config_BCoAMM.csv new file mode 100644 index 00000000..f4a41838 --- /dev/null +++ b/benchmark/scripts/scanARank/config_BCoAMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +sketchDimension,25,U64 +ptFile,torchscripts/BetaCoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/config_CoAMM.csv b/benchmark/scripts/scanARank/config_CoAMM.csv new file mode 100644 index 00000000..fb18a981 --- /dev/null +++ b/benchmark/scripts/scanARank/config_CoAMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +sketchDimension,25,U64 +ptFile,torchscripts/CoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/config_FDAMM.csv b/benchmark/scripts/scanARank/config_FDAMM.csv new file mode 100644 index 00000000..15e68879 --- /dev/null +++ b/benchmark/scripts/scanARank/config_FDAMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +sketchDimension,25,U64 +ptFile,torchscripts/FDAMM.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/config_RAWMM.csv b/benchmark/scripts/scanARank/config_RAWMM.csv new file mode 100644 index 00000000..4216fbeb --- /dev/null +++ b/benchmark/scripts/scanARank/config_RAWMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +matrixLoaderTag,sparse,String +sketchDimension,25,U64 +ptFile,torchscripts/RAWMM.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARank/drawTogether.py b/benchmark/scripts/scanARank/drawTogether.py new file mode 100755 index 00000000..585f18d9 --- /dev/null +++ b/benchmark/scripts/scanARank/drawTogether.py @@ -0,0 +1,154 @@ +#!/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 = "aReduce" + + +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 main(): + exeSpace = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/" + resultPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag + resultPathFDAMM = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/FDAMM" + resultPathCoFD = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/CoFD" + resultPathBetaCoFD = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/BCoFD" + resultPathRAWMM = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/RAWMM" + figPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/figures/" + scanTag + configTemplate = exeSpace + "config.csv" + valueVec = [2,5,10,20,50,100,200,500,900] + valueVecRun = 1000-np.array(valueVec) + print(configTemplate) + # run + if (len(sys.argv) < 2): + os.system("mkdir ../../results") + os.system("mkdir ../../figures") + os.system("mkdir " + figPath) + os.system("sudo rm -rf " + resultPath) + os.system("sudo mkdir " + resultPath) + # + cleanPath(resultPathFDAMM) + cleanPath(resultPathCoFD) + cleanPath(resultPathBetaCoFD) + cleanPath(resultPathRAWMM) + # + runScanVector(exeSpace, valueVecRun, resultPathFDAMM, "config_FDAMM.csv") + runScanVector(exeSpace, valueVecRun, resultPathCoFD, "config_CoAMM.csv") + runScanVector(exeSpace, valueVecRun, resultPathBetaCoFD, "config_BCoAMM.csv") + runScanVector(exeSpace, valueVecRun, resultPathRAWMM, "config_RAWMM.csv") + evaTypes=['FDAMM','MM','Co-FD','BCO-FD'] + elapseTimeVecFD, cacheMissVecFD, cacheRefVecFD = readResultVector(valueVecRun, resultPathFDAMM) + elapseTimeVecCoFD, cacheMissVecCoFD, cacheRefVecCoFD = readResultVector(valueVecRun, resultPathCoFD) + elapseTimeVeCB, cacheMissVecB, cacheRefVecB = readResultVector(valueVecRun, resultPathBetaCoFD) + elapseTimeVecRAW, cacheMissVecRAW, cacheRefVecRAW = readResultVector(valueVecRun, resultPathRAWMM) + # os.system("mkdir " + figPath) + groupLine.DrawFigureYnormal([valueVec,valueVec,valueVec,valueVec], [elapseTimeVecFD,elapseTimeVecRAW,elapseTimeVecCoFD,elapseTimeVeCB], + evaTypes, + "Rank of matrix A", "elapsed time (ms)", 0, 1, figPath + "Rank" + "_elapsedTime", + True) + groupLine.DrawFigureYnormal([valueVec,valueVec,valueVec,valueVec], [cacheMissVecFD/cacheRefVecFD*100.0,cacheMissVecRAW/cacheRefVecRAW*100.0, + cacheMissVecCoFD/cacheRefVecCoFD*100.0,cacheMissVecB/cacheRefVecB*100.0], + evaTypes, + "Rank of matrix A", "cacheMiss (%)", 0, 1, figPath + "Rank" + "_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/scanARank/groupBar.py b/benchmark/scripts/scanARank/groupBar.py new file mode 100755 index 00000000..ef2d9842 --- /dev/null +++ b/benchmark/scripts/scanARank/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/scanARank/groupBar2.py b/benchmark/scripts/scanARank/groupBar2.py new file mode 100755 index 00000000..31155695 --- /dev/null +++ b/benchmark/scripts/scanARank/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/scanARank/groupLine.py b/benchmark/scripts/scanARank/groupLine.py new file mode 100755 index 00000000..89020eff --- /dev/null +++ b/benchmark/scripts/scanARank/groupLine.py @@ -0,0 +1,364 @@ +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/scanARank/perfRu.csv b/benchmark/scripts/scanARank/perfRu.csv new file mode 100644 index 00000000..9ee43623 --- /dev/null +++ b/benchmark/scripts/scanARank/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/scanASparse/OoOCommon.py b/benchmark/scripts/scanASparse/OoOCommon.py new file mode 100755 index 00000000..70f4cf33 --- /dev/null +++ b/benchmark/scripts/scanASparse/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/scanASparse/accuBar.py b/benchmark/scripts/scanASparse/accuBar.py new file mode 100755 index 00000000..638c8a60 --- /dev/null +++ b/benchmark/scripts/scanASparse/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/scanASparse/autoParase.py b/benchmark/scripts/scanASparse/autoParase.py new file mode 100755 index 00000000..9375c8e0 --- /dev/null +++ b/benchmark/scripts/scanASparse/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/scanASparse/config_BCoAMM.csv b/benchmark/scripts/scanASparse/config_BCoAMM.csv new file mode 100644 index 00000000..cc872faf --- /dev/null +++ b/benchmark/scripts/scanASparse/config_BCoAMM.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/BetaCoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/config_CoAMM.csv b/benchmark/scripts/scanASparse/config_CoAMM.csv new file mode 100644 index 00000000..ba4eee70 --- /dev/null +++ b/benchmark/scripts/scanASparse/config_CoAMM.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/CoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/config_FDAMM.csv b/benchmark/scripts/scanASparse/config_FDAMM.csv new file mode 100644 index 00000000..e917d269 --- /dev/null +++ b/benchmark/scripts/scanASparse/config_FDAMM.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/FDAMM.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/config_RAWMM.csv b/benchmark/scripts/scanASparse/config_RAWMM.csv new file mode 100644 index 00000000..d5231505 --- /dev/null +++ b/benchmark/scripts/scanASparse/config_RAWMM.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/RAWMM.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanASparse/drawTogether.py b/benchmark/scripts/scanASparse/drawTogether.py new file mode 100755 index 00000000..b138cf4d --- /dev/null +++ b/benchmark/scripts/scanASparse/drawTogether.py @@ -0,0 +1,154 @@ +#!/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 = "aDensity" + + +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 main(): + exeSpace = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/" + resultPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag + resultPathFDAMM = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/FDAMM" + resultPathCoFD = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/CoFD" + resultPathBetaCoFD = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/BCoFD" + resultPathRAWMM = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/RAWMM" + figPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/figures/" + scanTag + configTemplate = exeSpace + "config.csv" + valueVec = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0] + valueVecDisp = np.array(valueVec) + print(configTemplate) + # run + if (len(sys.argv) < 2): + os.system("mkdir ../../results") + os.system("mkdir ../../figures") + os.system("mkdir " + figPath) + os.system("sudo rm -rf " + resultPath) + os.system("sudo mkdir " + resultPath) + # + cleanPath(resultPathFDAMM) + cleanPath(resultPathCoFD) + cleanPath(resultPathBetaCoFD) + cleanPath(resultPathRAWMM) + # + runScanVector(exeSpace, valueVec, resultPathFDAMM, "config_FDAMM.csv") + runScanVector(exeSpace, valueVec, resultPathCoFD, "config_CoAMM.csv") + runScanVector(exeSpace, valueVec, resultPathBetaCoFD, "config_BCoAMM.csv") + runScanVector(exeSpace, valueVec, resultPathRAWMM, "config_RAWMM.csv") + evaTypes=['FDAMM','MM','Co-FD','BCO-FD'] + elapseTimeVecFD, cacheMissVecFD, cacheRefVecFD = readResultVector(valueVec, resultPathFDAMM) + elapseTimeVecCoFD, cacheMissVecCoFD, cacheRefVecCoFD = readResultVector(valueVec, resultPathCoFD) + elapseTimeVeCB, cacheMissVecB, cacheRefVecB = readResultVector(valueVec, resultPathBetaCoFD) + elapseTimeVecRAW, cacheMissVecRAW, cacheRefVecRAW = readResultVector(valueVec, resultPathRAWMM) + # os.system("mkdir " + figPath) + groupLine.DrawFigureXYnormal([valueVec,valueVec,valueVec,valueVec], [elapseTimeVecFD,elapseTimeVecRAW,elapseTimeVecCoFD,elapseTimeVeCB], + evaTypes, + "Density of matrix A", "elapsed time (ms)", 0, 1, figPath + scanTag + "_elapsedTime", + True) + groupLine.DrawFigureXYnormal([valueVec,valueVec,valueVec,valueVec], [cacheMissVecFD/cacheRefVecFD*100.0,cacheMissVecRAW/cacheRefVecRAW*100.0, + cacheMissVecCoFD/cacheRefVecCoFD*100.0,cacheMissVecB/cacheRefVecB*100.0], + evaTypes, + "Density of matrix A", "cacheMiss (%)", 0, 1, figPath + scanTag + "_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/scanASparse/groupBar.py b/benchmark/scripts/scanASparse/groupBar.py new file mode 100755 index 00000000..ef2d9842 --- /dev/null +++ b/benchmark/scripts/scanASparse/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/scanASparse/groupBar2.py b/benchmark/scripts/scanASparse/groupBar2.py new file mode 100755 index 00000000..31155695 --- /dev/null +++ b/benchmark/scripts/scanASparse/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/scanASparse/groupLine.py b/benchmark/scripts/scanASparse/groupLine.py new file mode 100755 index 00000000..89020eff --- /dev/null +++ b/benchmark/scripts/scanASparse/groupLine.py @@ -0,0 +1,364 @@ +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/scanASparse/perfRu.csv b/benchmark/scripts/scanASparse/perfRu.csv new file mode 100644 index 00000000..9ee43623 --- /dev/null +++ b/benchmark/scripts/scanASparse/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/src/Benchmark.cpp b/benchmark/src/Benchmark.cpp index 8f896980..7123c301 100644 --- a/benchmark/src/Benchmark.cpp +++ b/benchmark/src/Benchmark.cpp @@ -1,17 +1,10 @@ -// Copyright (C) 2021 by the IntelliStream team (https://github.com/intellistream) +/*! \file Benchmark.h*/ /** * @brief This is the main entry point of the entire program. * We use this as the entry point for benchmarking. */ -#include -#include -#include -#include -#include -#include -#include -#include +#include #include using namespace std; using namespace INTELLI; @@ -19,27 +12,29 @@ using namespace torch; void runSingleThreadTest(std::string configName) { ConfigMapPtr cfg = newConfigMap(); cfg->fromFile(configName); - //555 - uint64_t aRow, aCol, bCol, sketchDimension; - aRow = cfg->tryU64("aRow", 100, true); - aCol = cfg->tryU64("aCol", 1000, true); - bCol = cfg->tryU64("bCol", 500, true); + AMMBench::MatrixLoaderTable mLoaderTable; + uint64_t sketchDimension; sketchDimension = cfg->tryU64("sketchDimension", 50, true); uint64_t coreBind = cfg->tryU64("coreBind", 0, true); UtilityFunctions::bind2Core((int) coreBind); std::string ptFile = cfg->tryString("ptFile", "torchscripts/FDAMM.pt", true); - uint64_t customResultName = cfg->tryU64("customResultName", 0, true); + //uint64_t customResultName = cfg->tryU64("customResultName", 0, true); INTELLI_INFO("Place me at core" + to_string(coreBind)); INTELLI_INFO( - "Generating [" + to_string(aRow) + "x" + to_string(aCol) + "]*[" + to_string(aCol) + "x" + to_string(bCol) - + "], with sketch" + to_string(sketchDimension)); + "with sketch" + to_string(sketchDimension)); torch::jit::script::Module module; INTELLI_INFO("Try pt file " + ptFile); module = torch::jit::load(ptFile); - torch::manual_seed(114514); - //555 - auto A = torch::rand({(long) aRow, (long) aCol}); - auto B = torch::rand({(long) aCol, (long) bCol}); + std::string matrixLoaderTag = cfg->tryString("matrixLoaderTag", "random", true); + auto matLoaderPtr = mLoaderTable.findMatrixLoader(matrixLoaderTag); + assert(matLoaderPtr); + matLoaderPtr->setConfig(cfg); + auto A = matLoaderPtr->getA(); + auto B = matLoaderPtr->getB(); + /*torch::manual_seed(114514); +//555 +auto A = torch::rand({(long) aRow, (long) aCol}); +auto B = torch::rand({(long) aCol, (long) bCol});*/ INTELLI_INFO("Generation done, conducting..."); ThreadPerf pef((int) coreBind); pef.setPerfList(); @@ -47,10 +42,6 @@ void runSingleThreadTest(std::string configName) { auto C =module.forward({A, B, (long) sketchDimension}).toTensor(); pef.end(); std::string ruName = "default"; - if (customResultName) { - ruName = "ru_core_" + to_string(coreBind) + "_matrix_" + to_string(aRow) + "x" + to_string(aCol) + "amm" - + to_string(aCol) + "x" + to_string(bCol) + "_sketch_" + to_string(sketchDimension); - } auto resultCsv = pef.resultToConfigMap(); resultCsv->toFile(ruName + ".csv"); diff --git a/benchmark/torchscripts/BetaCoOccurringFD.py b/benchmark/torchscripts/BetaCoOccurringFD.py index c936d112..9060fca8 100644 --- a/benchmark/torchscripts/BetaCoOccurringFD.py +++ b/benchmark/torchscripts/BetaCoOccurringFD.py @@ -3,110 +3,108 @@ import os import math + def get_first_element(tensor): - if tensor.numel() == 1: - return tensor.item() - else: - return tensor[0].item() - + if tensor.numel() == 1: + return tensor.item() + else: + return tensor[0].item() + + def is_empty_tensor(tensor): - return tensor.numel() == 0 + return tensor.numel() == 0 + def attenuate(beta: float, k: torch.Tensor, l: int) -> torch.Tensor: - return (torch.exp(k * beta / (l - 1)) - 1) / (torch.exp(beta) - 1) - + return (torch.exp(k * beta / (l - 1)) - 1) / (torch.exp(beta) - 1) + @torch.jit.script def FDAMM(A: torch.Tensor, B: torch.Tensor, l: int): - B = B.t() - beta=1.0 - assert A.shape[1] == B.shape[1] - mx, n = A.shape - my, n = B.shape - # initialize sketch matrices - BX = torch.zeros((mx, l)) - BY = torch.zeros((my, l)) - - # the first l iterations - for i in range(l): - BX[:, i] = A[:, i] - BY[:, i] = B[:, i] - - zero_columns = torch.tensor([0]) - zero_columns = zero_columns[1:] - - # iteration l to n: insert if available, else shrink sketch matrices - for i in range(l, n): - # acruire the index of a zero valued column - if len(zero_columns) != 0: - idx = int(get_first_element(zero_columns)) - # assert idx == get_first_element(torch.nonzero(torch.sum(BX, dim = 0) == 0).squeeze()) - BX[:, idx] = A[:, i] - BY[:, idx] = B[:, i] - zero_columns = zero_columns [1:] - - # if no zero valued column, shrink accrodingly - else: - QX, RX = torch.linalg.qr(BX) - QY, RY = torch.linalg.qr(BY) - U, SV, V = torch.svd(torch.matmul(RX, RY.t())) - - # find the median of singular values - S_sorted = torch.sort(SV).values - delta = (S_sorted[len(S_sorted) // 2] if len(S_sorted) % 2 == 1 else - (S_sorted[len(S_sorted) // 2 - 1] + S_sorted[len(S_sorted) // 2]) / 2) - - # delta = S_sorted[-1] - - - # parameterizedReduceRank - indices = torch.arange(l, dtype=torch.float32) - attenuated_values = attenuate(beta, indices, l) - parameterizedReduceRank = delta * attenuated_values - SV_shrunk = torch.clamp(SV - parameterizedReduceRank, min = 0) - - - # restore SV diagnal matrix - SV = torch.diag_embed(SV_shrunk) - SV_sqrt = torch.sqrt(SV) - - # update indices of zero valued columns - zero_indices = torch.nonzero(SV_shrunk == 0).squeeze() - zero_columns = torch.unique(torch.cat((zero_columns, zero_indices))) - - # update sketch matrices - BX = torch.matmul(torch.matmul(QX, U), SV_sqrt) - BY = torch.matmul(torch.matmul(QY, V), SV_sqrt) - - - return torch.matmul(BX, BY.t()) - + B = B.t() + beta = 1.0 + assert A.shape[1] == B.shape[1] + mx, n = A.shape + my, n = B.shape + # initialize sketch matrices + BX = torch.zeros((mx, l)) + BY = torch.zeros((my, l)) + + # the first l iterations + for i in range(l): + BX[:, i] = A[:, i] + BY[:, i] = B[:, i] + + zero_columns = torch.tensor([0]) + zero_columns = zero_columns[1:] + + # iteration l to n: insert if available, else shrink sketch matrices + for i in range(l, n): + # acruire the index of a zero valued column + if len(zero_columns) != 0: + idx = int(get_first_element(zero_columns)) + # assert idx == get_first_element(torch.nonzero(torch.sum(BX, dim = 0) == 0).squeeze()) + BX[:, idx] = A[:, i] + BY[:, idx] = B[:, i] + zero_columns = zero_columns[1:] + + # if no zero valued column, shrink accrodingly + else: + QX, RX = torch.linalg.qr(BX) + QY, RY = torch.linalg.qr(BY) + U, SV, V = torch.svd(torch.matmul(RX, RY.t())) + + # find the median of singular values + S_sorted = torch.sort(SV).values + delta = (S_sorted[len(S_sorted) // 2] if len(S_sorted) % 2 == 1 else + (S_sorted[len(S_sorted) // 2 - 1] + S_sorted[len(S_sorted) // 2]) / 2) + + # delta = S_sorted[-1] + + # parameterizedReduceRank + indices = torch.arange(l, dtype=torch.float32) + attenuated_values = attenuate(beta, indices, l) + parameterizedReduceRank = delta * attenuated_values + SV_shrunk = torch.clamp(SV - parameterizedReduceRank, min=0) + + # restore SV diagnal matrix + SV = torch.diag_embed(SV_shrunk) + SV_sqrt = torch.sqrt(SV) + + # update indices of zero valued columns + zero_indices = torch.nonzero(SV_shrunk == 0).squeeze() + zero_columns = torch.unique(torch.cat((zero_columns, zero_indices))) + + # update sketch matrices + BX = torch.matmul(torch.matmul(QX, U), SV_sqrt) + BY = torch.matmul(torch.matmul(QY, V), SV_sqrt) + + return torch.matmul(BX, BY.t()) def main(): - - width = 1000 - A = torch.rand(10000, width) - B = torch.rand(width, 5000) - - t = time.time() - - aResult = FDAMM(A, B, 500) - print("approximate: " + str(time.time() - t) + "s") - - print(aResult) - - # exact result - t = time.time() - eResult = torch.matmul(A, B) - print("\nExact: " + str(time.time() - t) + "s") - - print(eResult) - - print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) - - FDAMM_script = FDAMM.save("BetaCoOccurringFD.pt") + width = 1000 + A = torch.rand(10000, width) + B = torch.rand(width, 5000) + + t = time.time() + + aResult = FDAMM(A, B, 500) + print("approximate: " + str(time.time() - t) + "s") + + print(aResult) + + # exact result + t = time.time() + eResult = torch.matmul(A, B) + print("\nExact: " + str(time.time() - t) + "s") + + print(eResult) + + print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) + + FDAMM_script = FDAMM.save("BetaCoOccurringFD.pt") + if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/benchmark/torchscripts/CoOccurringFD.py b/benchmark/torchscripts/CoOccurringFD.py index 688da6df..95b4b403 100644 --- a/benchmark/torchscripts/CoOccurringFD.py +++ b/benchmark/torchscripts/CoOccurringFD.py @@ -3,113 +3,116 @@ import os import math + def get_first_element(tensor): - if tensor.numel() == 1: - return tensor.item() - else: - return tensor[0].item() - + if tensor.numel() == 1: + return tensor.item() + else: + return tensor[0].item() + + def is_empty_tensor(tensor): - return tensor.numel() == 0 + return tensor.numel() == 0 + def attenuate(beta, k, l): - return (math.e**(k*beta/(l-1))-1) / (math.e**beta -1) + return (math.e ** (k * beta / (l - 1)) - 1) / (math.e ** beta - 1) + def paramerizedReduceRank(SV, delta, l, beta): - elements = [delta*attenuate(beta, i, l) for i in range(l)] - reduceRank = torch.tensor(elements, dtype=torch.float) - return torch.clamp(SV - reduceRank, min = 0) + elements = [delta * attenuate(beta, i, l) for i in range(l)] + reduceRank = torch.tensor(elements, dtype=torch.float) + return torch.clamp(SV - reduceRank, min=0) + def medianReduceRank(SV, delta): - return torch.clamp(SV - delta, min = 0) + return torch.clamp(SV - delta, min=0) + -@torch.jit.script +@torch.jit.script def FDAMM(A: torch.Tensor, B: torch.Tensor, l: int): - # if beta set zero, the median is used to reduce rank - B = B.t() - - assert A.shape[1] == B.shape[1] - mx, n = A.shape - my, n = B.shape - # initialize sketch matrices - BX = torch.zeros((mx, l)) - BY = torch.zeros((my, l)) - - # the first l iterations - for i in range(l): - BX[:, i] = A[:, i] - BY[:, i] = B[:, i] - - zero_columns = torch.tensor([0]) - zero_columns = zero_columns[1:] - - # iteration l to n: insert if available, else shrink sketch matrices - for i in range(l, n): - # acruire the index of a zero valued column - if len(zero_columns) != 0: - idx = int(get_first_element(zero_columns)) - # assert idx == get_first_element(torch.nonzero(torch.sum(BX, dim = 0) == 0).squeeze()) - BX[:, idx] = A[:, i] - BY[:, idx] = B[:, i] - zero_columns = zero_columns [1:] - - # if no zero valued column, shrink accrodingly - else: - QX, RX = torch.linalg.qr(BX) - QY, RY = torch.linalg.qr(BY) - U, SV, V = torch.svd(torch.matmul(RX, RY.t())) - - # find the median of singular values - S_sorted = torch.sort(SV).values - delta = (S_sorted[len(S_sorted) // 2] if len(S_sorted) % 2 == 1 else - (S_sorted[len(S_sorted) // 2 - 1] + S_sorted[len(S_sorted) // 2]) / 2) - - # delta = S_sorted[-1] - - - # shrink the singular values with delta - SV_shrunk = medianReduceRank(SV, delta) - - - # restore SV diagnal matrix - SV = torch.diag_embed(SV_shrunk) - SV_sqrt = torch.sqrt(SV) - - # update indices of zero valued columns - zero_indices = torch.nonzero(SV_shrunk == 0).squeeze() - zero_columns = torch.unique(torch.cat((zero_columns, zero_indices))) - - # update sketch matrices - BX = torch.matmul(torch.matmul(QX, U), SV_sqrt) - BY = torch.matmul(torch.matmul(QY, V), SV_sqrt) - - - return torch.matmul(BX, BY.t()) + # if beta set zero, the median is used to reduce rank + B = B.t() + + assert A.shape[1] == B.shape[1] + mx, n = A.shape + my, n = B.shape + # initialize sketch matrices + BX = torch.zeros((mx, l)) + BY = torch.zeros((my, l)) + + # the first l iterations + for i in range(l): + BX[:, i] = A[:, i] + BY[:, i] = B[:, i] + + zero_columns = torch.tensor([0]) + zero_columns = zero_columns[1:] + + # iteration l to n: insert if available, else shrink sketch matrices + for i in range(l, n): + # acruire the index of a zero valued column + if len(zero_columns) != 0: + idx = int(get_first_element(zero_columns)) + # assert idx == get_first_element(torch.nonzero(torch.sum(BX, dim = 0) == 0).squeeze()) + BX[:, idx] = A[:, i] + BY[:, idx] = B[:, i] + zero_columns = zero_columns[1:] + + # if no zero valued column, shrink accrodingly + else: + QX, RX = torch.linalg.qr(BX) + QY, RY = torch.linalg.qr(BY) + U, SV, V = torch.svd(torch.matmul(RX, RY.t())) + + # find the median of singular values + S_sorted = torch.sort(SV).values + delta = (S_sorted[len(S_sorted) // 2] if len(S_sorted) % 2 == 1 else + (S_sorted[len(S_sorted) // 2 - 1] + S_sorted[len(S_sorted) // 2]) / 2) + + # delta = S_sorted[-1] + + # shrink the singular values with delta + SV_shrunk = medianReduceRank(SV, delta) + + # restore SV diagnal matrix + SV = torch.diag_embed(SV_shrunk) + SV_sqrt = torch.sqrt(SV) + + # update indices of zero valued columns + zero_indices = torch.nonzero(SV_shrunk == 0).squeeze() + zero_columns = torch.unique(torch.cat((zero_columns, zero_indices))) + + # update sketch matrices + BX = torch.matmul(torch.matmul(QX, U), SV_sqrt) + BY = torch.matmul(torch.matmul(QY, V), SV_sqrt) + + return torch.matmul(BX, BY.t()) + def main(): - - width = 1000 - A = torch.rand(10000, width) - B = torch.rand(width, 5000) - - t = time.time() - - aResult = FDAMM(A, B, 200) - print("approximate: " + str(time.time() - t) + "s") - - print(aResult) - - # exact result - t = time.time() - eResult = torch.matmul(A, B) - print("\nExact: " + str(time.time() - t) + "s") - - print(eResult) - - print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) - - FDAMM_script = FDAMM.save("CoOccurringFD.pt") + width = 1000 + A = torch.rand(10000, width) + B = torch.rand(width, 5000) + + t = time.time() + + aResult = FDAMM(A, B, 200) + print("approximate: " + str(time.time() - t) + "s") + + print(aResult) + + # exact result + t = time.time() + eResult = torch.matmul(A, B) + print("\nExact: " + str(time.time() - t) + "s") + + print(eResult) + + print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) + + FDAMM_script = FDAMM.save("CoOccurringFD.pt") + if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/benchmark/torchscripts/FDAMM.py b/benchmark/torchscripts/FDAMM.py index 193874ae..6dc46068 100644 --- a/benchmark/torchscripts/FDAMM.py +++ b/benchmark/torchscripts/FDAMM.py @@ -1,81 +1,86 @@ import torch import time + def get_first_element(tensor): - if tensor.numel() == 1: - return tensor.item() - else: - return tensor[0].item() -@torch.jit.script -def FDAMM(A:torch.Tensor, B:torch.Tensor,l:int): - #assert A.shape[1] == B.shape[1] - mx, n = A.shape - bn,my = B.shape - # initialize sketch matrices - BX = torch.zeros((mx, l)) - BY = torch.zeros((my, l)) - - - for i in range(n): - # find zero valued column, to be replaced with a better mechanism - sum_cols = torch.sum(BX, dim = 0) - zero_valued_columns_X = torch.nonzero(sum_cols == 0).squeeze() # sum each column to find the zero valued ones - - # if a zero valued column exists, insert a column - if len(zero_valued_columns_X.shape) != 0: - idx = int(get_first_element(zero_valued_columns_X)) - BX[:, idx] = A[:, i] - - sum_cols = torch.sum(BY, dim = 0) - zero_valued_columns_Y = torch.nonzero(sum_cols == 0).squeeze() - if len(zero_valued_columns_Y.shape) != 0: - idx = int(get_first_element(zero_valued_columns_Y)) - BY[:, idx] = B[i,:] - - # if no zero valued column, shrink accrodingly - if len(zero_valued_columns_X.shape) == 0 and len(zero_valued_columns_Y.shape) == 0: - QX, RX = torch.linalg.qr(BX) - QY, RY = torch.linalg.qr(BY) - U, SV, V = torch.svd(torch.matmul(RX, RY.t())) - - # find the median of singular values - S_sorted = torch.sort(SV).values - delta = (S_sorted[len(S_sorted) // 2] if len(S_sorted) % 2 == 1 else - (S_sorted[len(S_sorted) // 2 - 1] + S_sorted[len(S_sorted) // 2]) / 2) - - # shrink the singular values with delta - # (this is based on co-occuring paper from 2017, diffrent from beta-Co-FD) - SV_shrunk = torch.clamp(SV - delta, min = 0) - SV = torch.diag_embed(SV_shrunk) - SV_sqrt = torch.sqrt(SV) - - BX = torch.matmul(torch.matmul(QX, U), SV_sqrt) - BY = torch.matmul(torch.matmul(QY, V), SV_sqrt) - - - return torch.matmul(BX, BY.t()) - -@torch.jit.script -def RAWMM(A:torch.Tensor, B:torch.Tensor,l:int): - return torch.matmul(A, B) + if tensor.numel() == 1: + return tensor.item() + else: + return tensor[0].item() + + +@torch.jit.script +def FDAMM(A: torch.Tensor, B: torch.Tensor, l: int): + # assert A.shape[1] == B.shape[1] + mx, n = A.shape + bn, my = B.shape + # initialize sketch matrices + BX = torch.zeros((mx, l)) + BY = torch.zeros((my, l)) + + for i in range(n): + # find zero valued column, to be replaced with a better mechanism + sum_cols = torch.sum(BX, dim=0) + zero_valued_columns_X = torch.nonzero(sum_cols == 0).squeeze() # sum each column to find the zero valued ones + + # if a zero valued column exists, insert a column + if len(zero_valued_columns_X.shape) != 0: + idx = int(get_first_element(zero_valued_columns_X)) + BX[:, idx] = A[:, i] + + sum_cols = torch.sum(BY, dim=0) + zero_valued_columns_Y = torch.nonzero(sum_cols == 0).squeeze() + if len(zero_valued_columns_Y.shape) != 0: + idx = int(get_first_element(zero_valued_columns_Y)) + BY[:, idx] = B[i, :] + + # if no zero valued column, shrink accrodingly + if len(zero_valued_columns_X.shape) == 0 and len(zero_valued_columns_Y.shape) == 0: + QX, RX = torch.linalg.qr(BX) + QY, RY = torch.linalg.qr(BY) + U, SV, V = torch.svd(torch.matmul(RX, RY.t())) + + # find the median of singular values + S_sorted = torch.sort(SV).values + delta = (S_sorted[len(S_sorted) // 2] if len(S_sorted) % 2 == 1 else + (S_sorted[len(S_sorted) // 2 - 1] + S_sorted[len(S_sorted) // 2]) / 2) + + # shrink the singular values with delta + # (this is based on co-occuring paper from 2017, diffrent from beta-Co-FD) + SV_shrunk = torch.clamp(SV - delta, min=0) + SV = torch.diag_embed(SV_shrunk) + SV_sqrt = torch.sqrt(SV) + + BX = torch.matmul(torch.matmul(QX, U), SV_sqrt) + BY = torch.matmul(torch.matmul(QY, V), SV_sqrt) + + return torch.matmul(BX, BY.t()) + + +@torch.jit.script +def RAWMM(A: torch.Tensor, B: torch.Tensor, l: int): + return torch.matmul(A, B) + + def main(): - A = torch.rand(10000, 1000) - B = torch.rand(1000,5000) - #A= A.to('cuda') - #B = B.to('cuda') - t = time.time() - Aresult = FDAMM(A, B, 500) - print("approximate: " + str(time.time() - t) + "s") - print(Aresult) - - t = time.time() - Eresult = torch.matmul(A, B) # exact result - print("\nExact: " + str(time.time() - t) + "s") - print(Eresult) - FDAMM_script = FDAMM.save("FDAMM.pt") - RAWMM_script=RAWMM.save("RAWMM.pt") - #print("\nerror: " + str(torch.norm(Aresult - Eresult, p='fro').item())) + A = torch.rand(10000, 1000) + B = torch.rand(1000, 5000) + # A= A.to('cuda') + # B = B.to('cuda') + t = time.time() + Aresult = FDAMM(A, B, 500) + print("approximate: " + str(time.time() - t) + "s") + print(Aresult) + + t = time.time() + Eresult = torch.matmul(A, B) # exact result + print("\nExact: " + str(time.time() - t) + "s") + print(Eresult) + FDAMM_script = FDAMM.save("FDAMM.pt") + RAWMM_script = RAWMM.save("RAWMM.pt") + + +# print("\nerror: " + str(torch.norm(Aresult - Eresult, p='fro').item())) if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/commit.sh b/commit.sh index 6ce14ccd..3ad83c39 100755 --- a/commit.sh +++ b/commit.sh @@ -1,4 +1,4 @@ -BRANCH=hump +BRANCH=matrixLoader git init git checkout -b $BRANCH git add . diff --git a/commit_info b/commit_info index 3dace517..432c9436 100644 --- a/commit_info +++ b/commit_info @@ -1,2 +1,2 @@ -1. modify scripts +1. fix doxygen bugs diff --git a/include/AMMBench.h b/include/AMMBench.h new file mode 100755 index 00000000..8a50aefe --- /dev/null +++ b/include/AMMBench.h @@ -0,0 +1,86 @@ +/*! \file AMMBench.h*/ +// +// Created by tony on 22/11/22. +// + +#ifndef INTELLISTREAM_AMMBENCH_H +#define INTELLISTREAM_AMMBENCH_H +#include +#include +#include +#include +#include +/** + * + * @mainpage Introduction + * This project is for benchmarking common (approximate) matrix multiplication algorithms under various archeitectures in as streaming setting + * @section BENCH_MARK Benchmark Tips + * usage: ./benchmark [configfile] + * @note Require configs in configfile: + * - aRow (U64) the rows of tensor A, required by @ref RandomMatrixLoader, @ref SparseMatrixLoader + * - aCol (U64) the columns of tensor A, required by @ref RandomMatrixLoader, @ref SparseMatrixLoader + * - bCol (U64) the columns of tensor B, required by @ref RandomMatrixLoader, @ref SparseMatrixLoader + * - "aDensity" The density factor of matrix A, Double, 1.0, required by @ref SparseMatrixLoader + * - "bDensity" The density factor of matrix B, Double, 1.0, required by @ref SparseMatrixLoader + * - "aReduce" Reduce some rows of A to be linearly dependent, U64, 0, required by @ref SparseMatrixLoader + * - "bReduce" Reduce some rows of A to be linearly dependent, U64, 0, required by @ref SparseMatrixLoader + * - sketchDimension (U64) the dimension of sketch matrix, default 50 + * - 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 + See also the template config.csv + * @section subsec_extend_operator How to extend a new algorithm + * - 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. + */ +/** +* +*/ +//The groups of modules +/** + * @mainpage Code Structure + * @section Code_Structure Code Structure + */ +/** + * @subsection code_stru_matrixloader MatrixLoader + * This folder contains the loader to matrixes under different generation rules + * @defgroup AMMBENCH_MatrixLOADER The matrix loaders + * @{ + * We define the generation classes of matrixes. here + **/ +#include +#include +#include +#include +/** + * @} + */ +/*** + * @subsection code_stru_utils Utils +* This folder contains the public utils shared by INTELISTREAM team and some third party dependencies. + **/ +/** +* @defgroup INTELLI_UTIL Shared Utils +* @{ +*/ +#include +/** + * @ingroup INTELLI_UTIL +* @defgroup INTELLI_UTIL_OTHERC20 Other common class or package under C++20 standard +* @{ +* This package covers some common C++20 new features, such as std::thread to ease the programming +*/ +#include +#include +#include +/** + * @} + */ +/** + * + * @} + */ + +#endif diff --git a/include/MatrixLoader/AbstractMatrixLoader.h b/include/MatrixLoader/AbstractMatrixLoader.h new file mode 100644 index 00000000..57886227 --- /dev/null +++ b/include/MatrixLoader/AbstractMatrixLoader.h @@ -0,0 +1,77 @@ +/*! \file AbstractMatrixLoader.h*/ +// +// Created by tony on 10/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_MATRIXLOADER_ABSTRACTMATRIXLOADER_H_ +#define INTELLISTREAM_INCLUDE_MATRIXLOADER_ABSTRACTMATRIXLOADER_H_ + +#include +#include +#include +#include +namespace AMMBench { +/** + * @ingroup AMMBENCH_MatrixLOADER + * @{ + */ +/** + * @ingroup AMMBENCH_MatrixLOADER_abstract The abstract template + * @{ + */ +/** + * @class AbstractMatrixLoader MatrixLoader/AbstractMatrixLoader.h + * @brief The abstract class of matrix loader, parent for all loaders + * @ingroup AMMBENCH_MatrixLOADER_abstract + * @note: + * - Must have a global config by @ref setConfig + * @note Default behavior +* - create +* - call @ref setConfig, this function will also generate the tensor A and B correspondingly +* - call @ref getA and @ref getB (assuming we are benchmarking torch.mm(A,B)) + */ +class AbstractMatrixLoader { + public: + AbstractMatrixLoader() = default; + + ~AbstractMatrixLoader() = default; + /** + * @brief Set the GLOBAL config map related to this loader + * @param cfg The config map + * @return bool whether the config is successfully set + * @note + */ + virtual bool setConfig(INTELLI::ConfigMapPtr cfg); + /** + * @brief get the A matrix + * @return the generated A matrix + */ + virtual torch::Tensor getA(); + /** + * @brief get the B matrix + * @return the generated B matrix + */ + virtual torch::Tensor getB(); +}; +/** + * @ingroup AMMBENCH_MatrixLOADER_abstract + * @typedef AbstractMatrixLoaderPtr + * @brief The class to describe a shared pointer to @ref AbstractMatrixLoader + + */ +typedef std::shared_ptr AbstractMatrixLoaderPtr; +/** + * @ingroup AMMBENCH_MatrixLOADER_abstract + * @def newAbstractMatrixLoader + * @brief (Macro) To creat a new @ref AbstractMatrixLoader under shared pointer. + */ +#define newAbstractMatrixLoader std::make_shared +/** + * @} + */ +/** + * @} + */ +} // AMMBench + +#endif //INTELLISTREAM_INCLUDE_MATRIXLOADER_ABSTRACTMATRIXLOADER_H_ diff --git a/include/MatrixLoader/MatrixLoaderTable.h b/include/MatrixLoader/MatrixLoaderTable.h new file mode 100644 index 00000000..7fbdbc58 --- /dev/null +++ b/include/MatrixLoader/MatrixLoaderTable.h @@ -0,0 +1,85 @@ +// +// Created by tony on 10/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_MATRIXLOADER_MATRIXLOADERTABLE_H_ +#define INTELLISTREAM_INCLUDE_MATRIXLOADER_MATRIXLOADERTABLE_H_ +#include +#include +namespace AMMBench { +/** + * @ingroup AMMBENCH_MatrixLOADER + * @{ + */ +/** + * @ingroup AMMBENCH_MatrixLOADER_Table The Table to index all matrix loaders + * @{ + */ +/** + * @class MatrixLoaderTable MatrixLoader/MatrixLoaderTable.h + * @brief The table class to index all matrix loaders + * @ingroup AMMBENCH_MatrixLOADER_Table + * @note Default behavior +* - create +* - (optional) call @ref registerNewDataLoader for new loader +* - find a loader by @ref findMatrixLoader using its tag + * @note default tags + * - random @ref RandomMatrixLoader + * - sparse @ref SparseMatrixLoader + */ +class MatrixLoaderTable { + protected: + std::map loaderMap; + public: + /** + * @brief The constructing function + * @note If new MatrixLoader wants to be included by default, please revise the following in *.cpp + */ + MatrixLoaderTable(); + + ~MatrixLoaderTable() { + } + + /** + * @brief To register a new loader + * @param onew The new operator + * @param tag THe name tag + */ + void registerNewDataLoader(AMMBench::AbstractMatrixLoaderPtr dnew, std::string tag) { + loaderMap[tag] = dnew; + } + + /** + * @brief find a dataloader in the table according to its name + * @param name The nameTag of loader + * @return The MatrixLoader, nullptr if not found + */ + AMMBench::AbstractMatrixLoaderPtr findMatrixLoader(std::string name) { + if (loaderMap.count(name)) { + return loaderMap[name]; + } + return nullptr; + } + /** + * @ingroup AMMBENCH_MatrixLOADER_Table + * @typedef MatrixLoaderTablePtr + * @brief The class to describe a shared pointer to @ref MatrixLoaderTable + + */ + typedef std::shared_ptr MatrixLoaderTablePtr; +/** + * @ingroup AMMBENCH_MatrixLOADER_Table + * @def newMatrixLoaderTable + * @brief (Macro) To creat a new @ref MatrixLoaderTable under shared pointer. + */ +#define newMatrixLoaderTable std::make_shared +}; +/** + * @} + */ +/** + * @} + */ +} // AMMBench + +#endif //INTELLISTREAM_INCLUDE_MATRIXLOADER_MATRIXLOADERTABLE_H_ diff --git a/include/MatrixLoader/RandomMatrixLoader.h b/include/MatrixLoader/RandomMatrixLoader.h new file mode 100644 index 00000000..b2466c02 --- /dev/null +++ b/include/MatrixLoader/RandomMatrixLoader.h @@ -0,0 +1,91 @@ +/*! \file RandomMatrixLoader.h*/ +// +// Created by tony on 10/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_MATRIXLOADER_RANDOMMATRIXLOADER_H_ +#define INTELLISTREAM_INCLUDE_MATRIXLOADER_RANDOMMATRIXLOADER_H_ +#include +namespace AMMBench { +/** + * @ingroup AMMBENCH_MatrixLOADER + * @{ + */ +/** + * @ingroup AMMBENCH_MatrixLOADER_Random The Random generator + * @{ + */ +/** + * @class RandomMatrixLoader MatrixLoader/RandomMatrixLoader.h + * @brief The Random class of matrix loader + * @ingroup AMMBENCH_MatrixLOADER_Random + * @note: + * - Must have a global config by @ref setConfig + * @note Default behavior +* - create +* - call @ref setConfig, this function will also generate the tensor A and B correspondingly +* - call @ref getA and @ref getB (assuming we are benchmarking torch.mm(A,B)) + * @note: require config parameters and default values + * - "aRow" The rows in matrix A, U64, 100 + * - "aCol" The cols in matrix B, U64, 1000 + * - "bCol" The rows in matrix B, U64, 500 + * - "seed" The seed of inline random generator,U64,114514 + * @note: default name tags + * "random": @ref RandomMatrixLoader + */ +class RandomMatrixLoader : public AbstractMatrixLoader { + protected: + torch::Tensor A, B; + uint64_t aRow, aCol, bCol, seed; + /** + * @brief Inline logic of reading a config file + * @param cfg the config + */ + void paraseConfig(INTELLI::ConfigMapPtr cfg); + /** + * @brief inline logic of generating A and B + */ + void generateAB(); + public: + RandomMatrixLoader() = default; + + ~RandomMatrixLoader() = default; + /** + * @brief Set the GLOBAL config map related to this loader + * @param cfg The config map + * @return bool whether the config is successfully set + * @note + */ + virtual bool setConfig(INTELLI::ConfigMapPtr cfg); + /** + * @brief get the A matrix + * @return the generated A matrix + */ + virtual torch::Tensor getA(); + /** + * @brief get the B matrix + * @return the generated B matrix + */ + virtual torch::Tensor getB(); +}; +/** + * @ingroup AMMBENCH_MatrixLOADER_Random + * @typedef RandomMatrixLoaderPtr + * @brief The class to describe a shared pointer to @ref RandomMatrixLoader + + */ +typedef std::shared_ptr RandomMatrixLoaderPtr; +/** + * @ingroup AMMBENCH_MatrixLOADER_Random + * @def newRandomMatrixLoader + * @brief (Macro) To creat a new @ref RandomMatrixLoader under shared pointer. + */ +#define newRandomMatrixLoader std::make_shared +/** + * @} + */ +/** + * @} + */ +} +#endif //INTELLISTREAM_INCLUDE_MATRIXLOADER_RANDOMMATRIXLOADER_H_ diff --git a/include/MatrixLoader/SparseMatrixLoader.h b/include/MatrixLoader/SparseMatrixLoader.h new file mode 100644 index 00000000..50e632d2 --- /dev/null +++ b/include/MatrixLoader/SparseMatrixLoader.h @@ -0,0 +1,105 @@ +/*! \file SparseMatrixLoader.h*/ +// +// Created by tony on 10/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_MATRIXLOADER_SparseMATRIXLOADER_H_ +#define INTELLISTREAM_INCLUDE_MATRIXLOADER_SparseMATRIXLOADER_H_ +#include +namespace AMMBench { +/** + * @ingroup AMMBENCH_MatrixLOADER + * @{ + */ +/** + * @ingroup AMMBENCH_MatrixLOADER_Sparse The Sparse generator + * @{ + */ +/** + * @class SparseMatrixLoader MatrixLoader/SparseMatrixLoader.h + * @brief The matrix loader to generate adjustable sparse matrix with adjust rank reduction + * @ingroup AMMBENCH_MatrixLOADER_Sparse + * @note: + * - Must have a global config by @ref setConfig + * @note Default behavior +* - create +* - call @ref setConfig, this function will also generate the tensor A and B correspondingly +* - call @ref getA and @ref getB (assuming we are benchmarking torch.mm(A,B)) + * @note: require config parameters and default values + * - "aRow" The rows in matrix A, U64, 100 + * - "aCol" The cols in matrix B, U64, 1000 + * - "bCol" The rows in matrix B, U64, 500 + * - "seed" The seed of inline Sparse generator,U64,114514 + * - "aDensity" The density factor of matrix A, Double, 1.0 + * - "bDensity" The density factor of matrix B, Double, 1.0 + * - "aReduce" Reduce some rows of A to be linearly dependent, U64, 0 + * - "bReduce" Reduce some rows of A to be linearly dependent, U64, 0 + * @note: default name tags + * "sparse": @ref SparseMatrixLoader + */ +class SparseMatrixLoader : public AbstractMatrixLoader { + protected: + torch::Tensor A, B; + uint64_t aRow, aCol, bCol, seed, aReduce, bReduce; + double aDensity, bDensity; + + /** + * @brief Inline logic of generate the sparse matrix + * @param m the rows + * @param n the cols + * @param density the density in 0~1 + * @param reduceRows the number of rows to be reduced + */ + torch::Tensor genSparseMatrix(uint64_t m, uint64_t n, double density, uint64_t reduceRows); + /** + * @brief Inline logic of reading a config file + * @param cfg the config + */ + void paraseConfig(INTELLI::ConfigMapPtr cfg); + /** + * @brief inline logic of generating A and B + */ + void generateAB(); + public: + SparseMatrixLoader() = default; + + ~SparseMatrixLoader() = default; + /** + * @brief Set the GLOBAL config map related to this loader + * @param cfg The config map + * @return bool whether the config is successfully set + * @note + */ + virtual bool setConfig(INTELLI::ConfigMapPtr cfg); + /** + * @brief get the A matrix + * @return the generated A matrix + */ + virtual torch::Tensor getA(); + /** + * @brief get the B matrix + * @return the generated B matrix + */ + virtual torch::Tensor getB(); +}; +/** + * @ingroup AMMBENCH_MatrixLOADER_Sparse + * @typedef SparseMatrixLoaderPtr + * @brief The class to describe a shared pointer to @ref SparseMatrixLoader + + */ +typedef std::shared_ptr SparseMatrixLoaderPtr; +/** + * @ingroup AMMBENCH_MatrixLOADER_Sparse + * @def newSparseMatrixLoader + * @brief (Macro) To creat a new @ref SparseMatrixLoader under shared pointer. + */ +#define newSparseMatrixLoader std::make_shared +/** + * @} + */ +/** + * @} + */ +} +#endif //INTELLISTREAM_INCLUDE_MATRIXLOADER_SparseMATRIXLOADER_H_ diff --git a/include/Utils/ConfigMap.hpp b/include/Utils/ConfigMap.hpp index 9d703613..b26e6347 100644 --- a/include/Utils/ConfigMap.hpp +++ b/include/Utils/ConfigMap.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include /** * @defgroup INTELLI_UTIL diff --git a/include/Utils/IntelliLog.h b/include/Utils/IntelliLog.h index 7706b0f1..1ac69e33 100755 --- a/include/Utils/IntelliLog.h +++ b/include/Utils/IntelliLog.h @@ -110,19 +110,19 @@ class IntelliLog_FileProtector { * @def INTELLI_INFO * @brief (Macro) To log something as information */ -#define INTELLI_INFO(n) IntelliLog::log("INFO",n) +#define INTELLI_INFO(n) INTELLI::IntelliLog::log("INFO",n) /** * @ingroup INTELLI_UTIL_INTELLILOG * @def INTELLI_ERROR * @brief (Macro) To log something as error */ -#define INTELLI_ERROR(n) IntelliLog::log("ERROR",n) +#define INTELLI_ERROR(n) INTELLI::IntelliLog::log("ERROR",n) /** * @ingroup INTELLI_UTIL_INTELLILOG * @def INTELLI_Warning * @brief (Macro) To log something as warnning */ -#define INTELLI_WARNING(n) IntelliLog::log("WARNING",n) +#define INTELLI_WARNING(n) INTELLI::IntelliLog::log("WARNING",n) /** * @ingroup INTELLI_UTIL_INTELLILOG * @def INTELLI_DEBUG diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6cc3bb53..c0ba5ee2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(Utils) +add_subdirectory(MatrixLoader) add_sources( myVecAdd.cpp ) \ No newline at end of file diff --git a/src/MatrixLoader/AbstractMatrixLoader.cpp b/src/MatrixLoader/AbstractMatrixLoader.cpp new file mode 100644 index 00000000..1ea2aef0 --- /dev/null +++ b/src/MatrixLoader/AbstractMatrixLoader.cpp @@ -0,0 +1,17 @@ +// +// Created by tony on 10/05/23. +// + +#include + +//do nothing in abstract class +bool AMMBench::AbstractMatrixLoader::setConfig(INTELLI::ConfigMapPtr cfg) { + assert(cfg); + return true; +} +torch::Tensor AMMBench::AbstractMatrixLoader::getA() { + return torch::rand({1, 1}); +} +torch::Tensor AMMBench::AbstractMatrixLoader::getB() { + return torch::rand({1, 1}); +} diff --git a/src/MatrixLoader/CMakeLists.txt b/src/MatrixLoader/CMakeLists.txt new file mode 100644 index 00000000..b0585356 --- /dev/null +++ b/src/MatrixLoader/CMakeLists.txt @@ -0,0 +1,6 @@ +add_sources( + AbstractMatrixLoader.cpp + RandomMatrixLoader.cpp + SparseMatrixLoader.cpp + MatrixLoaderTable.cpp +) \ No newline at end of file diff --git a/src/MatrixLoader/MatrixLoaderTable.cpp b/src/MatrixLoader/MatrixLoaderTable.cpp new file mode 100644 index 00000000..80b82d15 --- /dev/null +++ b/src/MatrixLoader/MatrixLoaderTable.cpp @@ -0,0 +1,17 @@ +// +// Created by tony on 10/05/23. +// + +#include +#include +#include +namespace AMMBench { +/** + * @note revise me if you need new loader + */ +AMMBench::MatrixLoaderTable::MatrixLoaderTable() { + loaderMap["random"] = newRandomMatrixLoader(); + loaderMap["sparse"] = newSparseMatrixLoader(); +} + +} // AMMBench \ No newline at end of file diff --git a/src/MatrixLoader/RandomMatrixLoader.cpp b/src/MatrixLoader/RandomMatrixLoader.cpp new file mode 100644 index 00000000..f5089b85 --- /dev/null +++ b/src/MatrixLoader/RandomMatrixLoader.cpp @@ -0,0 +1,32 @@ +// +// Created by tony on 10/05/23. +// + +#include +#include +void AMMBench::RandomMatrixLoader::paraseConfig(INTELLI::ConfigMapPtr cfg) { + aRow = cfg->tryU64("aRow", 100, true); + aCol = cfg->tryU64("aCol", 1000, true); + bCol = cfg->tryU64("bCol", 500, true); + seed = cfg->tryU64("seed", 114514, true); + INTELLI_INFO( + "Generating [" + to_string(aRow) + "x" + to_string(aCol) + "]*[" + to_string(aCol) + "x" + to_string(bCol) + + "]"); +} +void AMMBench::RandomMatrixLoader::generateAB() { + torch::manual_seed(seed); + A = torch::rand({(long) aRow, (long) aCol}); + B = torch::rand({(long) aCol, (long) bCol}); +} +//do nothing in abstract class +bool AMMBench::RandomMatrixLoader::setConfig(INTELLI::ConfigMapPtr cfg) { + paraseConfig(cfg); + generateAB(); + return true; +} +torch::Tensor AMMBench::RandomMatrixLoader::getA() { + return A; +} +torch::Tensor AMMBench::RandomMatrixLoader::getB() { + return B; +} diff --git a/src/MatrixLoader/SparseMatrixLoader.cpp b/src/MatrixLoader/SparseMatrixLoader.cpp new file mode 100644 index 00000000..d19af797 --- /dev/null +++ b/src/MatrixLoader/SparseMatrixLoader.cpp @@ -0,0 +1,96 @@ +// +// Created by tony on 10/05/23. +// + +#include +#include +#include +#include +torch::Tensor AMMBench::SparseMatrixLoader::genSparseMatrix(uint64_t m, + uint64_t n, + double density, + uint64_t reduceRows) { + /** + * @brief 1. gen random mat + */ + auto mat = torch::rand({(long) m, (long) n}); + + // Iterate over each element of A and zero out the element with probability p + /** + * @brief 2. make it sparse according to density + */ + if (density < 1.0) { + for (uint64_t i = 0; i < m; i++) { + for (uint64_t j = 0; j < n; j++) { + if (torch::rand({1}).item() >= density) { + mat[i][j] = 0.0; + } + } + } + } + + /** + * @brief 3. reduce rows + */ + if (reduceRows == 0) { + return mat; + } + + std::vector selected_rows(reduceRows); + std::iota(selected_rows.begin(), selected_rows.end(), 0); + for (uint64_t i = reduceRows; i < m; ++i) { + uint64_t j = std::rand() % (i + 1); + if (j < reduceRows) { + selected_rows[j] = i; + } + } + for (const uint64_t &row_idx : selected_rows) { + //mat[row_idx]=mat[0]*torch::rand({1}).item(); + mat[row_idx] = mat[0]; + // do something with the row, e.g. print it + //std::cout << row_idx << std::endl; + + } + return mat; +} +void AMMBench::SparseMatrixLoader::paraseConfig(INTELLI::ConfigMapPtr cfg) { + aRow = cfg->tryU64("aRow", 100, true); + aCol = cfg->tryU64("aCol", 1000, true); + bCol = cfg->tryU64("bCol", 500, true); + seed = cfg->tryU64("seed", 114514, true); + aDensity = cfg->tryDouble("aDensity", 1.0, true); + bDensity = cfg->tryDouble("bDensity", 1.0, true); + aReduce = cfg->tryU64("aReduce", 0, true); + bReduce = cfg->tryU64("bReduce", 0, true); + if (aReduce >= aRow) { + aReduce = aRow - 1; + } + if (bReduce >= aCol) { + aReduce = aCol - 1; + } + INTELLI_INFO( + "Generating [" + to_string(aRow) + "x" + to_string(aCol) + "]*[" + to_string(aCol) + "x" + to_string(bCol) + + "], please wait for a while"); +} +void AMMBench::SparseMatrixLoader::generateAB() { + torch::manual_seed(seed); + std::srand(seed); + A = genSparseMatrix(aRow, aCol, aDensity, aReduce); + INTELLI_INFO( + "Sparse matrix A is done"); + B = genSparseMatrix(aCol, bCol, bDensity, bReduce); + INTELLI_INFO( + "Sparse matrix B is done"); +} +//do nothing in abstract class +bool AMMBench::SparseMatrixLoader::setConfig(INTELLI::ConfigMapPtr cfg) { + paraseConfig(cfg); + generateAB(); + return true; +} +torch::Tensor AMMBench::SparseMatrixLoader::getA() { + return A; +} +torch::Tensor AMMBench::SparseMatrixLoader::getB() { + return B; +} diff --git a/test/SystemTest/SimpleTest.cpp b/test/SystemTest/SimpleTest.cpp index 9dc2c4d5..5aad51e3 100644 --- a/test/SystemTest/SimpleTest.cpp +++ b/test/SystemTest/SimpleTest.cpp @@ -2,7 +2,8 @@ #define CATCH_CONFIG_MAIN #include "catch.hpp" - +#include +#include using namespace std; TEST_CASE("Test basic", "[short]") @@ -10,4 +11,24 @@ TEST_CASE("Test basic", "[short]") int a = 0; // place your test here REQUIRE(a == 0); +} +TEST_CASE("Generate spase matrix", "[short]") +{ + int a = 0; + INTELLI::ConfigMapPtr cfg = newConfigMap(); + cfg->edit("aRow", (uint64_t) 6); + cfg->edit("aCol", (uint64_t) 6); + cfg->edit("bCol", (uint64_t) 6); + cfg->edit("aDensity", (double) 1.0); + cfg->edit("bDensity", (double) 0.5); + cfg->edit("aReduce", (uint64_t) 1); + cfg->edit("bReduce", (uint64_t) 2); + AMMBench::SparseMatrixLoader sml; + sml.setConfig(cfg); + cout << "sparse A" << endl; + cout << sml.getA() << endl; + cout << "sparse B" << endl; + cout << sml.getB() << endl; + // place your test here + REQUIRE(a == 0); } \ No newline at end of file