diff --git a/src/finn/analysis/fpgadataflow/hls_synth_res_estimation.py b/src/finn/analysis/fpgadataflow/hls_synth_res_estimation.py index 0334c316b80a5c0628d00b75eb40776436cb8434..58fe8e2962d03ab0c47957f205a0c2f2b8fc51f5 100644 --- a/src/finn/analysis/fpgadataflow/hls_synth_res_estimation.py +++ b/src/finn/analysis/fpgadataflow/hls_synth_res_estimation.py @@ -30,7 +30,7 @@ import os import xml.etree.ElementTree as ET import finn.custom_op.registry as registry -import finn.util.basic as util +from finn.util.fpgadataflow import is_fpgadataflow_node def hls_synth_res_estimation(model): @@ -40,38 +40,33 @@ def hls_synth_res_estimation(model): res_dict = {} for node in model.graph.node: - if node.domain == "finn": - backend_attribute = util.get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - op_type = node.op_type - inst = registry.custom_op[op_type](node) - code_gen_dir = inst.get_nodeattr("code_gen_dir_ipgen") - if code_gen_dir == "": - raise Exception( - """Please run "CodeGen_ipgen" transformation and - "HLSSynth_IPGen" first to generate the report files""" - ) + if is_fpgadataflow_node(node) is True: + op_type = node.op_type + inst = registry.custom_op[op_type](node) + code_gen_dir = inst.get_nodeattr("code_gen_dir_ipgen") + if code_gen_dir == "": + raise Exception( + """Please run "CodeGen_ipgen" transformation and + "HLSSynth_IPGen" first to generate the report files""" + ) + else: + xmlfile = "{}/project_{}/sol1/syn/report/{}_csynth.xml".format( + code_gen_dir, node.name, node.name + ) + + if os.path.isfile(xmlfile): + res_dict[node.name] = [] + tree = ET.parse(xmlfile) + root = tree.getroot() + for item in root.findall("AreaEstimates/Resources"): + for child in item: + res_dict[node.name].append( + ["{} : {}".format(child.tag, child.text)] + ) else: - xmlfile = "{}/project_{}/sol1/syn/report/{}_csynth.xml".format( - code_gen_dir, node.name, node.name + raise Exception( + """Please run "HLSSynth_IPGen" first + to generate the report files""" ) - if os.path.isfile(xmlfile): - res_dict[node.name] = [] - tree = ET.parse(xmlfile) - root = tree.getroot() - for item in root.findall("AreaEstimates/Resources"): - for child in item: - res_dict[node.name].append( - ["{} : {}".format(child.tag, child.text)] - ) - else: - raise Exception( - """Please run "HLSSynth_IPGen" first - to generate the report files""" - ) - return res_dict diff --git a/src/finn/analysis/fpgadataflow/res_estimation.py b/src/finn/analysis/fpgadataflow/res_estimation.py index 3585868906fb2c66aef045f49f0da919f933d012..c190059eceb0cc111477c84f843f4a9f9bf2f393 100644 --- a/src/finn/analysis/fpgadataflow/res_estimation.py +++ b/src/finn/analysis/fpgadataflow/res_estimation.py @@ -27,7 +27,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import finn.custom_op.registry as registry -import finn.util.basic as util +from finn.util.fpgadataflow import is_fpgadataflow_node def res_estimation(model): @@ -37,14 +37,9 @@ def res_estimation(model): res_dict = {} for node in model.graph.node: - if node.domain == "finn": - backend_attribute = util.get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - op_type = node.op_type - inst = registry.custom_op[op_type](node) - res_dict[node.name] = inst.node_res_estimation() + if is_fpgadataflow_node(node) is True: + op_type = node.op_type + inst = registry.custom_op[op_type](node) + res_dict[node.name] = inst.node_res_estimation() return res_dict diff --git a/src/finn/transformation/fpgadataflow/cleanup.py b/src/finn/transformation/fpgadataflow/cleanup.py index e1bf53f7ef53c986fffe3dcc507e6886660eb611..a31cbfa7dd30eff37ceb2d7bf3c162093a5a3a1c 100644 --- a/src/finn/transformation/fpgadataflow/cleanup.py +++ b/src/finn/transformation/fpgadataflow/cleanup.py @@ -30,7 +30,7 @@ import os import shutil import finn.custom_op.registry as registry -import finn.util.basic as util +from finn.util.fpgadataflow import is_fpgadataflow_node from finn.transformation import Transformation @@ -53,36 +53,33 @@ class CleanUp(Transformation): model.set_metadata_prop("vivado_stitch_proj", "") for node in model.graph.node: op_type = node.op_type - if node.domain == "finn": - backend_attribute = util.get_by_name(node.attribute, "backend") - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - try: - # lookup op_type in registry of CustomOps - inst = registry.custom_op[op_type](node) - # delete code_gen_dir from npysim - code_gen_dir = inst.get_nodeattr("code_gen_dir_npysim") - if os.path.isdir(code_gen_dir): - shutil.rmtree(code_gen_dir) - inst.set_nodeattr("code_gen_dir_npysim", "") - inst.set_nodeattr("executable_path", "") - # delete code_gen_dir from ipgen and project folder - code_gen_dir = inst.get_nodeattr("code_gen_dir_ipgen") - ipgen_path = inst.get_nodeattr("ipgen_path") - if os.path.isdir(code_gen_dir): - shutil.rmtree(code_gen_dir) - if os.path.isdir(ipgen_path): - shutil.rmtree(ipgen_path) - inst.set_nodeattr("code_gen_dir_ipgen", "") - inst.set_nodeattr("ipgen_path", "") - # delete Java HotSpot Performance data log - for d_name in os.listdir("/tmp/"): - if "hsperfdata" in d_name: - shutil.rmtree("/tmp/" + str(d_name)) + if is_fpgadataflow_node(node) is True: + try: + # lookup op_type in registry of CustomOps + inst = registry.custom_op[op_type](node) + # delete code_gen_dir from npysim + code_gen_dir = inst.get_nodeattr("code_gen_dir_npysim") + if os.path.isdir(code_gen_dir): + shutil.rmtree(code_gen_dir) + inst.set_nodeattr("code_gen_dir_npysim", "") + inst.set_nodeattr("executable_path", "") + # delete code_gen_dir from ipgen and project folder + code_gen_dir = inst.get_nodeattr("code_gen_dir_ipgen") + ipgen_path = inst.get_nodeattr("ipgen_path") + if os.path.isdir(code_gen_dir): + shutil.rmtree(code_gen_dir) + if os.path.isdir(ipgen_path): + shutil.rmtree(ipgen_path) + inst.set_nodeattr("code_gen_dir_ipgen", "") + inst.set_nodeattr("ipgen_path", "") + # delete Java HotSpot Performance data log + for d_name in os.listdir("/tmp/"): + if "hsperfdata" in d_name: + shutil.rmtree("/tmp/" + str(d_name)) - except KeyError: - # exception if op_type is not supported - raise Exception( - "Custom op_type %s is currently not supported." % op_type - ) + except KeyError: + # exception if op_type is not supported + raise Exception( + "Custom op_type %s is currently not supported." % op_type + ) return (model, False) diff --git a/src/finn/transformation/fpgadataflow/codegen_ipgen.py b/src/finn/transformation/fpgadataflow/codegen_ipgen.py index ab3b4e820e04ff1f0a02b6b95254b5fe8b45de91..30bb6eb90a515615ff333f7858da9f7f3130986d 100644 --- a/src/finn/transformation/fpgadataflow/codegen_ipgen.py +++ b/src/finn/transformation/fpgadataflow/codegen_ipgen.py @@ -30,7 +30,8 @@ import os import finn.custom_op.registry as registry from finn.transformation import Transformation -from finn.util.basic import get_by_name, make_build_dir +from finn.util.basic import make_build_dir +from finn.util.fpgadataflow import is_fpgadataflow_node def _codegen_single_node(node, model, fpgapart, clk): @@ -77,11 +78,6 @@ class CodeGen_ipgen(Transformation): def apply(self, model): for node in model.graph.node: - if node.domain == "finn": - backend_attribute = get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - _codegen_single_node(node, model, self.fpgapart, self.clk) + if is_fpgadataflow_node(node) is True: + _codegen_single_node(node, model, self.fpgapart, self.clk) return (model, False) diff --git a/src/finn/transformation/fpgadataflow/codegen_npysim.py b/src/finn/transformation/fpgadataflow/codegen_npysim.py index d2862d82cf76f62bc236ace9d44c607dd2ab86ff..178601c31a52c4cef5a17f63144a1d091a577d3e 100644 --- a/src/finn/transformation/fpgadataflow/codegen_npysim.py +++ b/src/finn/transformation/fpgadataflow/codegen_npysim.py @@ -30,7 +30,8 @@ import os import finn.custom_op.registry as registry from finn.transformation import Transformation -from finn.util.basic import get_by_name, make_build_dir +from finn.util.basic import make_build_dir +from finn.util.fpgadataflow import is_fpgadataflow_node def _codegen_single_node(node, model): @@ -67,11 +68,6 @@ class CodeGen_npysim(Transformation): def apply(self, model): for node in model.graph.node: - if node.domain == "finn": - backend_attribute = get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - _codegen_single_node(node, model) + if is_fpgadataflow_node(node) is True: + _codegen_single_node(node, model) return (model, False) diff --git a/src/finn/transformation/fpgadataflow/compile.py b/src/finn/transformation/fpgadataflow/compile.py index e577c3af6d2b92d8a2c63e89e3b1bca21d3d7c0a..0b1489e61aca04ae7b771ed42b1deb6d90f446bf 100644 --- a/src/finn/transformation/fpgadataflow/compile.py +++ b/src/finn/transformation/fpgadataflow/compile.py @@ -27,7 +27,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import finn.custom_op.registry as registry -import finn.util.basic as util +from finn.util.fpgadataflow import is_fpgadataflow_node from finn.transformation import Transformation @@ -46,32 +46,27 @@ class Compile(Transformation): def apply(self, model): for node in model.graph.node: op_type = node.op_type - if node.domain == "finn": - backend_attribute = util.get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - try: - # lookup op_type in registry of CustomOps - inst = registry.custom_op[op_type](node) - # ensure that code is generated - assert ( - inst.get_nodeattr("code_gen_dir_npysim") != "" - ), """Node + if is_fpgadataflow_node(node) is True: + try: + # lookup op_type in registry of CustomOps + inst = registry.custom_op[op_type](node) + # ensure that code is generated + assert ( + inst.get_nodeattr("code_gen_dir_npysim") != "" + ), """Node attribute "code_gen_dir_npysim" is not set. Please run Transformation CodeGen_npysim first.""" - # call the compilation function for this node - inst.compile_singlenode_code() - # ensure that executable path is now set - assert ( - inst.get_nodeattr("executable_path") != "" - ), """Transformation + # call the compilation function for this node + inst.compile_singlenode_code() + # ensure that executable path is now set + assert ( + inst.get_nodeattr("executable_path") != "" + ), """Transformation compile was not successful, there is no path to executables set in node attribute "executable_path".""" - except KeyError: - # exception if op_type is not supported - raise Exception( - "Custom op_type %s is currently not supported." % op_type - ) + except KeyError: + # exception if op_type is not supported + raise Exception( + "Custom op_type %s is currently not supported." % op_type + ) return (model, False) diff --git a/src/finn/transformation/fpgadataflow/hlssynth_ipgen.py b/src/finn/transformation/fpgadataflow/hlssynth_ipgen.py index 9fb7f8652d1fa5e624776a81ff6946d67882aa2a..e90a6debeedb4553b825baea94a73425c5e2615c 100644 --- a/src/finn/transformation/fpgadataflow/hlssynth_ipgen.py +++ b/src/finn/transformation/fpgadataflow/hlssynth_ipgen.py @@ -27,7 +27,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import finn.custom_op.registry as registry -import finn.util.basic as util +from finn.util.fpgadataflow import is_fpgadataflow_node from finn.transformation import Transformation @@ -46,32 +46,27 @@ class HLSSynth_IPGen(Transformation): def apply(self, model): for node in model.graph.node: op_type = node.op_type - if node.domain == "finn": - backend_attribute = util.get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - try: - # lookup op_type in registry of CustomOps - inst = registry.custom_op[op_type](node) - # ensure that code is generated - assert ( - inst.get_nodeattr("code_gen_dir_ipgen") != "" - ), """Node + if is_fpgadataflow_node(node) is True: + try: + # lookup op_type in registry of CustomOps + inst = registry.custom_op[op_type](node) + # ensure that code is generated + assert ( + inst.get_nodeattr("code_gen_dir_ipgen") != "" + ), """Node attribute "code_gen_dir_ipgen" is empty. Please run transformation CodeGen_ipgen first.""" - # call the compilation function for this node - inst.ipgen_singlenode_code() - # ensure that executable path is now set - assert ( - inst.get_nodeattr("ipgen_path") != "" - ), """Transformation + # call the compilation function for this node + inst.ipgen_singlenode_code() + # ensure that executable path is now set + assert ( + inst.get_nodeattr("ipgen_path") != "" + ), """Transformation HLSSynth_IPGen was not successful. Node attribute "ipgen_path" is empty.""" - except KeyError: - # exception if op_type is not supported - raise Exception( - "Custom op_type %s is currently not supported." % op_type - ) + except KeyError: + # exception if op_type is not supported + raise Exception( + "Custom op_type %s is currently not supported." % op_type + ) return (model, False) diff --git a/src/finn/transformation/fpgadataflow/insert_dwc.py b/src/finn/transformation/fpgadataflow/insert_dwc.py index 7121434dedef428cbd20c324d39193469e9b1a04..3fe60292e8f54a8cdf394b5e09f8a3d2bca7605c 100644 --- a/src/finn/transformation/fpgadataflow/insert_dwc.py +++ b/src/finn/transformation/fpgadataflow/insert_dwc.py @@ -3,7 +3,7 @@ from onnx import helper as oh from finn.custom_op.registry import getCustomOp from finn.transformation import Transformation -from finn.util.basic import get_by_name +from finn.util.fpgadataflow import is_fpgadataflow_node def _is_dwc_node(node): @@ -13,21 +13,9 @@ def _is_dwc_node(node): return False -def _is_fpgadataflow_node(node): - if node.domain == "finn": - n_backend = get_by_name(node.attribute, "backend") - if n_backend is None: - return False - backend_value = n_backend.s.decode("UTF-8") - if backend_value == "fpgadataflow": - return True - else: - return False - - def _suitable_node(node): if node is not None: - if _is_fpgadataflow_node(node) is True: + if is_fpgadataflow_node(node) is True: if _is_dwc_node(node) is False: return True else: diff --git a/src/finn/transformation/fpgadataflow/replace_verilog_relpaths.py b/src/finn/transformation/fpgadataflow/replace_verilog_relpaths.py index dce62c20b99097feee7208cbf57aa8921ddb3566..e63ae4e0203188d9664f432f75e36994e8a71ac5 100644 --- a/src/finn/transformation/fpgadataflow/replace_verilog_relpaths.py +++ b/src/finn/transformation/fpgadataflow/replace_verilog_relpaths.py @@ -29,7 +29,7 @@ import os import finn.custom_op.registry as registry -import finn.util.basic as util +from finn.util.fpgadataflow import is_fpgadataflow_node from finn.transformation import Transformation @@ -42,32 +42,27 @@ class ReplaceVerilogRelPaths(Transformation): def apply(self, model): for node in model.graph.node: op_type = node.op_type - if node.domain == "finn": - backend_attribute = util.get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - try: - # lookup op_type in registry of CustomOps - inst = registry.custom_op[op_type](node) - # find the IP gen dir - ipgen_path = inst.get_nodeattr("ipgen_path") - if ipgen_path is not None and os.path.isdir(ipgen_path): - for dname, dirs, files in os.walk(ipgen_path): - for fname in files: - if fname.endswith(".v"): - fpath = os.path.join(dname, fname) - with open(fpath, "r") as f: - s = f.read() - old = '$readmemh(".' - new = '$readmemh("%s' % dname - s = s.replace(old, new) - old = '"./' - new = '"%s/' % dname - s = s.replace(old, new) - with open(fpath, "w") as f: - f.write(s) - except KeyError: - pass + if is_fpgadataflow_node(node) is True: + try: + # lookup op_type in registry of CustomOps + inst = registry.custom_op[op_type](node) + # find the IP gen dir + ipgen_path = inst.get_nodeattr("ipgen_path") + if ipgen_path is not None and os.path.isdir(ipgen_path): + for dname, dirs, files in os.walk(ipgen_path): + for fname in files: + if fname.endswith(".v"): + fpath = os.path.join(dname, fname) + with open(fpath, "r") as f: + s = f.read() + old = '$readmemh(".' + new = '$readmemh("%s' % dname + s = s.replace(old, new) + old = '"./' + new = '"%s/' % dname + s = s.replace(old, new) + with open(fpath, "w") as f: + f.write(s) + except KeyError: + pass return (model, False) diff --git a/src/finn/transformation/fpgadataflow/set_exec_mode.py b/src/finn/transformation/fpgadataflow/set_exec_mode.py index 1f9c4c42189950e456da2dda77dee98fda49d522..83dda7ceccfd26fa1c43ab517ade2e19ccae4a61 100644 --- a/src/finn/transformation/fpgadataflow/set_exec_mode.py +++ b/src/finn/transformation/fpgadataflow/set_exec_mode.py @@ -27,7 +27,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import finn.custom_op.registry as registry -import finn.util.basic as util +from finn.util.fpgadataflow import is_fpgadataflow_node from finn.transformation import Transformation @@ -42,25 +42,20 @@ class SetExecMode(Transformation): def apply(self, model): for node in model.graph.node: op_type = node.op_type - if node.domain == "finn": - backend_attribute = util.get_by_name(node.attribute, "backend") - if backend_attribute is None: - continue - backend_value = backend_attribute.s.decode("UTF-8") - if backend_value == "fpgadataflow": - try: - # lookup op_type in registry of CustomOps - inst = registry.custom_op[op_type](node) - # set sim_mode accordingly to argument mode - inst.set_nodeattr("exec_mode", self.mode) - # ensure that sim_mode is now set - assert ( - inst.get_nodeattr("exec_mode") != "" - ), """Transformation + if is_fpgadataflow_node(node) is True: + try: + # lookup op_type in registry of CustomOps + inst = registry.custom_op[op_type](node) + # set sim_mode accordingly to argument mode + inst.set_nodeattr("exec_mode", self.mode) + # ensure that sim_mode is now set + assert ( + inst.get_nodeattr("exec_mode") != "" + ), """Transformation was not successful. Node attribute "exec_mode" is not set""" - except KeyError: - # exception if op_type is not supported - raise Exception( - "Custom op_type %s is currently not supported." % op_type - ) + except KeyError: + # exception if op_type is not supported + raise Exception( + "Custom op_type %s is currently not supported." % op_type + ) return (model, False)