Skip to content

Add symbiflow tests #1564

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

Merged
merged 20 commits into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/kokoro/continuous/nightly.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ env_vars {

env_vars {
key: "NUM_CORES"
value: "5"
value: "3"
}
2 changes: 1 addition & 1 deletion .github/kokoro/presubmit/nightly.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ env_vars {

env_vars {
key: "NUM_CORES"
value: "5"
value: "3"
}
1 change: 1 addition & 0 deletions .github/kokoro/steps/vtr-full-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

make get_titan_benchmarks
make get_ispd_benchmarks
make get_symbiflow_benchmarks

dev/upgrade_vtr_archs.sh
23 changes: 23 additions & 0 deletions .github/kokoro/steps/vtr-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,26 @@ echo "========================================"
export VPR_NUM_WORKERS=1
./run_reg_test.py $VTR_TEST $VTR_TEST_OPTIONS -j$NUM_CORES
kill $MONITOR

echo "========================================"
echo "Cleaning benchmarks files"
echo "========================================"
# Removing Symbiflow archs and benchmarks
find vtr_flow/arch/symbiflow/ -type f -not -name 'README.*' -delete
find vtr_flow/benchmarks/symbiflow/ -type f -not -name 'README.*' -delete

# Removing ISPD benchmarks
find vtr_flow/benchmarks/ispd_blif/ -type f -not -name 'README.*' -delete

# Removing Titan benchmarks
find vtr_flow/benchmarks/titan_blif/ -type f -not -name 'README.*' -delete

# Removing ISPD, Titan and Symbiflow tarballs
find . -type f -regex ".*\.tar\.\(gz\|xz\)" -delete

# Make sure working directory doesn't exceed disk space limit!
echo "Working directory size: $(du -sh)"
if [[ $(du -s | cut -d $'\t' -f 1) -gt $(expr 1024 \* 1024 \* 90) ]]; then
echo "Working directory too large!"
exit 1
fi
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ vtr_flow/benchmarks/titan_other_blif/*.sdc
ispd_benchmarks_vtr*.tar.gz
vtr_flow/benchmarks/ispd_blif/*.blif

#
# SymbiFlow benchmarks
#
# We ignore the SymbiFlow netlists and architectures because of thier large size.
#
*symbiflow*.tar.xz
vtr_flow/arch/symbiflow/*.bin
vtr_flow/arch/symbiflow/*.xml
vtr_flow/benchmarks/symbiflow/*.eblif
vtr_flow/benchmarks/symbiflow/sdc/*.sdc

#
# Cloud9 Directory
#
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ add_custom_target(get_ispd_benchmarks
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Downloading (~50MB) and extracting Titan benchmarks (~0.5GB) into VTR source tree.")

#
# SymbiFlow Benchmarks
#
add_custom_target(get_symbiflow_benchmarks
COMMAND ./vtr_flow/scripts/download_symbiflow.py --vtr_flow_dir ./vtr_flow
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Downloading (~100MB) and extracting SymbiFlow architectures (~2.7GB) into VTR source tree.")

#
# Unit Testing
#
Expand Down
12 changes: 12 additions & 0 deletions vtr_flow/arch/symbiflow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SymbiFlow architectures
=======================

This directory holds all the SymbiFlow architectures that are generated in the [SymbiFlow-arch-defs](https://github.com/SymbiFlow/symbiflow-arch-defs) repository.

The data files needed to successfully run VPR are:
- Architecture XML definition
- RR Graph
- Router Lookahead
- Place delay matrix lookup

All the data files can be downloaded with the `make get_symbiflow_benchmarks` target in the root directory.
12 changes: 12 additions & 0 deletions vtr_flow/benchmarks/symbiflow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SymbiFlow benchmarks
====================

This directory holds all the SymbiFlow benchmarks that are generated in the [SymbiFlow-arch-defs](https://github.com/SymbiFlow/symbiflow-arch-defs) repository.

The circuits come along with the SDC constraints file, if present, and have been produced with yosys.
They are compatible with the symbiflow architectures produced in the same Symbiflow-arch-defs build.

Some of the circuites require also the place constraint files to correctly place some IOs and clock tiles
in the correct location, so not to incur in routability issues.

All the data files can be downloaded with the `make get_symbiflow_benchmarks` target in the root directory.
4 changes: 4 additions & 0 deletions vtr_flow/benchmarks/symbiflow/place_constr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Place constraints
=================

This directory contains the Place constraints files corresponding to the homonym circuit file.
4 changes: 4 additions & 0 deletions vtr_flow/benchmarks/symbiflow/sdc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SDC constraints
===============

This directory contains the SDC constraints files corresponding to the homonym circuit file.
195 changes: 195 additions & 0 deletions vtr_flow/scripts/download_symbiflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#!/usr/bin/env python3
"""
Script to download the SymbiFlow Series-7 architectures
"""

import sys
import os
import argparse
import math
import textwrap
import fnmatch
import tempfile
import shutil
import subprocess
from urllib import request

GCS_URL = {
"architectures":
"https://storage.googleapis.com/symbiflow-arch-defs-gha/symbiflow-xc7a50t_test-latest",
"benchmarks":
"https://storage.googleapis.com/symbiflow-arch-defs-gha/symbiflow-benchmarks-latest"
}

SYMBIFLOW_URL_MIRRORS = {"google": GCS_URL}


class ExtractionError(Exception):
"""
Extraction error exception class
"""


def parse_args():
"""
Parses and returns script's arguments
"""

description = textwrap.dedent(
"""
Download and extract a symbiflow benchmark release into a
VTR-style directory structure.

If a previous matching symbiflow release tar.gz file is found
does nothing (unless --force is specified).
"""
)
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter, description=description
)

parser.add_argument(
"--vtr_flow_dir",
required=True,
help="The 'vtr_flow' directory under the VTR tree. "
"If specified this will extract the symbiflow release, "
"placing benchmarks under vtr_flow/benchmarks/symbiflow ",
)
parser.add_argument(
"--force",
default=False,
action="store_true",
help="Run extraction step even if directores etc. already exist",
)

parser.add_argument("--mirror", default="google", choices=["google"], help="Download mirror")

parser.add_argument(
"--upgrade_archs",
action="store_true",
default=True,
help="Try to upgrade included architecture files (using the upgrade_archs.py)",
)

return parser.parse_args()


def main():
"""
Main function
"""

args = parse_args()

try:
urls = SYMBIFLOW_URL_MIRRORS[args.mirror]
archs_tar_xz_url = urls["architectures"]
benchmarks_tar_xz_url = urls["benchmarks"]

archs_tar_xz_filename = "archs_symbiflow.tar.xz"
benchmarks_tar_xz_filename = "benchmarks_symbiflow.tar.xz"

print("Downloading architectures {}".format(archs_tar_xz_url))
download_url(archs_tar_xz_filename, archs_tar_xz_url)

print("Extracting architectures {}".format(archs_tar_xz_filename))
symbiflow_data_dir = "share/symbiflow/arch/xc7a50t_test"
extract_to_vtr_flow_dir(args, archs_tar_xz_filename, "arch", symbiflow_data_dir)

print("Downloading benchmarks {}".format(benchmarks_tar_xz_url))
download_url(benchmarks_tar_xz_filename, benchmarks_tar_xz_url)

print("Extracting benchmarks {}".format(benchmarks_tar_xz_filename))
extract_to_vtr_flow_dir(args, benchmarks_tar_xz_filename, "benchmarks")

except ExtractionError as error:
print("Failed to extract data: ", error)
sys.exit(1)

sys.exit(0)


def download_url(filename, url):
"""
Downloads the symbiflow release
"""
latest_package_url = request.urlopen(url).read().decode("utf-8")
print("Downloading latest package:\n{}".format(latest_package_url))
request.urlretrieve(latest_package_url, filename, reporthook=download_progress_callback)


def download_progress_callback(block_num, block_size, expected_size):
"""
Callback for urllib.urlretrieve which prints a dot for every percent of a file downloaded
"""
total_blocks = int(math.ceil(expected_size / block_size))
progress_increment = int(math.ceil(total_blocks / 100))

if block_num % progress_increment == 0:
sys.stdout.write(".")
sys.stdout.flush()
if block_num * block_size >= expected_size:
print("")


def extract_to_vtr_flow_dir(args, tar_xz_filename, destination, extract_path=""):
"""
Extracts the 'benchmarks' directory of the symbiflow release
into its corresponding vtr directory
"""

# Reference directories
dest_dir = os.path.join(args.vtr_flow_dir, destination)
symbiflow_extract_dir = os.path.join(dest_dir, "symbiflow")

if not args.force:
# Check that all expected directories exist
expected_dirs = [
args.vtr_flow_dir,
symbiflow_extract_dir,
]
for directory in expected_dirs:
if not os.path.isdir(directory):
raise ExtractionError("{} should be a directory".format(directory))

# Create a temporary working directory
tmpdir = tempfile.mkdtemp(suffix="download_symbiflow", dir=".")

# Extract matching files into the temporary directory
subprocess.call(
"tar -C {} -xf {} {}".format(tmpdir, tar_xz_filename, extract_path),
shell=True,
)

# Move the extracted files to the relevant directories, SDC files first (since we
# need to look up the BLIF name to make it match)
for dirpath, _, filenames in os.walk(tmpdir):
for filename in filenames:
src_file_path = os.path.join(dirpath, filename)
dst_file_path = None

if fnmatch.fnmatch(src_file_path, "*/xc7a50t_test/arch.timing.xml"):
dst_file_path = os.path.join(symbiflow_extract_dir, "arch.timing.xml")

elif fnmatch.fnmatch(src_file_path, "*/xc7a50t_test/*.bin"):
dst_file_path = os.path.join(symbiflow_extract_dir, filename)

elif fnmatch.fnmatch(src_file_path, "**/*.eblif"):
dst_file_path = os.path.join(symbiflow_extract_dir, filename)

elif fnmatch.fnmatch(src_file_path, "**/*.sdc"):
dst_file_path = os.path.join(symbiflow_extract_dir, "sdc", filename)

elif fnmatch.fnmatch(src_file_path, "**/*.place"):
dst_file_path = os.path.join(symbiflow_extract_dir, "place_constr", filename)

if dst_file_path:
shutil.move(src_file_path, dst_file_path)

shutil.rmtree(tmpdir)

print("Done")


if __name__ == "__main__":
main()
Loading