added dynamic iteration adjustment

This commit is contained in:
cephi 2024-12-11 23:06:43 -05:00
parent cf86de6ea4
commit 6bf301e9b7

View File

@ -10,7 +10,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_file')
parser.add_argument('iterations', type=int) 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_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')
@ -24,19 +25,6 @@ python = {
Cpu.EPYC_7313P: 'python3.11', Cpu.EPYC_7313P: 'python3.11',
Cpu.XEON_4216: 'python3.11' Cpu.XEON_4216: 'python3.11'
} }
#program = {
# Cpu.ALTRA: [
# 'apptainer', 'run', 'pytorch-altra.sif', '-c',
# 'numactl --cpunodebind=0 --membind=0 '
# + f'python3 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}'],
# Cpu.XEON_4216: [
# 'apptainer', 'run', 'pytorch-altra.sif', '-c',
# 'numactl --cpunodebind=0 --membind=0 '
# + f'python3 spmv.py {args.matrix_file} {args.iterations}']
#}
perf = ['perf', 'stat'] perf = ['perf', 'stat']
perf_args = { perf_args = {
Cpu.ALTRA: [ Cpu.ALTRA: [
@ -95,9 +83,19 @@ def trapezoidal_rule(power: list[float], time_s: float) -> float:
result = dict() result = dict()
result[Stat.CPU.name] = args.cpu.name result[Stat.CPU.name] = args.cpu.name
result[Stat.ITERATIONS.name] = args.iterations
program_result = run_program(program(args.cpu, args.matrix_file, args.iterations)) 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)
# Add another 5% for safety.
iterations += iterations * 0.05
iterations = int(iterations)
program_result = run_program(program(args.cpu, args.matrix_file, iterations))
result[Stat.ITERATIONS.name] = iterations
result |= program_result[0] result |= program_result[0]
print(program_result[1], file=sys.stderr) print(program_result[1], file=sys.stderr)
@ -111,7 +109,6 @@ if args.power:
# Baseline # Baseline
time.sleep(args.baseline_delay_s) time.sleep(args.baseline_delay_s)
#result[Stat.POWER_BEFORE.name] = baseline_power(args.cpu, args.baseline_time_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)
@ -119,27 +116,25 @@ if args.power:
# Power Collection # Power Collection
power_process = subprocess.run( power_process = subprocess.run(
['./power.sh', '-1'] + program(args.cpu, args.matrix_file, args.iterations), ['./power.sh', '-1'] + program(args.cpu, args.matrix_file, result[Stat.ITERATIONS.name]),
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
power_process.check_returncode() power_process.check_returncode()
#result[Stat.POWER.name] = [float(x) for x in power_process.communicate()[0].strip().split('\n')]
power_list = [float(x) power_list = [float(x)
#for x in power_process.communicate()[0].strip().split('\n')]
for x in power_process.stdout.strip().split('\n')] for x in power_process.stdout.strip().split('\n')]
power_process_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)
print(power_process_time_s) print(power_time_s)
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.
result[Stat.J.name] = trapezoidal_rule( result[Stat.J.name] = trapezoidal_rule(
power_list, power_process_time_s) power_list, power_time_s)
elif args.cpu == Cpu.EPYC_7313P or args.cpu == Cpu.XEON_4216: elif args.cpu == Cpu.EPYC_7313P or args.cpu == Cpu.XEON_4216:
result[Stat.J.name] = power_list[0] * power_process_time_s result[Stat.J.name] = power_list[0] * power_time_s
result[Stat.W.name] = result[Stat.J.name] / power_process_time_s result[Stat.W.name] = result[Stat.J.name] / power_time_s
if args.debug: if args.debug:
print(result) print(result)
@ -148,7 +143,6 @@ if args.power:
# Baseline # Baseline
time.sleep(args.baseline_delay_s) time.sleep(args.baseline_delay_s)
#result[Stat.POWER_AFTER.name] = baseline_power(args.cpu, args.baseline_time_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)
@ -171,7 +165,7 @@ if args.power:
(result[Stat.W.name] / result[Stat.ITERATIONS.name]) * 1000 (result[Stat.W.name] / result[Stat.ITERATIONS.name]) * 1000
) )
result[Stat.W_D.name] = result[Stat.W.name] - baseline_wattage result[Stat.W_D.name] = result[Stat.W.name] - baseline_wattage
result[Stat.J_D.name] = result[Stat.W_D.name] * power_process_time_s result[Stat.J_D.name] = result[Stat.W_D.name] * power_time_s
result[Stat.W_D_1KI.name] = ( result[Stat.W_D_1KI.name] = (
(result[Stat.W_D.name] / result[Stat.ITERATIONS.name]) * 1000 (result[Stat.W_D.name] / result[Stat.ITERATIONS.name]) * 1000
) )