Added full support for synthetic matrices and added scaffolding for coo

This commit is contained in:
cephi 2024-12-12 17:36:15 -05:00
parent 47995eab85
commit 9aab9b18b9
15 changed files with 238 additions and 51 deletions

View File

@ -1,4 +1,4 @@
from data_stat import Cpu, Format from data_stat import Cpu, Format, MatrixType
import argparse import argparse
import glob import glob
@ -9,7 +9,8 @@ import random
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('cpu', choices=[x.name.lower() for x in Cpu]) parser.add_argument('cpu', choices=[x.name.lower() for x in Cpu])
parser.add_argument('output_dir') parser.add_argument('output_dir')
parser.add_argument('matrix_dir') parser.add_argument('matrix_type', type=str,
choices=[t.name.lower() for t in MatrixType])
parser.add_argument('format', type=str, parser.add_argument('format', type=str,
choices=[fmt.name.lower() for fmt in Format]) choices=[fmt.name.lower() for fmt in Format])
parser.add_argument('base_iterations', type=int) parser.add_argument('base_iterations', type=int)
@ -17,10 +18,14 @@ parser.add_argument('min_time_s', type=int)
parser.add_argument('baseline_time_s', type=int) parser.add_argument('baseline_time_s', type=int)
parser.add_argument('baseline_delay_s', type=int) parser.add_argument('baseline_delay_s', type=int)
#parser.add_argument('--perf', action='store_const', const='--perf') #parser.add_argument('--perf', action='store_const', const='--perf')
parser.add_argument('-m', '--matrix_dir', type=str)
parser.add_argument('-ss', '--synthetic_size', nargs="+", type=int)
parser.add_argument('-sd', '--synthetic_density', nargs="+", type=float)
parser.add_argument('--power', action='store_const', const='--power') parser.add_argument('--power', action='store_const', const='--power')
parser.add_argument('--distribute', action='store_true') parser.add_argument('--distribute', action='store_true')
args = parser.parse_args() args = parser.parse_args()
args.cpu = Cpu[args.cpu.upper()] args.cpu = Cpu[args.cpu.upper()]
args.matrix_type = MatrixType[args.matrix_type.upper()]
args.format = Format[args.format.upper()] args.format = Format[args.format.upper()]
srun_args = { srun_args = {
@ -63,15 +68,28 @@ python = {
Cpu.XEON_4216: 'python3.11' Cpu.XEON_4216: 'python3.11'
} }
def run(run_args, matrix_file: str, srun_args_list: list = None) -> list: def run(
run_args,
matrix_file: str,
synthetic_size: int,
synthetic_density: float,
srun_args_list: list = None
) -> list:
run_args_list = [ run_args_list = [
args.cpu.name.lower(), args.cpu.name.lower(),
matrix_file, args.matrix_type.name.lower(),
args.format.name.lower(), args.format.name.lower(),
str(args.base_iterations), str(args.base_iterations),
str(args.min_time_s), str(args.min_time_s),
str(args.baseline_time_s), str(args.baseline_time_s),
str(args.baseline_delay_s)] str(args.baseline_delay_s)]
if args.matrix_type == MatrixType.SUITESPARSE:
run_args_list += ['-m', matrix_file]
elif args.matrix_type == MatrixType.SYNTHETIC:
run_args_list += ['-ss', str(synthetic_size), '-sd', str(synthetic_density)]
else:
exit("Unrecognized matrix type!")
# if args.perf is not None: # if args.perf is not None:
# run_args_list += [args.perf] # run_args_list += [args.perf]
if args.power is not None: if args.power is not None:
@ -87,7 +105,15 @@ def run(run_args, matrix_file: str, srun_args_list: list = None) -> list:
processes = list() processes = list()
for i, matrix in enumerate(glob.glob(f'{args.matrix_dir.rstrip("/")}/*.mtx')): if args.matrix_type == MatrixType.SUITESPARSE:
parameter_list = enumerate(glob.glob(f'{args.matrix_dir.rstrip("/")}/*.mtx'))
elif args.matrix_type == MatrixType.SYNTHETIC:
parameter_list = enumerate([(size, density)
for size in args.synthetic_size
for density in args.synthetic_density])
#for i, matrix in enumerate(glob.glob(f'{args.matrix_dir.rstrip("/")}/*.mtx')):
for i, parameter in parameter_list:
#if args.distribute: #if args.distribute:
# if args.cpu == Cpu.ALTRA: # if args.cpu == Cpu.ALTRA:
# i = i % 40 # i = i % 40
@ -97,12 +123,19 @@ for i, matrix in enumerate(glob.glob(f'{args.matrix_dir.rstrip("/")}/*.mtx')):
#else: #else:
srun_args_temp = srun_args[args.cpu] srun_args_temp = srun_args[args.cpu]
output_filename = '_'.join([ synthetic_size = args.synthetic_size
synthetic_density = args.synthetic_density
output_filename_list = [
args.cpu.name.lower(), args.cpu.name.lower(),
str(args.min_time_s), str(args.min_time_s),
str(args.baseline_time_s), str(args.baseline_time_s),
str(args.baseline_delay_s), str(args.baseline_delay_s)]
os.path.splitext(os.path.basename(matrix))[0]]) if args.matrix_type == MatrixType.SUITESPARSE:
output_filename_list += [os.path.splitext(os.path.basename(parameter))[0]]
elif args.matrix_type == MatrixType.SYNTHETIC:
output_filename_list += [str(parameter[0]), str(parameter[1])]
output_filename = '_'.join(output_filename_list)
json_filepath = f'{args.output_dir.rstrip("/")}/{output_filename}.json' json_filepath = f'{args.output_dir.rstrip("/")}/{output_filename}.json'
raw_filepath = f'{args.output_dir.rstrip("/")}/{output_filename}.output' raw_filepath = f'{args.output_dir.rstrip("/")}/{output_filename}.output'
@ -111,13 +144,17 @@ for i, matrix in enumerate(glob.glob(f'{args.matrix_dir.rstrip("/")}/*.mtx')):
print(raw_filepath) print(raw_filepath)
if args.distribute: if args.distribute:
processes.append(subprocess.Popen( processes.append(subprocess.Popen(run(
run(args, matrix, srun_args_temp), args,
parameter,
parameter[0],
parameter[1],
srun_args_temp),
stdout=json_file, stdout=json_file,
stderr=raw_file)) stderr=raw_file))
else: else:
subprocess.run( subprocess.run(
run(args, matrix), run(args, parameter, parameter[0], parameter[1]),
stdout=json_file, stdout=json_file,
stderr=raw_file) stderr=raw_file)

View File

@ -0,0 +1 @@
{"CPU": "Altra", "ITERATIONS": 82249, "MATRIX_TYPE": "synthetic", "MATRIX_FORMAT": "csr", "MATRIX_SHAPE": [100000, 100000], "MATRIX_SIZE": 10000000000, "MATRIX_NNZ": 999948, "MATRIX_DENSITY": 9.99948e-05, "TIME_S": 12.20802617073059, "TIME_S_1KI": 0.14842765469161437, "BASELINE_TIME_S": 2, "BASELINE_DELAY_S": 10, "J": 1033.954319496155, "W": 84.9319356344559, "J_1KI": 12.57102602458577, "W_1KI": 1.032619674822258, "W_D": 74.4169356344559, "J_D": 905.9455841684344, "W_D_1KI": 0.9047761752052413, "J_D_1KI": 0.011000451983674468}

View File

@ -0,0 +1,17 @@
/nfshomes/vut/ampere_research/pytorch/spmv.py:57: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at /space/jenkins/workspace/Releases/pytorch-dls/pytorch-dls/aten/src/ATen/SparseCsrTensorImpl.cpp:55.)
matrix = matrix.to_sparse_csr().type(torch.float32)
tensor(crow_indices=tensor([ 0, 12, 20, ..., 999931, 999940,
999948]),
col_indices=tensor([20217, 25552, 38877, ..., 63581, 75717, 96314]),
values=tensor([-1.5899, -0.7194, -0.7547, ..., 0.5402, -0.1912,
-0.1167]), size=(100000, 100000), nnz=999948,
layout=torch.sparse_csr)
tensor([0.7377, 0.7528, 0.7695, ..., 0.6702, 0.9924, 0.8686])
Matrix: synthetic
Matrix: csr
Shape: torch.Size([100000, 100000])
Size: 10000000000
NNZ: 999948
Density: 9.99948e-05
Time: 12.20802617073059 seconds

View File

@ -0,0 +1 @@
{"CPU": "Altra", "ITERATIONS": 104724, "MATRIX_TYPE": "synthetic", "MATRIX_FORMAT": "csr", "MATRIX_SHAPE": [100000, 100000], "MATRIX_SIZE": 10000000000, "MATRIX_NNZ": 99999, "MATRIX_DENSITY": 9.9999e-06, "TIME_S": 10.740116596221924, "TIME_S_1KI": 0.10255640155286203, "BASELINE_TIME_S": 2, "BASELINE_DELAY_S": 10, "J": 720.857314195633, "W": 76.49734010579499, "J_1KI": 6.883401266143702, "W_1KI": 0.7304661787727262, "W_D": 65.89234010579499, "J_D": 620.9232275140286, "W_D_1KI": 0.6291999933710991, "J_D_1KI": 0.0060081738032456665}

View File

@ -0,0 +1,16 @@
/nfshomes/vut/ampere_research/pytorch/spmv.py:57: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at /space/jenkins/workspace/Releases/pytorch-dls/pytorch-dls/aten/src/ATen/SparseCsrTensorImpl.cpp:55.)
matrix = matrix.to_sparse_csr().type(torch.float32)
tensor(crow_indices=tensor([ 0, 0, 1, ..., 99990, 99994, 99999]),
col_indices=tensor([77500, 30298, 91629, ..., 67143, 70964, 98118]),
values=tensor([ 0.0300, -1.0927, 1.5365, ..., -1.2655, 1.0213,
0.2378]), size=(100000, 100000), nnz=99999,
layout=torch.sparse_csr)
tensor([0.9139, 0.4903, 0.5737, ..., 0.7094, 0.3230, 0.9275])
Matrix: synthetic
Matrix: csr
Shape: torch.Size([100000, 100000])
Size: 10000000000
NNZ: 99999
Density: 9.9999e-06
Time: 10.740116596221924 seconds

View File

@ -0,0 +1 @@
{"CPU": "Epyc 7313P", "ITERATIONS": 101034, "MATRIX_TYPE": "synthetic", "MATRIX_FORMAT": "csr", "MATRIX_SHAPE": [100000, 100000], "MATRIX_SIZE": 10000000000, "MATRIX_NNZ": 999955, "MATRIX_DENSITY": 9.99955e-05, "TIME_S": 10.361092805862427, "TIME_S_1KI": 0.10255055531665011, "BASELINE_TIME_S": 2, "BASELINE_DELAY_S": 10, "J": 1568.5116010475158, "W": 147.64, "J_1KI": 15.524591731966623, "W_1KI": 1.4612902587247856, "W_D": 127.57249999999999, "J_D": 1355.316623033285, "W_D_1KI": 1.2626690025140053, "J_D_1KI": 0.012497466224379963}

View File

@ -0,0 +1,17 @@
/nfshomes/vut/ampere_research/pytorch/spmv.py:57: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:53.)
matrix = matrix.to_sparse_csr().type(torch.float32)
tensor(crow_indices=tensor([ 0, 12, 24, ..., 999933, 999940,
999955]),
col_indices=tensor([ 5967, 15636, 19622, ..., 82825, 87847, 97213]),
values=tensor([-1.5657, 1.3165, 0.1051, ..., -0.5017, 0.1827,
-1.1977]), size=(100000, 100000), nnz=999955,
layout=torch.sparse_csr)
tensor([0.4289, 0.2254, 0.8435, ..., 0.1753, 0.8896, 0.3058])
Matrix: synthetic
Matrix: csr
Shape: torch.Size([100000, 100000])
Size: 10000000000
NNZ: 999955
Density: 9.99955e-05
Time: 10.361092805862427 seconds

View File

@ -0,0 +1 @@
{"CPU": "Epyc 7313P", "ITERATIONS": 150582, "MATRIX_TYPE": "synthetic", "MATRIX_FORMAT": "csr", "MATRIX_SHAPE": [100000, 100000], "MATRIX_SIZE": 10000000000, "MATRIX_NNZ": 100000, "MATRIX_DENSITY": 1e-05, "TIME_S": 10.027292013168335, "TIME_S_1KI": 0.06659024327720667, "BASELINE_TIME_S": 2, "BASELINE_DELAY_S": 10, "J": 1239.2374660491944, "W": 116.83, "J_1KI": 8.229652057013418, "W_1KI": 0.7758563440517459, "W_D": 97.04249999999999, "J_D": 1029.3477856636046, "W_D_1KI": 0.6444495358010917, "J_D_1KI": 0.0042797249060385146}

View File

@ -0,0 +1,17 @@
/nfshomes/vut/ampere_research/pytorch/spmv.py:57: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:53.)
matrix = matrix.to_sparse_csr().type(torch.float32)
tensor(crow_indices=tensor([ 0, 1, 2, ..., 99996, 99997,
100000]),
col_indices=tensor([98366, 86469, 784, ..., 24883, 35225, 74645]),
values=tensor([ 0.5652, 0.5870, -0.9667, ..., -0.8134, 0.3649,
-0.5054]), size=(100000, 100000), nnz=100000,
layout=torch.sparse_csr)
tensor([0.7832, 0.0968, 0.2513, ..., 0.3975, 0.2140, 0.9668])
Matrix: synthetic
Matrix: csr
Shape: torch.Size([100000, 100000])
Size: 10000000000
NNZ: 100000
Density: 1e-05
Time: 10.027292013168335 seconds

View File

@ -0,0 +1 @@
{"CPU": "Xeon 4216", "ITERATIONS": 41245, "MATRIX_TYPE": "synthetic", "MATRIX_FORMAT": "csr", "MATRIX_SHAPE": [100000, 100000], "MATRIX_SIZE": 10000000000, "MATRIX_NNZ": 999957, "MATRIX_DENSITY": 9.99957e-05, "TIME_S": 10.48258900642395, "TIME_S_1KI": 0.2541541764195406, "BASELINE_TIME_S": 2, "BASELINE_DELAY_S": 10, "J": 907.7721267700196, "W": 86.4, "J_1KI": 22.00926480227954, "W_1KI": 2.0947993696205605, "W_D": 77.29, "J_D": 812.0568018293382, "W_D_1KI": 1.8739241120135777, "J_D_1KI": 0.045433970469476975}

View File

@ -0,0 +1,17 @@
/nfshomes/vut/ampere_research/pytorch/spmv.py:57: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:53.)
matrix = matrix.to_sparse_csr().type(torch.float32)
tensor(crow_indices=tensor([ 0, 10, 20, ..., 999933, 999947,
999957]),
col_indices=tensor([10614, 12000, 12630, ..., 76477, 82289, 92989]),
values=tensor([ 0.5650, 0.5553, -0.5300, ..., 0.3637, -1.1395,
0.7341]), size=(100000, 100000), nnz=999957,
layout=torch.sparse_csr)
tensor([0.5083, 0.7251, 0.1206, ..., 0.9177, 0.3147, 0.5521])
Matrix: synthetic
Matrix: csr
Shape: torch.Size([100000, 100000])
Size: 10000000000
NNZ: 999957
Density: 9.99957e-05
Time: 10.48258900642395 seconds

View File

@ -0,0 +1 @@
{"CPU": "Xeon 4216", "ITERATIONS": 118541, "MATRIX_TYPE": "synthetic", "MATRIX_FORMAT": "csr", "MATRIX_SHAPE": [100000, 100000], "MATRIX_SIZE": 10000000000, "MATRIX_NNZ": 99998, "MATRIX_DENSITY": 9.9998e-06, "TIME_S": 10.91425085067749, "TIME_S_1KI": 0.09207152673486381, "BASELINE_TIME_S": 2, "BASELINE_DELAY_S": 10, "J": 868.9650503587723, "W": 82.07, "J_1KI": 7.3305021077835715, "W_1KI": 0.6923342978378788, "W_D": 72.5, "J_D": 767.636970281601, "W_D_1KI": 0.6116027366059, "J_D_1KI": 0.005159419412742426}

View File

@ -0,0 +1,16 @@
/nfshomes/vut/ampere_research/pytorch/spmv.py:57: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:53.)
matrix = matrix.to_sparse_csr().type(torch.float32)
tensor(crow_indices=tensor([ 0, 2, 3, ..., 99997, 99997, 99998]),
col_indices=tensor([90305, 96230, 86891, ..., 66888, 39495, 21203]),
values=tensor([-0.5290, 1.7137, 0.7615, ..., 1.2465, -0.3855,
-0.4542]), size=(100000, 100000), nnz=99998,
layout=torch.sparse_csr)
tensor([0.2048, 0.5046, 0.8421, ..., 0.4453, 0.3792, 0.7036])
Matrix: synthetic
Matrix: csr
Shape: torch.Size([100000, 100000])
Size: 10000000000
NNZ: 99998
Density: 9.9998e-06
Time: 10.91425085067749 seconds

View File

@ -1,5 +1,5 @@
import data_stat import data_stat
from data_stat import Stat, Cpu, Format from data_stat import Stat, Cpu, Format, MatrixType
import argparse import argparse
import os, sys import os, sys
@ -9,7 +9,8 @@ import time
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('cpu', choices=[x.name.lower() for x in Cpu]) parser.add_argument('cpu', choices=[x.name.lower() for x in Cpu])
parser.add_argument('matrix_file') parser.add_argument('matrix_type', type=str,
choices=[t.name.lower() for t in MatrixType])
parser.add_argument('format', type=str, parser.add_argument('format', type=str,
choices=[fmt.name.lower() for fmt in Format]) choices=[fmt.name.lower() for fmt in Format])
parser.add_argument('base_iterations', type=int) parser.add_argument('base_iterations', type=int)
@ -17,11 +18,16 @@ parser.add_argument('min_time_s', type=int)
parser.add_argument('baseline_time_s', type=int) parser.add_argument('baseline_time_s', type=int)
parser.add_argument('baseline_delay_s', type=int) parser.add_argument('baseline_delay_s', type=int)
#parser.add_argument('--perf', action='store_true') #parser.add_argument('--perf', action='store_true')
parser.add_argument('-m', '--matrix_file', type=str)
parser.add_argument('-ss', '--synthetic_size', type=int)
parser.add_argument('-sd', '--synthetic_density', type=float)
parser.add_argument('--power', action='store_true') parser.add_argument('--power', action='store_true')
parser.add_argument('-d', '--debug', action='store_true') parser.add_argument('-d', '--debug', action='store_true')
args = parser.parse_args() args = parser.parse_args()
args.cpu = Cpu[args.cpu.upper()] args.cpu = Cpu[args.cpu.upper()]
args.matrix_type = MatrixType[args.matrix_type.upper()]
args.format = Format[args.format.upper()] args.format = Format[args.format.upper()]
assert args.baseline_time_s >= 2
python = { python = {
Cpu.ALTRA: 'python3', Cpu.ALTRA: 'python3',
@ -38,21 +44,39 @@ perf_args = {
['-M', 'l2_cache_miss_ratio,l2_tlb_miss_ratio,ll_cache_read_miss_ratio']] ['-M', 'l2_cache_miss_ratio,l2_tlb_miss_ratio,ll_cache_read_miss_ratio']]
} }
def program(cpu: Cpu, matrix_file: str, iterations: int) -> list: def program(
cpu: Cpu,
matrix_type: MatrixType,
fmt: Format,
iterations: int,
matrix_file: str,
synthetic_size: int,
synthetic_density: float
) -> list:
spmv = f'python3 spmv.py {matrix_type.name.lower()} {fmt.name.lower()} '
spmv += f'{iterations} '
if matrix_type == MatrixType.SUITESPARSE:
spmv += f'-m {matrix_file}'
elif matrix_type == MatrixType.SYNTHETIC:
spmv += f'-ss {synthetic_size} -sd {synthetic_density}'
else:
exit("Unrecognized matrix type!")
if cpu == Cpu.ALTRA: if cpu == Cpu.ALTRA:
return [ return [
'apptainer', 'run', 'pytorch-altra.sif', '-c', 'apptainer', 'run', 'pytorch-altra.sif', '-c',
'numactl --cpunodebind=0 --membind=0 ' 'numactl --cpunodebind=0 --membind=0 ' + spmv]
+ f'python3 spmv.py {iterations} csr -m {matrix_file}'] #+ f'python3 spmv.py {matrix_type.name.lower()} '
#+ f'csr {iterations} -m {matrix_file}']
elif cpu == Cpu.EPYC_7313P: elif cpu == Cpu.EPYC_7313P:
return [ return ['apptainer', 'run', 'pytorch-epyc_7313p.sif'] + spmv.split(' ')
'apptainer', 'run', 'pytorch-epyc_7313p.sif', #'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}']
'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}']
elif cpu == Cpu.XEON_4216: elif cpu == Cpu.XEON_4216:
return [ return [
'apptainer', 'run', 'pytorch-xeon_4216.sif', 'apptainer', 'run', 'pytorch-xeon_4216.sif',
'numactl', '--cpunodebind=0', '--membind=0', 'numactl', '--cpunodebind=0', '--membind=0'
'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}'] ] + spmv.split(' ')
#'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}']
def baseline_power(cpu: Cpu, baseline_time_s: int) -> list: def baseline_power(cpu: Cpu, baseline_time_s: int) -> list:
power_process = subprocess.Popen(['./power.sh', str(baseline_time_s)], power_process = subprocess.Popen(['./power.sh', str(baseline_time_s)],
@ -61,14 +85,14 @@ def baseline_power(cpu: Cpu, baseline_time_s: int) -> list:
def run_program(program: list[str]) -> tuple[dict, str]: def run_program(program: list[str]) -> tuple[dict, str]:
if args.debug: if args.debug:
print(program) print(program, file=sys.stderr)
process = subprocess.run(program, process = subprocess.run(program,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
process.check_returncode() process.check_returncode()
if args.debug: if args.debug:
print(process.stdout) print(process.stdout, file=sys.stderr)
print(process.stderr) print(process.stderr, file=sys.stderr)
return (json.loads(process.stdout), process.stderr) return (json.loads(process.stdout), process.stderr)
def trapezoidal_rule(power: list[float], time_s: float) -> float: def trapezoidal_rule(power: list[float], time_s: float) -> float:
@ -85,17 +109,21 @@ def trapezoidal_rule(power: list[float], time_s: float) -> float:
return result return result
result = dict() result = dict()
result[Stat.CPU.name] = args.cpu.name result[Stat.CPU.name] = args.cpu.value
iterations = args.base_iterations iterations = args.base_iterations
program_result = run_program(program(args.cpu, args.matrix_file, iterations)) program_result = run_program(program(
args.cpu, args.matrix_type, args.format, iterations,
args.matrix_file, args.synthetic_size, args.synthetic_density))
while program_result[0][Stat.TIME_S.name] < args.min_time_s: while program_result[0][Stat.TIME_S.name] < args.min_time_s:
# Increase the number of iterations by difference between the current time taken and the desired time. # Increase the number of iterations by difference between the current time taken and the desired time.
iterations *= 1 / (program_result[0][Stat.TIME_S.name] / args.min_time_s) iterations *= 1 / (program_result[0][Stat.TIME_S.name] / args.min_time_s)
# Add another 5% for safety. # Add another 5% for safety.
iterations += iterations * 0.05 iterations += iterations * 0.05
iterations = int(iterations) iterations = int(iterations)
program_result = run_program(program(args.cpu, args.matrix_file, iterations)) program_result = run_program(program(
args.cpu, args.matrix_type, args.format, iterations,
args.matrix_file, args.synthetic_size, args.synthetic_density))
result[Stat.ITERATIONS.name] = iterations result[Stat.ITERATIONS.name] = iterations
@ -114,12 +142,15 @@ if args.power:
time.sleep(args.baseline_delay_s) time.sleep(args.baseline_delay_s)
baseline_list = baseline_power(args.cpu, args.baseline_time_s) baseline_list = baseline_power(args.cpu, args.baseline_time_s)
if args.debug: if args.debug:
print(baseline_list) print(baseline_list, file=sys.stderr)
assert(len(baseline_list) == args.baseline_time_s) assert(len(baseline_list) == args.baseline_time_s)
# Power Collection # Power Collection
power_process = subprocess.run( power_process = subprocess.run(
['./power.sh', '-1'] + program(args.cpu, args.matrix_file, result[Stat.ITERATIONS.name]), ['./power.sh', '-1'] + program(
args.cpu, args.matrix_type, args.format,
result[Stat.ITERATIONS.name],
args.matrix_file, args.synthetic_size, args.synthetic_density),
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
power_process.check_returncode() power_process.check_returncode()
@ -127,8 +158,8 @@ if args.power:
for x in power_process.stdout.strip().split('\n')] for x in power_process.stdout.strip().split('\n')]
power_time_s = json.loads(power_process.stderr)[Stat.TIME_S.name] power_time_s = json.loads(power_process.stderr)[Stat.TIME_S.name]
if args.debug: if args.debug:
print(power_list) print(power_list, file=sys.stderr)
print(power_time_s) print(power_time_s, file=sys.stderr)
if args.cpu == Cpu.ALTRA: if args.cpu == Cpu.ALTRA:
# Trapezoidal Rule across the last (s) power recordings. # Trapezoidal Rule across the last (s) power recordings.
@ -140,7 +171,7 @@ if args.power:
result[Stat.W.name] = result[Stat.J.name] / power_time_s result[Stat.W.name] = result[Stat.J.name] / power_time_s
if args.debug: if args.debug:
print(result) print(result, file=sys.stderr)
#print(len(result['power'])) #print(len(result['power']))
#print(sum(result['power']) / len(result['power'])) #print(sum(result['power']) / len(result['power']))
@ -148,7 +179,7 @@ if args.power:
time.sleep(args.baseline_delay_s) time.sleep(args.baseline_delay_s)
baseline_list += baseline_power(args.cpu, args.baseline_time_s) baseline_list += baseline_power(args.cpu, args.baseline_time_s)
if args.debug: if args.debug:
print(baseline_list) print(baseline_list, file=sys.stderr)
assert(len(baseline_list) / 2 == args.baseline_time_s) assert(len(baseline_list) / 2 == args.baseline_time_s)
baseline_joules = ( baseline_joules = (
@ -161,8 +192,8 @@ if args.power:
) )
baseline_wattage = baseline_joules / (args.baseline_time_s * 2) baseline_wattage = baseline_joules / (args.baseline_time_s * 2)
if args.debug: if args.debug:
print(baseline_joules) print(baseline_joules, file=sys.stderr)
print(baseline_wattage) print(baseline_wattage, file=sys.stderr)
result[Stat.J_1KI.name] = ( result[Stat.J_1KI.name] = (
(result[Stat.J.name] / result[Stat.ITERATIONS.name]) * 1000 (result[Stat.J.name] / result[Stat.ITERATIONS.name]) * 1000
@ -180,7 +211,7 @@ if args.power:
) )
if args.debug: if args.debug:
print(result) print(result, file=sys.stderr)
print(json.dumps(result)) print(json.dumps(result))
#if args.perf: #if args.perf:

View File

@ -1,4 +1,4 @@
from data_stat import Stat, Format from data_stat import Stat, Format, MatrixType
import torch, scipy import torch, scipy
import numpy as np import numpy as np
@ -8,28 +8,39 @@ import json
import sys, os import sys, os
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('iterations', type=int, help='the number of iterations of multiplication to perform') parser.add_argument('matrix_type', type=str,
choices=[t.name.lower() for t in MatrixType],
help='the type of matrix')
parser.add_argument('format', type=str, parser.add_argument('format', type=str,
choices=[fmt.name.lower() for fmt in Format], choices=[fmt.name.lower() for fmt in Format],
help='the sparse format to use') help='the sparse format to use')
parser.add_argument('-m', '--matrix_file', help='the input matrix (.mtx) file') parser.add_argument('iterations', type=int, help='the number of iterations of multiplication to perform')
parser.add_argument('-m', '--matrix_file', type=str,
help='the input matrix (.mtx) file')
parser.add_argument('-ss', '--synthetic_size', type=int, parser.add_argument('-ss', '--synthetic_size', type=int,
help='the synthetic matrix parameters size (rows)') help='the synthetic matrix parameters size (rows)')
parser.add_argument('-sd', '--synthetic_density', type=float, parser.add_argument('-sd', '--synthetic_density', type=float,
help='the synthetic matrix density (%)') help='the synthetic matrix density')
args = parser.parse_args() args = parser.parse_args()
args.matrix_type = MatrixType[args.matrix_type.upper()]
args.format = Format[args.format.upper()] args.format = Format[args.format.upper()]
device = 'cpu' device = 'cpu'
if args.matrix_file is not None: if args.matrix_type == MatrixType.SUITESPARSE:
if args.matrix_file is None:
exit("Matrix file not specified!")
matrix = scipy.io.mmread(args.matrix_file) matrix = scipy.io.mmread(args.matrix_file)
matrix = torch.sparse_coo_tensor( matrix = torch.sparse_coo_tensor(
np.vstack((matrix.row, matrix.col)), np.vstack((matrix.row, matrix.col)),
matrix.data, matrix.shape, matrix.data, matrix.shape,
device=device, dtype=torch.float32) device=device, dtype=torch.float32)
elif args.synthetic_size is not None and args.synthetic_density is not None: elif args.matrix_type == MatrixType.SYNTHETIC:
nnz = int((args.synthetic_size ** 2) * (args.synthetic_density / 100)) if args.synthetic_size is None and args.synthetic_density is None:
exit("Synthetic matrix parameters not specified!")
nnz = int((args.synthetic_size ** 2) * args.synthetic_density)
row_indices = torch.randint(0, args.synthetic_size, (nnz,)) row_indices = torch.randint(0, args.synthetic_size, (nnz,))
col_indices = torch.randint(0, args.synthetic_size, (nnz,)) col_indices = torch.randint(0, args.synthetic_size, (nnz,))
indices = torch.stack([row_indices, col_indices]) indices = torch.stack([row_indices, col_indices])
@ -40,16 +51,14 @@ elif args.synthetic_size is not None and args.synthetic_density is not None:
size=(args.synthetic_size, args.synthetic_size), size=(args.synthetic_size, args.synthetic_size),
device=device, dtype=torch.float32) device=device, dtype=torch.float32)
else: else:
print("No matrix specified!") exit("Unrecognized matrix type!")
exit(1)
if args.format == Format.CSR: if args.format == Format.CSR:
matrix = matrix.to_sparse_csr().type(torch.float32) matrix = matrix.to_sparse_csr().type(torch.float32)
elif args.format == Format.COO: elif args.format == Format.COO:
pass pass
else: else:
print("Unrecognized format!") exit("Unrecognized format!")
exit(1)
vector = torch.rand(matrix.shape[1], device=device) vector = torch.rand(matrix.shape[1], device=device)
@ -65,12 +74,16 @@ end = time.time()
result = dict() result = dict()
if args.matrix_file is not None: result[Stat.MATRIX_TYPE.name] = args.matrix_type.value
print(f"Matrix: {result[Stat.MATRIX_TYPE.name]}", file=sys.stderr)
if args.matrix_type == MatrixType.SUITESPARSE:
result[Stat.MATRIX_FILE.name] = os.path.splitext(os.path.basename(args.matrix_file))[0] result[Stat.MATRIX_FILE.name] = os.path.splitext(os.path.basename(args.matrix_file))[0]
else:
result[Stat.MATRIX_FILE.name] = "synthetic"
print(f"Matrix: {result[Stat.MATRIX_FILE.name]}", file=sys.stderr) print(f"Matrix: {result[Stat.MATRIX_FILE.name]}", file=sys.stderr)
result[Stat.MATRIX_FORMAT.name] = args.format.value
print(f"Matrix: {result[Stat.MATRIX_FORMAT.name]}", file=sys.stderr)
result[Stat.MATRIX_SHAPE.name] = matrix.shape result[Stat.MATRIX_SHAPE.name] = matrix.shape
print(f"Shape: {result[Stat.MATRIX_SHAPE.name]}", file=sys.stderr) print(f"Shape: {result[Stat.MATRIX_SHAPE.name]}", file=sys.stderr)