From 5eff8265450afa0682caa0b60720e0a5b4ba8cbe Mon Sep 17 00:00:00 2001 From: Akash Dhiraj Date: Tue, 24 Sep 2024 19:42:27 -0400 Subject: [PATCH] Make cycle.sh and resources.sh generate JSONs --- frontends/queues/cycles.sh | 20 +++- frontends/queues/plot.py | 177 +++++++++++++++++----------------- frontends/queues/resources.sh | 23 ++++- 3 files changed, 124 insertions(+), 96 deletions(-) diff --git a/frontends/queues/cycles.sh b/frontends/queues/cycles.sh index c35b0b161..63d362947 100755 --- a/frontends/queues/cycles.sh +++ b/frontends/queues/cycles.sh @@ -4,7 +4,13 @@ shopt -s globstar cd "$(dirname "$0")/../.." # move to root -for file in frontends/queues/tests/**/*.py; do +declare -a files=(frontends/queues/tests/**/*.py) +num_files=${#files[@]} + +echo "{" + +for (( i=0; i<${num_files}; i++ )); do + file="${files[$i]}" name="$(basename $file .py)" dir="$(dirname $file)" @@ -15,5 +21,15 @@ for file in frontends/queues/tests/**/*.py; do -s verilog.data "$dir/$name.data" \ -s jq.expr ".cycles" \ -q)" - echo "${file#*tests/}: $cycles" + + echo -n "\"${file#*tests/}\" : $cycles" + + # because JSON doesn't allow trailing ','s + if [ $i -ne $(( num_files - 1 )) ]; then + echo "," + else + echo "" + fi done + +echo "}" diff --git a/frontends/queues/plot.py b/frontends/queues/plot.py index 19b3bd7dc..b3ea21225 100644 --- a/frontends/queues/plot.py +++ b/frontends/queues/plot.py @@ -1,10 +1,13 @@ import os import sys import json -import numpy as np +from enum import Enum import matplotlib.pyplot as plt -stat = sys.argv[1] + +class Logic(Enum): + RR = 1 + STRICT = 2 def append_path_prefix(file): path_to_script = os.path.dirname(__file__) @@ -12,111 +15,105 @@ def append_path_prefix(file): return path_to_file def parse(stat, file): - binheap_rr = [] - specialized_rr = [] - binheap_strict = [] - specialized_strict = [] + out = { + "binheap" : { + "round_robin" : {}, + "strict" : {} + }, + "specialized" : { + "round_robin" : {}, + "strict" : {} + } + } with open(file) as file: - if stat == "cycles": - for line in file: - split = line.strip().split(":") - tup = (split[0].split("flow")[0][-1], int(split[1])) - if "round_robin" in line: - if "binheap" in line: - binheap_rr.append(tup) - else: - specialized_rr.append(tup) - if "strict" in line: - if "binheap" in line: - binheap_strict.append(tup) - else: - specialized_strict.append(tup) - else: - data = file.read().strip() - for d in data.split("\n\n"): - split = d.split("\n") - name = split[0] - stats = json.loads("\n".join(split[1:])) - tup = (name.split("flow")[0][-1], stats[stat]) - if "round_robin" in name: - if "binheap" in name: - binheap_rr.append(tup) - else: - specialized_rr.append(tup) - if "strict" in name: - if "binheap" in name: - binheap_strict.append(tup) - else: - specialized_strict.append(tup) - - return (specialized_rr, - binheap_rr, - specialized_strict, - binheap_strict) - -def draw(specialized, binheap, name, filename, details=None): + data = json.load(file) + for file, data in data.items(): + if isinstance(data, dict): + data = data[stat] + + flow_no = file.split('flow')[0][-1] + + if "round_robin" in file: + if "binheap" in file: + out["binheap"]["round_robin"][flow_no] = data + else: + out["specialized"]["round_robin"][flow_no] = data + if "strict" in file: + if "binheap" in file: + out["binheap"]["strict"][flow_no] = data + else: + out["specialized"]["strict"][flow_no] = data + + return out + +def draw(data, stat, logic, unit): fig, ax = plt.subplots(1, 1) fig.set_size_inches(20, 10, forward=True) - ax.set_title(name, - fontweight='bold', - fontsize=20) - ax.set_xlabel("number of flows", - fontsize=20) - if details is None: - ax.set_ylabel(stat, - fontsize=20) + ax.set_xlabel("number of flows", fontsize=20) + if unit is None: + ax.set_ylabel(stat, fontsize=20) else: - ax.set_ylabel(f"{stat} ({details})", - fontsize=20) - specialized = ax.scatter( - list(map(lambda x: x[0], specialized)), - list(map(lambda x: x[1], specialized)), - c='b') - binheap = ax.scatter( - list(map(lambda x: x[0], binheap)), - list(map(lambda x: x[1], binheap)), - c='g') + ax.set_ylabel(f"{stat} ({unit})", fontsize=20) + + file = "" + + if logic == Logic.RR: + specialized = ax.scatter( + data["specialized"]["round_robin"].keys(), + data["specialized"]["round_robin"].values(), + c='b') + binheap = ax.scatter( + data["binheap"]["round_robin"].keys(), + data["binheap"]["round_robin"].values(), + c='g') + + ax.set_title("Round Robin Queues", fontweight='bold', fontsize=20) + file = append_path_prefix(f"{stat}_round_robin") + + elif logic == Logic.STRICT: + specialized = ax.scatter( + data["specialized"]["strict"].keys(), + data["specialized"]["strict"].values(), + c='b') + binheap = ax.scatter( + data["binheap"]["strict"].keys(), + data["binheap"]["strict"].values(), + c='g') + + ax.set_title("Strict Queues", fontweight='bold', fontsize=20) + file = append_path_prefix(f"{stat}_strict") + plt.legend((specialized, binheap), - ("Specialized (i.e. Cassandra style PIFO)", "Binary Heap"), + ("Specialized (i.e. Cassandra style)", "Binary Heap"), fontsize=12) - file = append_path_prefix(f"{stat}_{filename}") + plt.savefig(file) + print(f"Generated {file}.png") # Parse data for round_robin and strict queues -(specialized_rr, binheap_rr, specialized_strict, binheap_strict) = ([], [], [], []) +stat = sys.argv[1] +data = {} if stat == "total_time": file1 = sys.argv[2] file2 = sys.argv[3] - (specialized_cycles_rr, - binheap_cycles_rr, - specialized_cycles_strict, - binheap_cycles_strict) = parse("cycles", file1) - (specialized_slacks_rr, - binheap_slacks_rr, - specialized_slacks_strict, - binheap_slacks_strict) = parse("worst_slack", file2) - - def map2(cycles, slacks): - cycles.sort(key=lambda c: c[0]) - slacks.sort(key=lambda s: s[0]) - - def f(c,s): - return (c[0], (1000*c[1])/(7 - s[1])) - - return list(map(f, cycles, slacks)) + cycle_data = parse("cycles", file1) + slack_data = parse("worst_slack", file2) - specialized_rr = map2(specialized_cycles_rr, specialized_slacks_rr) - binheap_rr = map2(binheap_cycles_rr, binheap_slacks_rr) - specialized_strict = map2(specialized_cycles_strict, specialized_slacks_strict) - binheap_strict = map2(binheap_cycles_strict, binheap_slacks_strict) + data = cycle_data.copy() + for impl in data.keys(): + for logic in data[impl].keys(): + for flow_no in data[impl][logic].keys(): + cycles = cycle_data[impl][logic][flow_no] + slack = slack_data[impl][logic][flow_no] + data[impl][logic][flow_no] = (1000 * cycles) / (7 - slack) else: file = sys.argv[2] - (specialized_rr, binheap_rr, specialized_strict, binheap_strict) = parse(stat, file) + data = parse(stat, file) # Draw results -details = "μs" if stat == "total_time" else None -draw(specialized_rr, binheap_rr, "Round Robin Queues", "round_robin", details) -draw(specialized_strict, binheap_strict, "Strict Queues", "strict", details) +unit = "μs" if stat == "total_time" else None +draw(data, stat, Logic.RR, unit) +draw(data, stat, Logic.STRICT, unit) diff --git a/frontends/queues/resources.sh b/frontends/queues/resources.sh index 66659c2fd..c79dc08fa 100755 --- a/frontends/queues/resources.sh +++ b/frontends/queues/resources.sh @@ -9,7 +9,13 @@ fi cd "$(dirname "$0")/../.." # move to root -for file in frontends/queues/tests/**/*.py; do +declare -a files=(frontends/queues/tests/**/*.py) +num_files=${#files[@]} + +echo "{" + +for (( i=0; i<${num_files}; i++ )); do + file="${files[$i]}" name="$(basename $file .py)" dir="$(dirname $file)" @@ -18,9 +24,18 @@ for file in frontends/queues/tests/**/*.py; do if [ "$#" -eq 1 ]; then resource=$(jq ".$1" <<< "$resources") - echo "${file#*tests/}: $resource" + echo -n "\"${file#*tests/}\" : $resource" + else + echo "\"${file#*tests/}\" :" + echo -n "$resources" + fi + + # because JSON doesn't allow trailing ','s + if [ $i -ne $(( num_files - 1 )) ]; then + echo "," else - newline=$'\n' - echo "${file#*tests/}${newline}$resources${newline}" + echo "" fi done + +echo "}"