Added partial support for synthetic matrices

This commit is contained in:
cephi 2024-12-12 01:18:26 -05:00
parent 6bf301e9b7
commit 66b0699fa8
4 changed files with 79 additions and 21 deletions

View File

@ -16,7 +16,7 @@ class Stat(Enum):
MATRIX_SHAPE = 'matrix shape'
MATRIX_SIZE = 'matrix size'
MATRIX_NNZ = 'matrix nnz'
MATRIX_DENSITY = 'matrix density %'
MATRIX_DENSITY = 'matrix density'
#POWER_BEFORE = 'power before'
#POWER = 'power'
@ -65,6 +65,10 @@ class Stat(Enum):
L2D_CACHE_MISS_RATE = 'L2D cache miss rate'
LL_CACHE_MISS_RATE = 'LL cache miss rate'
class Format(Enum):
CSR = 'csr'
COO = 'coo'
class Cpu(Enum):
#ALTRA = altra_names
#XEON = xeon_names

View File

@ -1,4 +1,4 @@
from data_stat import Cpu
from data_stat import Cpu, Format
import argparse
import glob
@ -10,7 +10,10 @@ 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('iterations', type=int)
parser.add_argument('format', type=str,
choices=[fmt.name.lower() for fmt in Format])
parser.add_argument('base_iterations', type=int)
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')
@ -18,6 +21,7 @@ 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.format = Format[args.format.upper()]
srun_args = {
Cpu.ALTRA: [
@ -40,18 +44,29 @@ srun_args = {
'--cpus-per-task', '16',
'--ntasks-per-node', '1',
'--prefer', 'EPYC-7313P'
],
Cpu.XEON_4216: [
'--account', 'nexus',
'--partition', 'tron',
'--qos', 'tron-exempt',
'--cpus-per-task', '32',
'--ntasks-per-node', '1',
'--prefer', 'Xeon,4216'
]
}
python = {
Cpu.ALTRA: 'python3',
Cpu.EPYC_7313P: 'python3.11'
Cpu.EPYC_7313P: 'python3.11',
Cpu.XEON_4216: 'python3.11'
}
def srun(srun_args_list: list, run_args, matrix_file: str) -> list:
run_args_list = [
args.cpu.name.lower(),
matrix_file,
str(args.iterations),
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.perf is not None:
@ -74,10 +89,10 @@ for i, matrix in enumerate(glob.glob(f'{args.matrix_dir.rstrip("/")}/*.mtx')):
output_filename = '_'.join([
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.iterations)])
os.path.splitext(os.path.basename(matrix))[0]])
json_filepath = f'{args.output_dir.rstrip("/")}/{output_filename}.json'
raw_filepath = f'{args.output_dir.rstrip("/")}/{output_filename}.output'

View File

@ -1,5 +1,5 @@
import data_stat
from data_stat import Stat, Cpu
from data_stat import Stat, Cpu, Format
import argparse
import os, sys
@ -10,6 +10,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('format', type=str,
choices=[fmt.name.lower() for fmt in Format])
parser.add_argument('base_iterations', type=int)
parser.add_argument('min_time_s', type=int)
parser.add_argument('baseline_time_s', type=int)
@ -19,6 +21,7 @@ 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.format = Format[args.format.upper()]
python = {
Cpu.ALTRA: 'python3',
@ -40,16 +43,16 @@ def program(cpu: Cpu, matrix_file: str, iterations: int) -> list:
return [
'apptainer', 'run', 'pytorch-altra.sif', '-c',
'numactl --cpunodebind=0 --membind=0 '
+ f'python3 spmv.py {matrix_file} {iterations}']
+ f'python3 spmv.py {iterations} csr -m {matrix_file}']
elif cpu == Cpu.EPYC_7313P:
return [
'apptainer', 'run', 'pytorch-epyc_7313p.sif',
'python3', 'spmv.py', f'{matrix_file}', f'{iterations}']
'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'{matrix_file}', f'{iterations}']
'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)],
@ -88,7 +91,7 @@ iterations = args.base_iterations
program_result = run_program(program(args.cpu, args.matrix_file, iterations))
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 / ((args.min_time_s - 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.
iterations += iterations * 0.05
iterations = int(iterations)
@ -157,6 +160,9 @@ if args.power:
args.baseline_time_s)
)
baseline_wattage = baseline_joules / (args.baseline_time_s * 2)
if args.debug:
print(baseline_joules)
print(baseline_wattage)
result[Stat.J_1KI.name] = (
(result[Stat.J.name] / result[Stat.ITERATIONS.name]) * 1000

View File

@ -1,4 +1,4 @@
from data_stat import Stat
from data_stat import Stat, Format
import torch, scipy
import numpy as np
@ -8,18 +8,48 @@ import json
import sys, os
parser = argparse.ArgumentParser()
parser.add_argument('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('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('-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 (%)')
args = parser.parse_args()
args.format = Format[args.format.upper()]
device = 'cpu'
if args.matrix_file is not None:
matrix = scipy.io.mmread(args.matrix_file)
matrix = torch.sparse_coo_tensor(
np.vstack((matrix.row, matrix.col)),
matrix.data, matrix.shape,
device=device
).to_sparse_csr().type(torch.float)
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))
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])
values = torch.randn(nnz)
matrix = torch.sparse_coo_tensor(
indices, values,
size=(args.synthetic_size, args.synthetic_size),
device=device, dtype=torch.float32)
else:
print("No matrix specified!")
exit(1)
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)
vector = torch.rand(matrix.shape[1], device=device)
@ -35,7 +65,10 @@ end = time.time()
result = dict()
if args.matrix_file is not None:
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)
result[Stat.MATRIX_SHAPE.name] = matrix.shape