From 14fbb1499be15165bb0dd1565941974809f207eb Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Fri, 5 Mar 2021 18:29:43 +0100 Subject: [PATCH] ds: add perf stat parser We can only read one output file by now, located at: .garlic/perf.csv --- garlic/ds/index.nix | 2 ++ garlic/ds/perf/stat.nix | 23 +++++++++++++ garlic/ds/perf/stat.py | 71 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 garlic/ds/perf/stat.nix create mode 100644 garlic/ds/perf/stat.py diff --git a/garlic/ds/index.nix b/garlic/ds/index.nix index c3c0454..1c2c28e 100644 --- a/garlic/ds/index.nix +++ b/garlic/ds/index.nix @@ -15,4 +15,6 @@ latency = callPackage ./osu/latency.nix {}; bw = callPackage ./osu/bw.nix {}; }; + + perf.stat = callPackage ./perf/stat.nix {}; } diff --git a/garlic/ds/perf/stat.nix b/garlic/ds/perf/stat.nix new file mode 100644 index 0000000..14b55c4 --- /dev/null +++ b/garlic/ds/perf/stat.nix @@ -0,0 +1,23 @@ +{ + stdenv +, python3 +, gzip +}: + +resultTree: + +stdenv.mkDerivation { + name = "perf-stat.json.gz"; + preferLocalBuild = true; + src = ./stat.py; + phases = [ "unpackPhase" "installPhase" ]; + + unpackPhase = '' + cp $src stat.py + ''; + + buildInputs = [ python3 gzip ]; + installPhase = '' + python stat.py ${resultTree} | gzip > $out + ''; +} diff --git a/garlic/ds/perf/stat.py b/garlic/ds/perf/stat.py new file mode 100644 index 0000000..ac180fe --- /dev/null +++ b/garlic/ds/perf/stat.py @@ -0,0 +1,71 @@ +import json, re, sys, os, glob +from os import path + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, flush=True, **kwargs) + +def process_run(tree, runPath): + with open(".garlic/perf.csv", "r") as f: + lines = [line.strip() for line in f.readlines()] + + perf_data = {} + + for line in lines: + if len(line) == 0: continue + if line[0] == '#': continue + + slices = line.split(',') + if len(slices) != 7: + print("error: mismatched columns") + exit(1) + + name = slices[2].replace("-", "_") + value = float(slices[0]) + + perf_data[name] = value + + tree['perf'] = perf_data + + print(json.dumps(tree)) + +def process_result_tree(resultTree): + + eprint("processing resultTree: " + resultTree) + + os.chdir(resultTree) + + experiments = glob.glob(resultTree + "/*-experiment") + + for exp in glob.glob("*-experiment"): + eprint("found experiment: " + exp) + expPath = path.join(resultTree, exp) + os.chdir(expPath) + + for unit in glob.glob("*-unit"): + eprint("found unit: " + unit) + unitPath = path.join(resultTree, exp, unit) + os.chdir(unitPath) + + with open('garlic_config.json') as json_file: + garlic_conf = json.load(json_file) + + tree = {"exp":exp, "unit":unit, "config":garlic_conf} + + for i in range(garlic_conf['loops']): + run = str(i + 1) + runPath = path.join(resultTree, exp, unit, run) + if path.isdir(runPath) == False: + eprint("missing run {}, aborting".format(run)) + exit(1) + + tree["run"] = run + os.chdir(runPath) + + process_run(tree, runPath) + + +if len(sys.argv) != 2: + eprint("usage: python {} ".format(argv[0])) + exit(1) + +process_result_tree(sys.argv[1])