diff --git a/pytorch/batch.py b/pytorch/batch.py index 1bb69a6..0b0fd24 100644 --- a/pytorch/batch.py +++ b/pytorch/batch.py @@ -1,4 +1,4 @@ -from data_stat import Cpu, Format +from data_stat import Cpu, Format, MatrixType import argparse import glob @@ -9,7 +9,8 @@ import random parser = argparse.ArgumentParser() parser.add_argument('cpu', choices=[x.name.lower() for x in Cpu]) 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, choices=[fmt.name.lower() for fmt in Format]) 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_delay_s', type=int) #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('--distribute', action='store_true') args = parser.parse_args() args.cpu = Cpu[args.cpu.upper()] +args.matrix_type = MatrixType[args.matrix_type.upper()] args.format = Format[args.format.upper()] srun_args = { @@ -63,15 +68,28 @@ python = { 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 = [ args.cpu.name.lower(), - matrix_file, + args.matrix_type.name.lower(), args.format.name.lower(), str(args.base_iterations), str(args.min_time_s), str(args.baseline_time_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: # run_args_list += [args.perf] 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() -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.cpu == Cpu.ALTRA: # i = i % 40 @@ -97,12 +123,19 @@ for i, matrix in enumerate(glob.glob(f'{args.matrix_dir.rstrip("/")}/*.mtx')): #else: 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(), str(args.min_time_s), str(args.baseline_time_s), - str(args.baseline_delay_s), - os.path.splitext(os.path.basename(matrix))[0]]) + str(args.baseline_delay_s)] + 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' 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) if args.distribute: - processes.append(subprocess.Popen( - run(args, matrix, srun_args_temp), + processes.append(subprocess.Popen(run( + args, + parameter, + parameter[0], + parameter[1], + srun_args_temp), stdout=json_file, stderr=raw_file)) else: subprocess.run( - run(args, matrix), + run(args, parameter, parameter[0], parameter[1]), stdout=json_file, stderr=raw_file) diff --git a/pytorch/output_test2/altra_10_2_10_100000_0.0001.json b/pytorch/output_test2/altra_10_2_10_100000_0.0001.json new file mode 100644 index 0000000..b6820a1 --- /dev/null +++ b/pytorch/output_test2/altra_10_2_10_100000_0.0001.json @@ -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} diff --git a/pytorch/output_test2/altra_10_2_10_100000_0.0001.output b/pytorch/output_test2/altra_10_2_10_100000_0.0001.output new file mode 100644 index 0000000..d50cf42 --- /dev/null +++ b/pytorch/output_test2/altra_10_2_10_100000_0.0001.output @@ -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 + diff --git a/pytorch/output_test2/altra_10_2_10_100000_1e-05.json b/pytorch/output_test2/altra_10_2_10_100000_1e-05.json new file mode 100644 index 0000000..0a850b2 --- /dev/null +++ b/pytorch/output_test2/altra_10_2_10_100000_1e-05.json @@ -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} diff --git a/pytorch/output_test2/altra_10_2_10_100000_1e-05.output b/pytorch/output_test2/altra_10_2_10_100000_1e-05.output new file mode 100644 index 0000000..78b1d0c --- /dev/null +++ b/pytorch/output_test2/altra_10_2_10_100000_1e-05.output @@ -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 + diff --git a/pytorch/output_test2/epyc_7313p_10_2_10_100000_0.0001.json b/pytorch/output_test2/epyc_7313p_10_2_10_100000_0.0001.json new file mode 100644 index 0000000..24db3a4 --- /dev/null +++ b/pytorch/output_test2/epyc_7313p_10_2_10_100000_0.0001.json @@ -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} diff --git a/pytorch/output_test2/epyc_7313p_10_2_10_100000_0.0001.output b/pytorch/output_test2/epyc_7313p_10_2_10_100000_0.0001.output new file mode 100644 index 0000000..35074ce --- /dev/null +++ b/pytorch/output_test2/epyc_7313p_10_2_10_100000_0.0001.output @@ -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 + diff --git a/pytorch/output_test2/epyc_7313p_10_2_10_100000_1e-05.json b/pytorch/output_test2/epyc_7313p_10_2_10_100000_1e-05.json new file mode 100644 index 0000000..99ead94 --- /dev/null +++ b/pytorch/output_test2/epyc_7313p_10_2_10_100000_1e-05.json @@ -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} diff --git a/pytorch/output_test2/epyc_7313p_10_2_10_100000_1e-05.output b/pytorch/output_test2/epyc_7313p_10_2_10_100000_1e-05.output new file mode 100644 index 0000000..4d0c1da --- /dev/null +++ b/pytorch/output_test2/epyc_7313p_10_2_10_100000_1e-05.output @@ -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 + diff --git a/pytorch/output_test2/xeon_4216_10_2_10_100000_0.0001.json b/pytorch/output_test2/xeon_4216_10_2_10_100000_0.0001.json new file mode 100644 index 0000000..71fa75a --- /dev/null +++ b/pytorch/output_test2/xeon_4216_10_2_10_100000_0.0001.json @@ -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} diff --git a/pytorch/output_test2/xeon_4216_10_2_10_100000_0.0001.output b/pytorch/output_test2/xeon_4216_10_2_10_100000_0.0001.output new file mode 100644 index 0000000..ac2290e --- /dev/null +++ b/pytorch/output_test2/xeon_4216_10_2_10_100000_0.0001.output @@ -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 + diff --git a/pytorch/output_test2/xeon_4216_10_2_10_100000_1e-05.json b/pytorch/output_test2/xeon_4216_10_2_10_100000_1e-05.json new file mode 100644 index 0000000..4eb3a2c --- /dev/null +++ b/pytorch/output_test2/xeon_4216_10_2_10_100000_1e-05.json @@ -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} diff --git a/pytorch/output_test2/xeon_4216_10_2_10_100000_1e-05.output b/pytorch/output_test2/xeon_4216_10_2_10_100000_1e-05.output new file mode 100644 index 0000000..7fa6eba --- /dev/null +++ b/pytorch/output_test2/xeon_4216_10_2_10_100000_1e-05.output @@ -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 + diff --git a/pytorch/run.py b/pytorch/run.py index 29ff3eb..0fad805 100644 --- a/pytorch/run.py +++ b/pytorch/run.py @@ -1,5 +1,5 @@ import data_stat -from data_stat import Stat, Cpu, Format +from data_stat import Stat, Cpu, Format, MatrixType import argparse import os, sys @@ -9,7 +9,8 @@ import time parser = argparse.ArgumentParser() 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, choices=[fmt.name.lower() for fmt in Format]) 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_delay_s', type=int) #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('-d', '--debug', action='store_true') args = parser.parse_args() args.cpu = Cpu[args.cpu.upper()] +args.matrix_type = MatrixType[args.matrix_type.upper()] args.format = Format[args.format.upper()] +assert args.baseline_time_s >= 2 python = { Cpu.ALTRA: 'python3', @@ -38,21 +44,39 @@ perf_args = { ['-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: return [ 'apptainer', 'run', 'pytorch-altra.sif', '-c', - 'numactl --cpunodebind=0 --membind=0 ' - + f'python3 spmv.py {iterations} csr -m {matrix_file}'] + 'numactl --cpunodebind=0 --membind=0 ' + spmv] + #+ f'python3 spmv.py {matrix_type.name.lower()} ' + #+ f'csr {iterations} -m {matrix_file}'] elif cpu == Cpu.EPYC_7313P: - return [ - 'apptainer', 'run', 'pytorch-epyc_7313p.sif', - 'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}'] + return ['apptainer', 'run', 'pytorch-epyc_7313p.sif'] + spmv.split(' ') + #'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}'] elif cpu == Cpu.XEON_4216: return [ 'apptainer', 'run', 'pytorch-xeon_4216.sif', - 'numactl', '--cpunodebind=0', '--membind=0', - 'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}'] + 'numactl', '--cpunodebind=0', '--membind=0' + ] + spmv.split(' ') + #'python3', 'spmv.py', f'{iterations}', 'csr', '-m', f'{matrix_file}'] def baseline_power(cpu: Cpu, baseline_time_s: int) -> list: 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]: if args.debug: - print(program) + print(program, file=sys.stderr) process = subprocess.run(program, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) process.check_returncode() if args.debug: - print(process.stdout) - print(process.stderr) + print(process.stdout, file=sys.stderr) + print(process.stderr, file=sys.stderr) return (json.loads(process.stdout), process.stderr) 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 result = dict() -result[Stat.CPU.name] = args.cpu.name +result[Stat.CPU.name] = args.cpu.value 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: # 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) # Add another 5% for safety. iterations += iterations * 0.05 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 @@ -114,12 +142,15 @@ if args.power: time.sleep(args.baseline_delay_s) baseline_list = baseline_power(args.cpu, args.baseline_time_s) if args.debug: - print(baseline_list) + print(baseline_list, file=sys.stderr) assert(len(baseline_list) == args.baseline_time_s) # Power Collection 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) power_process.check_returncode() @@ -127,8 +158,8 @@ if args.power: for x in power_process.stdout.strip().split('\n')] power_time_s = json.loads(power_process.stderr)[Stat.TIME_S.name] if args.debug: - print(power_list) - print(power_time_s) + print(power_list, file=sys.stderr) + print(power_time_s, file=sys.stderr) if args.cpu == Cpu.ALTRA: # 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 if args.debug: - print(result) + print(result, file=sys.stderr) #print(len(result['power'])) #print(sum(result['power']) / len(result['power'])) @@ -148,7 +179,7 @@ if args.power: time.sleep(args.baseline_delay_s) baseline_list += baseline_power(args.cpu, args.baseline_time_s) if args.debug: - print(baseline_list) + print(baseline_list, file=sys.stderr) assert(len(baseline_list) / 2 == args.baseline_time_s) baseline_joules = ( @@ -161,8 +192,8 @@ if args.power: ) baseline_wattage = baseline_joules / (args.baseline_time_s * 2) if args.debug: - print(baseline_joules) - print(baseline_wattage) + print(baseline_joules, file=sys.stderr) + print(baseline_wattage, file=sys.stderr) result[Stat.J_1KI.name] = ( (result[Stat.J.name] / result[Stat.ITERATIONS.name]) * 1000 @@ -180,7 +211,7 @@ if args.power: ) if args.debug: - print(result) + print(result, file=sys.stderr) print(json.dumps(result)) #if args.perf: diff --git a/pytorch/spmv.py b/pytorch/spmv.py index 6afe600..7902d36 100644 --- a/pytorch/spmv.py +++ b/pytorch/spmv.py @@ -1,4 +1,4 @@ -from data_stat import Stat, Format +from data_stat import Stat, Format, MatrixType import torch, scipy import numpy as np @@ -8,28 +8,39 @@ import json import sys, os 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, choices=[fmt.name.lower() for fmt in Format], 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, help='the synthetic matrix parameters size (rows)') parser.add_argument('-sd', '--synthetic_density', type=float, - help='the synthetic matrix density (%)') + help='the synthetic matrix density') args = parser.parse_args() +args.matrix_type = MatrixType[args.matrix_type.upper()] args.format = Format[args.format.upper()] 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 = torch.sparse_coo_tensor( np.vstack((matrix.row, matrix.col)), matrix.data, matrix.shape, device=device, dtype=torch.float32) -elif args.synthetic_size is not None and args.synthetic_density is not None: - nnz = int((args.synthetic_size ** 2) * (args.synthetic_density / 100)) +elif args.matrix_type == MatrixType.SYNTHETIC: + 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,)) col_indices = torch.randint(0, args.synthetic_size, (nnz,)) 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), device=device, dtype=torch.float32) else: - print("No matrix specified!") - exit(1) + exit("Unrecognized matrix type!") if args.format == Format.CSR: matrix = matrix.to_sparse_csr().type(torch.float32) elif args.format == Format.COO: pass else: - print("Unrecognized format!") - exit(1) + exit("Unrecognized format!") vector = torch.rand(matrix.shape[1], device=device) @@ -65,11 +74,15 @@ end = time.time() 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] -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 print(f"Shape: {result[Stat.MATRIX_SHAPE.name]}", file=sys.stderr)