ampere_research/pytorch/run.py

160 lines
5.6 KiB
Python
Raw Normal View History

2024-12-04 22:47:16 -05:00
import data_stat
from data_stat import Stat, Cpu
2024-12-02 23:32:33 -05:00
import argparse
import os, sys
import subprocess, signal
import json
2024-12-04 22:47:16 -05:00
import time
2024-12-02 23:32:33 -05:00
parser = argparse.ArgumentParser()
2024-12-04 22:47:16 -05:00
parser.add_argument('cpu', choices=[x.name.lower() for x in Cpu])
2024-12-02 23:32:33 -05:00
parser.add_argument('matrix_file')
parser.add_argument('iterations', 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('--power', action='store_true')
parser.add_argument('-d', '--debug', action='store_true')
args = parser.parse_args()
2024-12-04 22:47:16 -05:00
args.cpu = Cpu[args.cpu.upper()]
2024-12-09 10:57:15 -05:00
python = {
Cpu.ALTRA: 'python3',
Cpu.EPYC_7313P: 'python3.11'
}
2024-12-04 22:47:16 -05:00
program = {
Cpu.ALTRA: [
'apptainer', 'run', 'pytorch-altra.sif', '-c',
'numactl --cpunodebind=0 --membind=0 '
2024-12-09 10:57:15 -05:00
+ f'python spmv.py {args.matrix_file} {args.iterations}'],
Cpu.EPYC_7313P: [
'apptainer', 'run', 'pytorch-epyc_7313p.sif',
'python3', 'spmv.py', f'{args.matrix_file}', f'{args.iterations}']
2024-12-04 22:47:16 -05:00
}
2024-12-02 23:32:33 -05:00
perf = ['perf', 'stat']
2024-12-04 22:47:16 -05:00
perf_args = {
Cpu.ALTRA: [
['-d', '-d'],
['-M', 'branch_misprediction_ratio'],
['-M', 'dtlb_walk_ratio,itlb_walk_ratio'],
['-M', 'l1d_cache_miss_ratio,l1i_cache_miss_ratio'],
['-M', 'l2_cache_miss_ratio,l2_tlb_miss_ratio,ll_cache_read_miss_ratio']]
}
2024-12-02 23:32:33 -05:00
2024-12-09 10:57:15 -05:00
def baseline_power(cpu: Cpu, baseline_time_s: int) -> list:
power_process = subprocess.Popen([python[args.cpu], 'power.py', '-s', str(baseline_time_s)],
2024-12-02 23:32:33 -05:00
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)
2024-12-09 10:57:15 -05:00
return [float(x) for x in power_process.communicate()[0].strip().split('\n') if len(x) != 0]
2024-12-02 23:32:33 -05:00
def run_program(program: list[str]) -> tuple[dict, str]:
2024-12-09 10:57:15 -05:00
if args.debug:
print(program)
2024-12-02 23:32:33 -05:00
process = subprocess.run(program,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
2024-12-04 22:47:16 -05:00
if args.debug:
print(process.stdout)
print(process.stderr)
2024-12-02 23:32:33 -05:00
return (json.loads(process.stdout), process.stderr)
2024-12-11 15:00:37 -05:00
def trapezoidal_rule(power: list[float], time_s: float) -> float:
from math import ceil
from itertools import pairwise
result = 0.0
relevant_power = power[-int(time_s):]
relevant_pairs = [pair for pair in zip(relevant_power, relevant_power[1:])]
for pair in relevant_pairs:
result += 0.5 * (pair[0] + pair[1])
result += (time_s % 1) * (power[-1])
return result
2024-12-02 23:32:33 -05:00
result = dict()
2024-12-05 14:49:05 -05:00
result[Stat.CPU.name] = args.cpu.name
result[Stat.ITERATIONS.name] = args.iterations
2024-12-09 10:57:15 -05:00
program_result = run_program(program[args.cpu])
result |= program_result[0]
print(program_result[1], file=sys.stderr)
2024-12-02 23:32:33 -05:00
2024-12-11 14:43:23 -05:00
result[Stat.TIME_S.name] = result[Stat.TIME_S_OVERALL.name] / result[Stat.ITERATIONS.name]
2024-12-04 22:47:16 -05:00
if args.power:
2024-12-09 10:57:15 -05:00
result[Stat.BASELINE_TIME_S.name] = args.baseline_time_s
result[Stat.BASELINE_DELAY_S.name] = args.baseline_delay_s
2024-12-04 22:47:16 -05:00
time.sleep(args.baseline_delay_s)
2024-12-09 10:57:15 -05:00
result[Stat.POWER_BEFORE.name] = baseline_power(args.cpu, args.baseline_time_s)
2024-12-02 23:32:33 -05:00
if args.debug:
print(result)
2024-12-04 22:47:16 -05:00
run_program(program[args.cpu]) # Warmup
2024-12-02 23:32:33 -05:00
2024-12-09 10:57:15 -05:00
if args.cpu == Cpu.ALTRA:
power_process = subprocess.Popen(
[python[args.cpu], 'power.py'],
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)
2024-12-02 23:32:33 -05:00
2024-12-09 10:57:15 -05:00
run_program(program[args.cpu])[0]
power_process.send_signal(signal.SIGINT)
if args.debug:
print(result)
result[Stat.POWER.name] = [float(x) for x in power_process.communicate()[0].strip().split('\n')]
2024-12-11 15:00:37 -05:00
# Trapezoidal Rule across the last (s) power recordings.
#result[Stat.JOULES.name] = (
# sum(result[Stat.POWER.name][-ceil(result[Stat.TIME_S.name]):])
# + (result[Stat.POWER.name][-1] * (result[Stat.TIME_S.name] % 1)))
result[Stat.JOULES.name] = trapezoidal_rule(
result[Stat.POWER.name],
result[Stat.TIME_S.name])
2024-12-09 10:57:15 -05:00
elif args.cpu == Cpu.EPYC_7313P:
power_process = subprocess.Popen(
[python[args.cpu], 'power.py'] + program[args.cpu],
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)
result[Stat.POWER.name] = [float(x) for x in power_process.communicate()[0].strip().split('\n')]
2024-12-11 14:43:23 -05:00
result[Stat.JOULES.name] = result[Stat.POWER.name][0] * result[Stat.TIME_S_OVERALL.name]
2024-12-02 23:32:33 -05:00
if args.debug:
print(result)
#print(len(result['power']))
#print(sum(result['power']) / len(result['power']))
time.sleep(args.baseline_delay_s)
2024-12-09 10:57:15 -05:00
result[Stat.POWER_AFTER.name] = baseline_power(args.cpu, args.baseline_time_s)
2024-12-02 23:32:33 -05:00
if args.debug:
print(result)
2024-12-04 22:47:16 -05:00
if args.perf:
for perf_arg in perf_args[args.cpu]:
output = run_program(perf + perf_arg + program[args.cpu])[1]
print(output, file=sys.stderr)
result = result | data_stat.parse_output(output, args.cpu)
if args.debug:
print(result)
result = result | data_stat.derive_stats(result)
2024-12-02 23:32:33 -05:00
if args.debug:
print(result)
print(json.dumps(result))
#arch = subprocess.run(['uname', '-m'], stdout=subprocess.PIPE, text=True).stdout.strip()
#baseline = subprocess.run(
# ['./power.sh', args.baseline_time_s],
# stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
#print(baseline)
#for line in baseline.stdout.split('\n'):
# print("line")
# print(line)
#os.path.basename(args.matrix_file)
#subprocess.run(
# ['apptainer', 'run', 'pytorch-altra.sif', '-c',
# f'"numactl --cpunodebind=0 --membind=0 python spmv.py {args.matrix_file} {args.iterations}"'
# ],
# stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)