CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
187 lines
8.8 KiB
Python
187 lines
8.8 KiB
Python
#!/usr/bin/env python3
|
|
import argparse
|
|
import os
|
|
import re
|
|
import sys
|
|
import matplotlib
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.cm as cm
|
|
import numpy as np
|
|
|
|
parser = argparse.ArgumentParser(description='Used with completed datasets from performancereport.py to compare different functions\' performance.\n' +
|
|
'Works with hipblas-bench and hipBLAS\' performancereport.py. Can also be used with rocblas-bench and rocBLAS\' performancereport.py with ' +
|
|
'command line arguments.',
|
|
epilog='Example usage: ./combine_plots.py -s N -d ./output_gemm/run00 -d ./output_symm/run00')
|
|
parser.add_argument('-s', '--size_arg', help='Value which to base the x axis "size" on.', dest='size_arg', default='N')
|
|
parser.add_argument('-d', '--dir', action='append', help='Each directory containing data which you would like to compare.', dest='dirs', required=True)
|
|
parser.add_argument('-t', '--titles', action='append', help='The subtitle name for the resulting plot for each directory, in the same order as the arguments passed in --dir.', dest='titles')
|
|
parser.add_argument('-f', '--savedir', type=str, help='Directory where resulting plots will be saved.', dest='savedir', default='combine_plots')
|
|
parser.add_argument('-x', '--executable', type=str, help='Name of the executable used to run perf tests.', dest='executable_name', default='hipblas-bench')
|
|
parser.add_argument('--search_str', type=str, help='A search string to find data line in data files.', dest='search_string', default='hipblas-Gflops')
|
|
|
|
args = parser.parse_args()
|
|
|
|
def get_all_files(directory_str):
|
|
"""
|
|
returns a list of *.out files in the given directory.
|
|
|
|
Parameters:
|
|
directory_str (string): the directory which we are gathering files from
|
|
Returns:
|
|
ret_list (list[string]): a list of file paths in the directory which end in .out
|
|
"""
|
|
ret_list = []
|
|
|
|
# only reading .out files as they contain the input parameters we need (func name, precision),
|
|
# along with the output parameters we need (gflops)
|
|
for f in os.listdir(os.fsencode(directory_str)):
|
|
filename = os.fsdecode(f)
|
|
if filename.endswith(".out"):
|
|
ret_list.append(os.path.join(directory_str, filename))
|
|
|
|
return ret_list
|
|
|
|
def get_output_val_from_file(filename, output_param='hipblas-Gflops', gflops_str='hipblas-Gflops'):
|
|
"""
|
|
parses through file and returns the val as given in the file.
|
|
|
|
Parameters:
|
|
filename (string): path of the file to parse.
|
|
output_param (string): the output parameter which we are parsing the file for.
|
|
gflops_str (string): string to parse file for in csv portion.
|
|
Returns:
|
|
value (string): the gflops as listed in the file, refer to example file (TODO).
|
|
"""
|
|
if os.path.exists(filename):
|
|
lines = open(filename, 'r').readlines()
|
|
|
|
for i in range(0, len(lines)):
|
|
if(output_param in lines[i]):
|
|
arg_line = lines[i].split(",")
|
|
data_line = re.split(r',\s*(?![^()]*\))', lines[i+1])
|
|
idx = arg_line.index(gflops_str)
|
|
return data_line[idx]
|
|
|
|
return '-1'
|
|
|
|
def get_input_param_from_file(filename, input_param, executable_name = 'hipblas-bench'):
|
|
"""
|
|
parses through file and returns the function name as given in the file (by the -f argument passed to xxx-bench).
|
|
|
|
Parameters:
|
|
filename (string): path of the file to parse.
|
|
input_param (string): the input parameter which we are parsing the file for. For example, '-f' to parse function name.
|
|
executable_name (string): executable name that we can use to parse the function name in the data file
|
|
Returns:
|
|
funcname (string): function name as given by the -f argument passed to xxx-bench.
|
|
"""
|
|
if os.path.exists(filename):
|
|
lines = open(filename, 'r').readlines()
|
|
|
|
for line in lines:
|
|
if executable_name in line:
|
|
linesplit = line.split()
|
|
return linesplit[linesplit.index(input_param)+1]
|
|
|
|
raise RuntimeError('Cannot find input param ' + input_param + ' in file: ' + filename)
|
|
|
|
def get_data_from_directories(directories, size_param = 'N', executable_name = 'hipblas-bench', search_string = 'hipblas-Gflops'):
|
|
"""
|
|
For each directory in directories, gathers function name, precisions, sizes, and gflops from within files in that directory and returns it.
|
|
|
|
Parameters:
|
|
directories (list[string]): list of directory names to gather information from
|
|
size_param (string): parameter in file which defines the "size"
|
|
executable_name (string): executable name that we can use to parse the function name in the data file
|
|
search_string (string): the string which we used to find the data line in the .out file
|
|
Returns:
|
|
res_dicts (list[dict{string: list[(int, float)]}]): for each directory; for each precision in any file within that directory, this dictionary contains a list
|
|
of tuples for that precision containing sizes (as defined by size_param) and the corresponding
|
|
gflops value from a file.
|
|
res_funcs (list[string]): a list of function names, one function name is gathered from each directory. Each function name corresponds to dictionary
|
|
at the same index in res_dicts.
|
|
"""
|
|
res_dicts = []
|
|
res_funcs = []
|
|
for directory in directories:
|
|
cur_funcname = None
|
|
cur_dict = {}
|
|
|
|
for f in get_all_files(directory):
|
|
# append funcname to list of funcnames, only for first file in each directory as we assume
|
|
# each directory has data for only one function (but multiple precisions)
|
|
if cur_funcname is None:
|
|
cur_funcname = get_input_param_from_file(f, '-f')
|
|
|
|
prec = get_input_param_from_file(f, '-r', executable_name)
|
|
|
|
# a tuple of (size, gflops) as gathered from the current file
|
|
size_perf_tuple = (int(get_output_val_from_file(f, search_string, size_param)), float(get_output_val_from_file(f, search_string)))
|
|
if prec in cur_dict:
|
|
cur_dict[prec].append(size_perf_tuple)
|
|
else:
|
|
cur_dict[prec] = [size_perf_tuple]
|
|
|
|
res_dicts.append(cur_dict)
|
|
res_funcs.append(cur_funcname)
|
|
|
|
return res_dicts, res_funcs
|
|
|
|
def plot_data(gflops_dicts, titles, savedir, size_arg = 'N'):
|
|
"""
|
|
plots gflops data from dictionaries, one plot for each common precision present in all dictionaries.
|
|
|
|
Parameters:
|
|
gflops_dicts (list[dict{string: list[(int, float)]}]): data as given by :func:`get_data_from_directories`.
|
|
titles (list[string]): a list of titles for each data set to be plotted and used as a savefile name.
|
|
savedir (string): directory where resulting plots will be saved.
|
|
size_arg (string): x axis title on plot.
|
|
"""
|
|
if len(gflops_dicts) == 0:
|
|
return
|
|
|
|
gflops_dict0 = gflops_dicts[0]
|
|
for prec, _ in gflops_dict0.items():
|
|
colors=iter(cm.rainbow(np.linspace(0,1,len(gflops_dicts))))
|
|
figure, axes = plt.subplots(figsize=(7,7))
|
|
for gflops_dict, funcname in zip(gflops_dicts, titles):
|
|
cur_color = next(colors)
|
|
if prec not in gflops_dict:
|
|
continue
|
|
gflops = gflops_dict[prec]
|
|
gflops.append((0, 0)) # I prefer having a 0 at the bottom so the performance looks more accurate
|
|
sorted_tuples = sorted(gflops)
|
|
sorted_sizes = [x[0] for x in sorted_tuples]
|
|
sorted_gflops = [x[1] for x in sorted_tuples]
|
|
|
|
axes.scatter(sorted_sizes, sorted_gflops, color=cur_color, label=funcname)
|
|
axes.plot(sorted_sizes, sorted_gflops, '-ok', color=cur_color)
|
|
|
|
axes.set_xlabel('='.join(size_arg)) # in case we add multiple params
|
|
axes.set_ylabel('gflops')
|
|
|
|
# magic numbers from performancereport.py to make plots look nice
|
|
axes.legend(fontsize=10, bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left',
|
|
mode='expand', borderaxespad=0.)
|
|
figure.tight_layout(rect=(0,0.05,1.0,1.0))
|
|
|
|
filename = ''
|
|
for func in titles:
|
|
if filename != '':
|
|
filename += '_'
|
|
filename += func
|
|
filename += '_' + prec
|
|
if not os.path.exists(savedir):
|
|
os.makedirs(savedir)
|
|
figure.savefig(os.path.join(os.getcwd(), savedir, filename))
|
|
|
|
gflops, funcnames = get_data_from_directories(args.dirs, args.size_arg, args.executable_name, args.search_string)
|
|
|
|
if args.titles:
|
|
if len(args.titles) == len(gflops):
|
|
funcnames = args.titles
|
|
else:
|
|
raise RuntimeError('Must have same amount of -t parameters as -d parameters, or have no -t parameters.')
|
|
|
|
plot_data(gflops, funcnames, args.savedir, args.size_arg)
|