Files
[Quy Anh] «Elliot» Nguyen e7af3103e8 Perf plot
2026-06-18 11:59:50 +02:00

122 lines
3.2 KiB
Python

import csv
import importlib.util
import os
import re
import sys
sys.path.insert(0, 'flopcounts')
ROOT = 'measurements'
OUT = 'analysis/results_x86.csv'
size_line = re.compile(r'=== N_P=(\d+) N_ITER=(\d+) ===')
def num(pattern, text):
m = re.search(pattern, text)
if m:
return float(m.group(1))
return None
_flopcount_modules = {}
def get_flops_per_iter(variant, n_p, n_obs=2):
variant = variant.strip()
module_name = variant.replace('/', '_').replace('\\', '_')
module_path = f'flopcounts/x86/{module_name}'
if module_name in _flopcount_modules:
module = _flopcount_modules[module_name]
elif os.path.exists(f'{module_path}.py'):
try:
spec = importlib.util.spec_from_file_location(module_name,
f'{module_path}.py')
assert spec is not None
assert spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
_flopcount_modules[module_name] = module
except Exception as e:
print(f'Warning: Failed to load flopcount for {variant}: {e}')
return None
else:
print(f'Warning: No flopcount module found for {variant}')
return None
if hasattr(module, 'total'):
try:
return module.total(n_iter=1, n_p=int(n_p), n_obs=int(n_obs))
except Exception as e:
print(f'Warning: Error calling total() for {variant}: {e}')
return None
else:
print(f'Warning: No total() function in {module_path}')
return None
runs = {}
for variant in sorted(os.listdir(ROOT)):
logdir = os.path.join(ROOT, variant, 'x86')
if not os.path.isdir(logdir):
continue
for fn in os.listdir(logdir):
if not fn.endswith('.log'):
continue
text = open(os.path.join(logdir, fn)).read()
marks = list(size_line.finditer(text))
for i, m in enumerate(marks):
n = int(m.group(1))
n_iter = int(m.group(2))
start = m.end()
stop = marks[i + 1].start() if i + 1 < len(marks) else len(text)
block = text[start:stop]
cycles = num(r'T\(n\):\s*([\d.]+)', block)
if cycles is None:
continue
key = (variant, n)
q = num(r'Q\(n\) per iteration:\s*([\d.]+)', block)
if key not in runs:
runs[key] = []
runs[key].append((cycles, n_iter, q))
with open(OUT, 'w', newline='') as f:
w = csv.writer(f)
w.writerow([
'variant', 'n', 'n_iter', 'W', 'Q_per_iter', 'I', 'cycles',
'flops_per_cycle'
])
for variant, n in sorted(runs):
entries = runs[(variant, n)]
n_iter = entries[0][1]
q = entries[0][2]
for _, ni, qi in entries:
if ni != n_iter:
print(f'Warning: n_iter mismatch for {(variant, n)}: {ni} vs {n_iter}')
if qi != q:
print(f'Warning: Q_per_iter mismatch for {(variant, n)}: {qi} vs {q}')
cycles = sum(e[0] for e in entries) / len(entries)
w_iter = get_flops_per_iter(variant, n)
assert w_iter is not None
W = w_iter * n_iter
I = w_iter / q if q else w_iter
fc = W / cycles if cycles else 0
w.writerow(
[variant, n, n_iter, W, q,
round(I, 2),
round(cycles, 1),
round(fc, 3)])
print('wrote', OUT, 'with', len(runs), 'rows')