Skip to content

Commit e1a0d73

Browse files
authored
Merge pull request #1587 from Xilinx/deprecate/omx
Replace oh-my-xilinx with built-in OOC synthesis in CreateStitchedIP
2 parents 6c32e0b + a8b4a5e commit e1a0d73

16 files changed

Lines changed: 320 additions & 233 deletions

docker/Dockerfile.finn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ RUN apt-get update && \
5757
libzmq3-dev \
5858
libpixman-1-0 \
5959
nano \
60-
zsh \
6160
rsync \
6261
git \
6362
openssh-client \

docker/finn_entrypoint.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export LC_ALL="en_US.UTF-8"
3535
export LANGUAGE="en_US:en"
3636
# colorful terminal output
3737
export PS1='\[\033[1;36m\]\u\[\033[1;31m\]@\[\033[1;32m\]\h:\[\033[1;35m\]\w\[\033[1;31m\]\$\[\033[0m\] '
38-
export PATH=$PATH:$OHMYXILINX
3938

4039
YELLOW='\033[0;33m'
4140
GREEN='\033[0;32m'

fetch-repos.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ FINN_EXP_COMMIT="0724be21111a21f0d81a072fccc1c446e053f851"
3333
BREVITAS_COMMIT="aad4d5a293db6f2ec622a92a5d3278e47072453e"
3434
CNPY_COMMIT="8c82362372ce600bbd1cf11d64661ab69d38d7de"
3535
HLSLIB_COMMIT="a2cd3e6ce653a03e59af6bcb9fbeaa71618d160e"
36-
OMX_COMMIT="a5d48f93309b235fdd21556d16e86e6ef5db6e2e"
3736
AVNET_BDF_COMMIT="2d49cfc25766f07792c0b314489f21fe916b639b"
3837
XIL_BDF_COMMIT="8cf4bb674a919ac34e3d99d8d71a9e60af93d14e"
3938
RFSOC4x2_BDF_COMMIT="13fb6f6c02c7dfd7e4b336b18b959ad5115db696"
@@ -46,7 +45,6 @@ FINN_EXP_URL="https://github.com/Xilinx/finn-experimental.git"
4645
BREVITAS_URL="https://github.com/Xilinx/brevitas.git"
4746
CNPY_URL="https://github.com/maltanar/cnpy.git"
4847
HLSLIB_URL="https://github.com/Xilinx/finn-hlslib.git"
49-
OMX_URL="https://github.com/maltanar/oh-my-xilinx.git"
5048
AVNET_BDF_URL="https://github.com/Avnet/bdf.git"
5149
XIL_BDF_URL="https://github.com/Xilinx/XilinxBoardStore.git"
5250
RFSOC4x2_BDF_URL="https://github.com/RealDigitalOrg/RFSoC4x2-BSP.git"
@@ -58,7 +56,6 @@ FINN_EXP_DIR="finn-experimental"
5856
BREVITAS_DIR="brevitas"
5957
CNPY_DIR="cnpy"
6058
HLSLIB_DIR="finn-hlslib"
61-
OMX_DIR="oh-my-xilinx"
6259
AVNET_BDF_DIR="avnet-bdf"
6360
XIL_BDF_DIR="xil-bdf"
6461
RFSOC4x2_BDF_DIR="rfsoc4x2-bdf"
@@ -122,7 +119,6 @@ fetch_repo $FINN_EXP_URL $FINN_EXP_COMMIT $FINN_EXP_DIR
122119
fetch_repo $BREVITAS_URL $BREVITAS_COMMIT $BREVITAS_DIR
123120
fetch_repo $CNPY_URL $CNPY_COMMIT $CNPY_DIR
124121
fetch_repo $HLSLIB_URL $HLSLIB_COMMIT $HLSLIB_DIR
125-
fetch_repo $OMX_URL $OMX_COMMIT $OMX_DIR
126122
fetch_repo $AVNET_BDF_URL $AVNET_BDF_COMMIT $AVNET_BDF_DIR
127123
fetch_repo $XIL_BDF_URL $XIL_BDF_COMMIT $XIL_BDF_DIR
128124
fetch_repo $RFSOC4x2_BDF_URL $RFSOC4x2_BDF_COMMIT $RFSOC4x2_BDF_DIR

run-docker.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ SCRIPTPATH=$(dirname "$SCRIPT")
9393
: ${FINN_DOCKER_BUILD_EXTRA=""}
9494
: ${FINN_SKIP_DEP_REPOS="0"}
9595
: ${FINN_SKIP_BOARD_FILES="0"}
96-
: ${OHMYXILINX="${SCRIPTPATH}/deps/oh-my-xilinx"}
9796
: ${NVIDIA_VISIBLE_DEVICES=""}
9897
: ${DOCKER_BUILDKIT="1"}
9998
: ${FINN_SINGULARITY=""}
@@ -253,7 +252,6 @@ DOCKER_EXEC+="-v $FINN_HOST_BUILD_DIR:$FINN_HOST_BUILD_DIR "
253252
DOCKER_EXEC+="-e FINN_BUILD_DIR=$FINN_HOST_BUILD_DIR "
254253
DOCKER_EXEC+="-e FINN_ROOT="$SCRIPTPATH" "
255254
DOCKER_EXEC+="-e LOCALHOST_URL=$LOCALHOST_URL "
256-
DOCKER_EXEC+="-e OHMYXILINX=$OHMYXILINX "
257255
DOCKER_EXEC+="-e NUM_DEFAULT_WORKERS=$NUM_DEFAULT_WORKERS "
258256
# Workaround for FlexLM issue, see:
259257
# https://community.flexera.com/t5/InstallAnywhere-Forum/Issues-when-running-Xilinx-tools-or-Other-vendor-tools-in-docker/m-p/245820#M10647

scripts/finn-env.sh

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ export FINN_HOST_BUILD_DIR="${FINN_HOST_BUILD_DIR:-/tmp/finn_local_$(whoami)}"
5555
export FINN_BUILD_DIR="$FINN_HOST_BUILD_DIR"
5656
mkdir -p "$FINN_BUILD_DIR"
5757

58-
# Add oh-my-xilinx to PATH
59-
export OHMYXILINX="$FINN_ROOT/deps/oh-my-xilinx"
60-
if [ -d "$OHMYXILINX" ]; then
61-
export PATH="$PATH:$OHMYXILINX"
62-
fi
63-
6458
# Board files path
6559
export FINN_BOARD_FILES_PATH="$FINN_ROOT/deps/board_files"
6660

scripts/install-system-deps.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ if command -v apt-get &> /dev/null; then
6868
git \
6969
wget \
7070
unzip \
71-
zsh \
7271
python3 \
7372
python3-pip \
7473
python3-venv

src/finn/builder/build_dataflow_config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ class VerificationStepType(str, Enum):
124124
"step_set_fifo_depths",
125125
"step_create_stitched_ip",
126126
"step_measure_rtlsim_performance",
127-
"step_out_of_context_synthesis",
128127
"step_synthesize_bitfile",
129128
"step_make_driver",
130129
"step_deployment_package",

src/finn/builder/build_dataflow_steps.py

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@
119119
from finn.transformation.fpgadataflow.set_folding import SetFolding
120120
from finn.transformation.fpgadataflow.set_loop_boundary import SetLoopBoundary
121121
from finn.transformation.fpgadataflow.specialize_layers import SpecializeLayers
122-
from finn.transformation.fpgadataflow.synth_ooc import SynthOutOfContext
123122
from finn.transformation.fpgadataflow.transpose_decomposition import (
124123
InferInnerOuterShuffles,
125124
ShuffleDecomposition,
@@ -141,6 +140,7 @@
141140
from finn.util.fpgadataflow import warn_hls_rtl_dsp_conflict
142141
from finn.util.mlo_sim import is_mlo, mlo_prehook_func_factory
143142
from finn.util.test import execute_parent
143+
from finn.util.vivado import parse_ooc_synth_results
144144

145145

146146
def verify_step(
@@ -272,7 +272,6 @@ def prepare_for_stitched_ip_rtlsim(verify_model, cfg):
272272
CreateStitchedIP(
273273
cfg._resolve_fpga_part(),
274274
cfg.synth_clk_period_ns,
275-
vitis=False,
276275
)
277276
)
278277
else:
@@ -332,7 +331,6 @@ def prepare_loop_ops_ipgen(node, cfg):
332331
CreateStitchedIP(
333332
cfg._resolve_fpga_part(),
334333
cfg.synth_clk_period_ns,
335-
vitis=False,
336334
)
337335
)
338336
node_inst.set_nodeattr("body", loop_model.graph)
@@ -1061,14 +1059,35 @@ def step_create_stitched_ip(model: ModelWrapper, cfg: DataflowBuildConfig):
10611059

10621060
if DataflowOutputType.STITCHED_IP in cfg.generate_outputs:
10631061
stitched_ip_dir = cfg.output_dir + "/stitched_ip"
1062+
# If OOC_SYNTH is also requested, run P&R to extract metrics
1063+
run_pnr = DataflowOutputType.OOC_SYNTH in cfg.generate_outputs
10641064
model = model.transform(
10651065
CreateStitchedIP(
10661066
cfg._resolve_fpga_part(),
10671067
cfg.synth_clk_period_ns,
1068-
vitis=cfg.stitched_ip_gen_dcp,
1068+
run_synth=cfg.stitched_ip_gen_dcp or run_pnr,
1069+
run_pnr=run_pnr,
10691070
signature=cfg.signature,
10701071
)
10711072
)
1073+
# If P&R was run, parse the OOC results and store in model metadata + write report
1074+
if run_pnr:
1075+
vivado_stitch_proj = model.get_metadata_prop("vivado_stitch_proj")
1076+
ooc_res_dict = parse_ooc_synth_results(vivado_stitch_proj)
1077+
if ooc_res_dict is not None:
1078+
# Calculate estimated throughput from fmax and cycle analysis
1079+
estimate_network_performance = model.analysis(dataflow_performance)
1080+
n_clock_cycles_per_sec = float(ooc_res_dict["fmax_mhz"]) * (10**6)
1081+
est_fps = n_clock_cycles_per_sec / estimate_network_performance["max_cycles"]
1082+
ooc_res_dict["estimated_throughput_fps"] = est_fps
1083+
1084+
model.set_metadata_prop("res_total_ooc_synth", str(ooc_res_dict))
1085+
# Write results to report directory
1086+
report_dir = cfg.output_dir + "/report"
1087+
os.makedirs(report_dir, exist_ok=True)
1088+
with open(report_dir + "/ooc_synth_and_timing.json", "w") as f:
1089+
json.dump(ooc_res_dict, f, indent=2)
1090+
10721091
# TODO copy all ip sources into output dir? as zip?
10731092
shutil.copytree(
10741093
model.get_metadata_prop("vivado_stitch_proj"), stitched_ip_dir, dirs_exist_ok=True
@@ -1212,35 +1231,6 @@ def step_make_driver(model: ModelWrapper, cfg: DataflowBuildConfig):
12121231
return model
12131232

12141233

1215-
def step_out_of_context_synthesis(model: ModelWrapper, cfg: DataflowBuildConfig):
1216-
"""Run out-of-context synthesis and generate reports.
1217-
Depends on the DataflowOutputType.STITCHED_IP output product."""
1218-
if DataflowOutputType.OOC_SYNTH in cfg.generate_outputs:
1219-
assert DataflowOutputType.STITCHED_IP in cfg.generate_outputs, "OOC needs stitched IP"
1220-
model = model.transform(
1221-
SynthOutOfContext(part=cfg._resolve_fpga_part(), clk_period_ns=cfg.synth_clk_period_ns)
1222-
)
1223-
report_dir = cfg.output_dir + "/report"
1224-
os.makedirs(report_dir, exist_ok=True)
1225-
ooc_res_dict = model.get_metadata_prop("res_total_ooc_synth")
1226-
ooc_res_dict = eval(ooc_res_dict)
1227-
1228-
estimate_network_performance = model.analysis(dataflow_performance)
1229-
# add some more metrics to estimated performance
1230-
n_clock_cycles_per_sec = float(ooc_res_dict["fmax_mhz"]) * (10**6)
1231-
est_fps = n_clock_cycles_per_sec / estimate_network_performance["max_cycles"]
1232-
ooc_res_dict["estimated_throughput_fps"] = est_fps
1233-
with open(report_dir + "/ooc_synth_and_timing.json", "w") as f:
1234-
json.dump(ooc_res_dict, f, indent=2)
1235-
1236-
else:
1237-
print(
1238-
"""DataflowOutputType.OOC_SYNTH not in requested outputs,
1239-
skipping step_out_of_context_synthesis."""
1240-
)
1241-
return model
1242-
1243-
12441234
def step_synthesize_bitfile(model: ModelWrapper, cfg: DataflowBuildConfig):
12451235
"""Synthesize a bitfile for the using the specified shell flow, using either
12461236
Vivado or Vitis, to target the specified board."""
@@ -1399,7 +1389,6 @@ def step_loop_rolling(model, cfg):
13991389
"step_create_stitched_ip": step_create_stitched_ip,
14001390
"step_measure_rtlsim_performance": step_measure_rtlsim_performance,
14011391
"step_make_driver": step_make_driver,
1402-
"step_out_of_context_synthesis": step_out_of_context_synthesis,
14031392
"step_synthesize_bitfile": step_synthesize_bitfile,
14041393
"step_deployment_package": step_deployment_package,
14051394
"step_loop_rolling": step_loop_rolling,

src/finn/transformation/fpgadataflow/alveo_build.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ def apply(self, model):
258258
kernel_model = kernel_model.transform(PrepareIP(self.fpga_part, self.period_ns))
259259
kernel_model = kernel_model.transform(HLSSynthIP())
260260
kernel_model = kernel_model.transform(
261-
CreateStitchedIP(self.fpga_part, self.period_ns, sdp_node.onnx_node.name, True)
261+
CreateStitchedIP(
262+
self.fpga_part, self.period_ns, sdp_node.onnx_node.name, run_synth=True
263+
)
262264
)
263265
if self.platform == "vitis-xrt":
264266
kernel_model = kernel_model.transform(CreateVitisXO(sdp_node.onnx_node.name))

src/finn/transformation/fpgadataflow/create_stitched_ip.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,19 @@ class CreateStitchedIP(Transformation):
8686
The packaged block design IP can be found under the ip subdirectory.
8787
"""
8888

89-
def __init__(self, fpgapart, clk_ns, ip_name="finn_design", vitis=False, signature=[]):
89+
def __init__(
90+
self, fpgapart, clk_ns, ip_name="finn_design", run_synth=False, run_pnr=False, signature=[]
91+
):
9092
super().__init__()
9193
self.fpgapart = fpgapart
9294
self.clk_ns = clk_ns
9395
self.ip_name = ip_name
9496
self.is_mlo = False
95-
self.vitis = vitis
97+
self.run_synth = run_synth
98+
self.run_pnr = run_pnr
99+
# run_pnr requires synthesis
100+
if self.run_pnr and not self.run_synth:
101+
self.run_synth = True
96102
self.signature = signature
97103
self.has_aximm = False
98104
self.aximm_idx = 0
@@ -508,7 +514,7 @@ def apply(self, model):
508514
model.set_metadata_prop("wrapper_filename", wrapper_filename)
509515
tcl.append("set_property top %s_wrapper [current_fileset]" % block_name)
510516
# synthesize to DCP and export stub, DCP and constraints
511-
if self.vitis:
517+
if self.run_synth:
512518
tcl.append(
513519
"set_property SYNTH_CHECKPOINT_MODE Hierarchical [ get_files %s ]" % bd_filename
514520
)
@@ -530,6 +536,32 @@ def apply(self, model):
530536
"report_utilization -hierarchical -hierarchical_depth 5 "
531537
"-file %s_partition_util.rpt" % block_name
532538
)
539+
# optionally run place & route and extract OOC metrics
540+
if self.run_pnr:
541+
tcl.append("")
542+
tcl.append("# --- Place and Route for OOC Metrics ---")
543+
tcl.append("create_clock -period %f [get_ports ap_clk]" % self.clk_ns)
544+
tcl.append("opt_design")
545+
tcl.append("place_design")
546+
tcl.append("route_design")
547+
tcl.append("")
548+
tcl.append("# Write reports to files for Python-side parsing")
549+
util_rpt_file = "%s/ooc_utilization.rpt" % vivado_stitch_proj_dir
550+
timing_rpt_file = "%s/ooc_timing.rpt" % vivado_stitch_proj_dir
551+
power_rpt_file = "%s/ooc_power.rpt" % vivado_stitch_proj_dir
552+
tcl.append('report_utilization -file "%s"' % util_rpt_file)
553+
tcl.append('report_timing_summary -file "%s"' % timing_rpt_file)
554+
tcl.append('report_power -file "%s"' % power_rpt_file)
555+
tcl.append("")
556+
tcl.append("# Write metadata (clock period, Vivado version) to a simple file")
557+
meta_file = "%s/ooc_metadata.txt" % vivado_stitch_proj_dir
558+
tcl.append('set fp [open "%s" w]' % meta_file)
559+
tcl.append('puts $fp "clk_period_ns=%f"' % self.clk_ns)
560+
tcl.append('puts $fp "vivado_version=[version -short]"')
561+
tcl.append("close $fp")
562+
tcl.append("")
563+
tcl.append("# Save routed checkpoint")
564+
tcl.append("write_checkpoint %s/%s_routed.dcp" % (vivado_stitch_proj_dir, block_name))
533565
# export block design itself as an IP core
534566
block_vendor = "xilinx_finn"
535567
block_library = "finn"
@@ -560,7 +592,7 @@ def apply(self, model):
560592
"-of [ipx::get_bus_interfaces -of [ipx::current_core ]]]"
561593
)
562594
# if targeting Vitis, add some properties to the IP
563-
if self.vitis:
595+
if self.run_synth:
564596
# replace source code with dcp
565597
tcl.append("set_property sdx_kernel true [ipx::find_open_core %s]" % block_vlnv)
566598
tcl.append("set_property sdx_kernel_type rtl [ipx::find_open_core %s]" % block_vlnv)

0 commit comments

Comments
 (0)