From 5924f630e996cc96d4c2ac8f2800a2b60cf02d0e Mon Sep 17 00:00:00 2001
From: Yaman Umuroglu <maltanar@gmail.com>
Date: Sun, 23 Aug 2020 21:40:49 +0200
Subject: [PATCH] [Vitis] allow specifying opt strategy + use quick for tests

---
 .../fpgadataflow/vitis_build.py               | 35 ++++++++++++++++---
 tests/end2end/test_vitis_end2end_cnv_w1a1.py  | 11 ++++--
 tests/end2end/test_vitis_end2end_tfc_w1a1.py  | 11 ++++--
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/src/finn/transformation/fpgadataflow/vitis_build.py b/src/finn/transformation/fpgadataflow/vitis_build.py
index cb9182c23..c37d753f6 100644
--- a/src/finn/transformation/fpgadataflow/vitis_build.py
+++ b/src/finn/transformation/fpgadataflow/vitis_build.py
@@ -51,6 +51,7 @@ from finn.transformation.fpgadataflow.make_pynq_driver import MakePYNQDriver
 from finn.transformation.general import GiveReadableTensorNames, GiveUniqueNodeNames
 from finn.util.basic import make_build_dir
 from finn.transformation.infer_data_layouts import InferDataLayouts
+from enum import Enum
 
 
 def _check_vitis_envvars():
@@ -63,6 +64,17 @@ def _check_vitis_envvars():
     ), "XILINX_XRT must be set for Vitis, ensure the XRT env is sourced"
 
 
+class VitisOptStrategy(Enum):
+    "Values applicable to VitisBuild optimization strategy."
+
+    DEFAULT = "0"
+    POWER = "1"
+    PERFORMANCE = "2"
+    PERFORMANCE_BEST = "3"
+    SIZE = "s"
+    BUILD_SPEED = "quick"
+
+
 class CreateVitisXO(Transformation):
     """Create a Vitis object file from a stitched FINN ip.
 
@@ -164,10 +176,11 @@ class VitisLink(Transformation):
     ModelProto's metadata_props field with the XCLBIN full path as value.
     """
 
-    def __init__(self, platform, f_mhz=200):
+    def __init__(self, platform, f_mhz=200, strategy=VitisOptStrategy.PERFORMANCE):
         super().__init__()
         self.platform = platform
         self.f_mhz = f_mhz
+        self.strategy = strategy
 
     def apply(self, model):
         _check_vitis_envvars()
@@ -246,9 +259,14 @@ class VitisLink(Transformation):
             f.write("cd {}\n".format(link_dir))
             f.write(
                 "v++ -t hw --platform %s --link %s"
-                " --kernel_frequency %d --config config.txt --optimize 2"
+                " --kernel_frequency %d --config config.txt --optimize %s"
                 " --save-temps -R2\n"
-                % (self.platform, " ".join(object_files), self.f_mhz)
+                % (
+                    self.platform,
+                    " ".join(object_files),
+                    self.f_mhz,
+                    self.strategy.value,
+                )
             )
             f.write("cd {}\n".format(working_dir))
         bash_command = ["bash", script]
@@ -266,11 +284,14 @@ class VitisLink(Transformation):
 class VitisBuild(Transformation):
     """Best-effort attempt at building the accelerator with Vitis."""
 
-    def __init__(self, fpga_part, period_ns, platform):
+    def __init__(
+        self, fpga_part, period_ns, platform, strategy=VitisOptStrategy.PERFORMANCE
+    ):
         super().__init__()
         self.fpga_part = fpga_part
         self.period_ns = period_ns
         self.platform = platform
+        self.strategy = strategy
 
     def apply(self, model):
         _check_vitis_envvars()
@@ -315,7 +336,11 @@ class VitisBuild(Transformation):
             )
             kernel_model.save(dataflow_model_filename)
         # Assemble design from kernels
-        model = model.transform(VitisLink(self.platform, round(1000 / self.period_ns)))
+        model = model.transform(
+            VitisLink(
+                self.platform, round(1000 / self.period_ns), strategy=self.strategy
+            )
+        )
         # set platform attribute for correct remote execution
         model.set_metadata_prop("platform", "alveo")
 
diff --git a/tests/end2end/test_vitis_end2end_cnv_w1a1.py b/tests/end2end/test_vitis_end2end_cnv_w1a1.py
index e1df93c57..3f8799c04 100644
--- a/tests/end2end/test_vitis_end2end_cnv_w1a1.py
+++ b/tests/end2end/test_vitis_end2end_cnv_w1a1.py
@@ -55,7 +55,7 @@ from finn.transformation.streamline import Streamline
 from finn.util.basic import alveo_part_map, alveo_default_platform
 from finn.util.test import get_test_model_trained, load_test_checkpoint_or_skip
 from finn.transformation.fpgadataflow.annotate_resources import AnnotateResources
-from finn.transformation.fpgadataflow.vitis_build import VitisBuild
+from finn.transformation.fpgadataflow.vitis_build import VitisBuild, VitisOptStrategy
 import pkg_resources as pk
 from finn.transformation.double_to_single_float import DoubleToSingleFloat
 from finn.transformation.move_reshape import RemoveCNVtoFCFlatten
@@ -176,7 +176,14 @@ def test_end2end_vitis_cnv_w1a1_build():
     model = load_test_checkpoint_or_skip(
         build_dir + "/end2end_vitis_cnv_w1a1_folded.onnx"
     )
-    model = model.transform(VitisBuild(test_fpga_part, target_clk_ns, test_platform))
+    model = model.transform(
+        VitisBuild(
+            test_fpga_part,
+            target_clk_ns,
+            test_platform,
+            strategy=VitisOptStrategy.BUILD_SPEED,
+        )
+    )
     model.save(build_dir + "/end2end_vitis_cnv_w1a1_build.onnx")
 
 
diff --git a/tests/end2end/test_vitis_end2end_tfc_w1a1.py b/tests/end2end/test_vitis_end2end_tfc_w1a1.py
index 085c63ace..c5057f253 100644
--- a/tests/end2end/test_vitis_end2end_tfc_w1a1.py
+++ b/tests/end2end/test_vitis_end2end_tfc_w1a1.py
@@ -60,7 +60,7 @@ from finn.transformation.streamline import Streamline
 from finn.transformation.streamline.round_thresholds import RoundAndClipThresholds
 from finn.util.basic import alveo_part_map, alveo_default_platform
 from finn.util.test import get_test_model_trained, load_test_checkpoint_or_skip
-from finn.transformation.fpgadataflow.vitis_build import VitisBuild
+from finn.transformation.fpgadataflow.vitis_build import VitisBuild, VitisOptStrategy
 from finn.transformation.infer_data_layouts import InferDataLayouts
 from finn.transformation.fpgadataflow.make_deployment import DeployToPYNQ
 from pkgutil import get_data
@@ -162,7 +162,14 @@ def test_end2end_vitis_tfc_w1a1_build():
     model = load_test_checkpoint_or_skip(
         build_dir + "/end2end_vitis_tfc_w1a1_folded.onnx"
     )
-    model = model.transform(VitisBuild(test_fpga_part, target_clk_ns, test_platform))
+    model = model.transform(
+        VitisBuild(
+            test_fpga_part,
+            target_clk_ns,
+            test_platform,
+            strategy=VitisOptStrategy.BUILD_SPEED,
+        )
+    )
     # TODO post-synth resources
     model.save(build_dir + "/end2end_vitis_tfc_w1a1_build.onnx")
 
-- 
GitLab