Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uniform results data #103

Merged
merged 8 commits into from
May 14, 2020
126 changes: 126 additions & 0 deletions dataframe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
acomodi marked this conversation as resolved.
Show resolved Hide resolved
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 The SymbiFlow Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC

import pandas


def get_clock_dataframe(results):
designs = []

# Clock-related lists
actual_frequency = []
requested_frequency = []
hold_violation = []
setup_violation = []
clock_met = []
clock_names = []

for idx, design in enumerate(results['design']):
clock = results['max_freq'][idx]
if clock:
for key, value in clock.items():
designs.append(design)
clock_names.append(key)
actual_frequency.append(value['actual'] / 1e6)
requested_frequency.append(value['requested'] / 1e6)
hold_violation.append(value['hold_violation'])
setup_violation.append(value['setup_violation'])
clock_met.append(value['met'])
else:
designs.append(design)
clock_names.append(None)
actual_frequency.append(None)
requested_frequency.append(None)
hold_violation.append(None)
setup_violation.append(None)
clock_met.append(None)

index = pandas.Index(designs)
return pandas.DataFrame(
{
'clocks': clock_names,
'clock_actual_frequency': actual_frequency,
'clock_requested_frequency': requested_frequency,
'clock_hold_violation': hold_violation,
'clock_setup_violation': setup_violation,
'clock_met': clock_met,
},
index=index
)


def get_general_dataframe(results):
designs = results['design']

# Get runtimes
runtimes = dict()
for runtime in results['runtime']:
if not runtimes:
runtimes = {k: [] for k in runtime.keys()}

for k, v in runtime.items():
runtimes[k].append(v)

runtimes_keys = list(runtimes.keys())
for key in runtimes_keys:
runtimes["{}_time".format(key)] = runtimes.pop(key)

# Get resources
resources = dict()
for resource in results['resources']:
if not resources:
resources = {k: [] for k in resource.keys()}

for k, v in resource.items():
resources[k].append(v)

resources_keys = list(resources.keys())
for key in resources_keys:
resources["#{}".format(key)] = resources.pop(key)

# Get versions
tools = dict()
# Initialize versions dictionary with all possible
# versions of the tools.
for version in results['versions']:
for key in version:
tools[key] = []

for version in results['versions']:
for k, v in version.items():
tools[k].append(v)

for k in version.keys() ^ tools.keys():
tools[k].append(None)

tools_keys = list(tools.keys())
for key in tools_keys:
tools["{}_version".format(key)] = tools.pop(key)

ALREADY_PARSED_KEYS = ['versions', 'max_freq', 'runtime', 'resources']
general_data = {
k: results[k]
for k in results.keys() ^ ALREADY_PARSED_KEYS
}

data = {**runtimes, **resources, **general_data, **tools}
index = pandas.Index(designs)
return pandas.DataFrame(data, index)


def generate_dataframe(results):
clock_df = get_clock_dataframe(results)

general_df = get_general_dataframe(results)

df = general_df.join(clock_df, how="left")

return df
7 changes: 5 additions & 2 deletions exhaust.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from fpgaperf import *
import sow
import pandas
from dataframe import generate_dataframe

MANDATORY_CONSTRAINTS = {
"vivado": "xdc",
Expand Down Expand Up @@ -259,8 +260,10 @@ def main():

with open('{}/all.json'.format(args.out_prefix), 'w') as fout:
json.dump(merged_dict, fout, indent=4, sort_keys=True)
dataframe = pandas.DataFrame(merged_dict)
dataframe.to_json('{}/dataframe.json'.format(args.out_prefix))

dataframe = generate_dataframe(merged_dict)
dataframe = dataframe.reset_index(drop=True)
dataframe.to_json('{}/dataframe.json'.format(args.out_prefix))

result = print_summary_table(args.out_prefix, len(tasks))

Expand Down
16 changes: 7 additions & 9 deletions fpgaperf.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ def print_section_header(title):
for cd in max_freq:
actual = "%0.3f MHz" % (max_freq[cd]['actual'] / 1e6)
requested = "%0.3f MHz" % (max_freq[cd]['requested'] / 1e6)
met = max_freq[cd]['met']
met = "unknown" if max_freq[cd]['met'] is None else max_freq[cd][
'met']
s_violation = ("%0.3f ns" % max_freq[cd]['setup_violation'])
h_violation = ("%0.3f ns" % max_freq[cd]['hold_violation'])
table_data.append(
Expand All @@ -116,13 +117,9 @@ def print_section_header(title):

print_section_header('Toolchain Run-Times')
table_data = [['Stage', 'Run Time (seconds)']]
for k, v in t.runtimes.items():
if type(v) is collections.OrderedDict:
table_data.append([k, ""])
for k1, v1 in v.items():
table_data.append([" " + k1, ("%0.3f" % v1)])
else:
table_data.append([k, ("%0.3f" % v)])
for k, v in t.get_runtimes().items():
value = "%0.3f" % v if v else "N/A"
table_data.append([k, value])

table = AsciiTable(table_data)
print(table.table)
Expand All @@ -131,7 +128,8 @@ def print_section_header(title):
table_data = [['Resource', 'Used']]

for k, v in sorted(t.resources().items()):
table_data.append([k, v])
value = v if v else "N/A"
table_data.append([k, value])

table = AsciiTable(table_data)
print(table.table)
Expand Down
Loading