Skip to content
Snippets Groups Projects
Commit 5695a7d6 authored by Yaman Umuroglu's avatar Yaman Umuroglu
Browse files

[ResUtil] improve nested SDP reporting

parent bea93338
No related branches found
No related tags found
No related merge requests found
......@@ -55,36 +55,35 @@ def post_synth_res(model, override_synth_report_filename=None):
raise Exception("Please run synthesis first")
for node in model.graph.node:
if _is_fpgadataflow_node(node):
if node.op_type == "StreamingDataflowPartition":
sdp_model = ModelWrapper(getCustomOp(node).get_nodeattr("model"))
sdp_res_dict = post_synth_res(sdp_model, synth_report_filename)
res_dict.update(sdp_res_dict)
else:
row = root.findall(".//*[@contents='%s']/.." % node.name)
if row != []:
node_dict = {}
row = row[0].getchildren()
""" Expected XML structure:
<tablerow class="" suppressoutput="0" wordwrap="0">
<tableheader class="" contents="Instance" halign="3" width="-1"/>
<tableheader class="" contents="Module" halign="3" width="-1"/>
<tableheader class="" contents="Total LUTs" halign="3" width="-1"/>
<tableheader class="" contents="Logic LUTs" halign="3" width="-1"/>
<tableheader class="" contents="LUTRAMs" halign="3" width="-1"/>
<tableheader class="" contents="SRLs" halign="3" width="-1"/>
<tableheader class="" contents="FFs" halign="3" width="-1"/>
<tableheader class="" contents="RAMB36" halign="3" width="-1"/>
<tableheader class="" contents="RAMB18" halign="3" width="-1"/>
<tableheader class="" contents="DSP48 Blocks" halign="3" width="-1"/>
</tablerow>
"""
node_dict["LUT"] = int(row[2].attrib["contents"])
node_dict["SRL"] = int(row[5].attrib["contents"])
node_dict["FF"] = int(row[6].attrib["contents"])
node_dict["BRAM_36K"] = int(row[7].attrib["contents"])
node_dict["BRAM_18K"] = int(row[8].attrib["contents"])
node_dict["DSP48"] = int(row[9].attrib["contents"])
res_dict[node.name] = node_dict
if node.op_type == "StreamingDataflowPartition":
sdp_model = ModelWrapper(getCustomOp(node).get_nodeattr("model"))
sdp_res_dict = post_synth_res(sdp_model, synth_report_filename)
res_dict.update(sdp_res_dict)
elif _is_fpgadataflow_node(node):
row = root.findall(".//*[@contents='%s']/.." % node.name)
if row != []:
node_dict = {}
row = row[0].getchildren()
""" Expected XML structure:
<tablerow class="" suppressoutput="0" wordwrap="0">
<tableheader class="" contents="Instance" halign="3" width="-1"/>
<tableheader class="" contents="Module" halign="3" width="-1"/>
<tableheader class="" contents="Total LUTs" halign="3" width="-1"/>
<tableheader class="" contents="Logic LUTs" halign="3" width="-1"/>
<tableheader class="" contents="LUTRAMs" halign="3" width="-1"/>
<tableheader class="" contents="SRLs" halign="3" width="-1"/>
<tableheader class="" contents="FFs" halign="3" width="-1"/>
<tableheader class="" contents="RAMB36" halign="3" width="-1"/>
<tableheader class="" contents="RAMB18" halign="3" width="-1"/>
<tableheader class="" contents="DSP48 Blocks" halign="3" width="-1"/>
</tablerow>
"""
node_dict["LUT"] = int(row[2].attrib["contents"])
node_dict["SRL"] = int(row[5].attrib["contents"])
node_dict["FF"] = int(row[6].attrib["contents"])
node_dict["BRAM_36K"] = int(row[7].attrib["contents"])
node_dict["BRAM_18K"] = int(row[8].attrib["contents"])
node_dict["DSP48"] = int(row[9].attrib["contents"])
res_dict[node.name] = node_dict
return res_dict
......@@ -36,7 +36,12 @@ class StreamingDataflowPartition(CustomOp):
bitfile by itself."""
def get_nodeattr_types(self):
return {"model": ("s", True, "")}
return {
"model": ("s", True, ""),
"res_estimate": ("s", False, ""),
"res_hls": ("s", False, ""),
"res_synth": ("s", False, ""),
}
def make_shape_compatible_op(self, model):
pass
......
......@@ -66,26 +66,25 @@ class AnnotateResources(Transformation):
children_dict = {}
# annotate node resources
for node in graph.node:
if _is_fpgadataflow_node(node):
if node.name in self.res_dict.keys():
op_inst = registry.getCustomOp(node)
op_inst.set_nodeattr(
"res_" + self.mode, str(self.res_dict[node.name])
)
children_dict[node.name] = self.res_dict[node.name]
elif node.op_type == "StreamingDataflowPartition":
# recurse into model to manually annotate per-layer resources
sdp_model_filename = getCustomOp(node).get_nodeattr("model")
sdp_model = ModelWrapper(sdp_model_filename)
sdp_model = sdp_model.transform(
AnnotateResources(self.mode, self.res_dict)
)
sdp_dict = sdp_model.get_metadata_prop("res_total_" + self.mode)
# save transformed model
sdp_model.save(sdp_model_filename)
# set res attribute for sdp node
getCustomOp(node).set_nodeattr("res_" + self.mode, str(sdp_dict))
children_dict[node.name] = sdp_dict
if _is_fpgadataflow_node(node) and node.name in self.res_dict.keys():
op_inst = registry.getCustomOp(node)
op_inst.set_nodeattr("res_" + self.mode, str(self.res_dict[node.name]))
children_dict[node.name] = self.res_dict[node.name]
elif node.op_type == "StreamingDataflowPartition":
# recurse into model to manually annotate per-layer resources
sdp_model_filename = getCustomOp(node).get_nodeattr("model")
sdp_model = ModelWrapper(sdp_model_filename)
sdp_model = sdp_model.transform(
AnnotateResources(self.mode, self.res_dict)
)
sdp_dict = sdp_model.get_metadata_prop("res_total_" + self.mode)
sdp_dict = eval(sdp_dict)
# save transformed model
sdp_model.save(sdp_model_filename)
# set res attribute for sdp node
getCustomOp(node).set_nodeattr("res_" + self.mode, str(sdp_dict))
children_dict[node.name] = sdp_dict
self.res_dict.update(children_dict)
total_dict = {}
for lname in children_dict.keys():
layer_res_dict = self.res_dict[lname]
......
......@@ -125,6 +125,7 @@ class CreateDataflowPartition(Transformation):
[df_out],
# use the model attribute to mark the df model
model=df_model_filename,
domain="finn",
)
non_df_model.graph.node.insert(df_start_ind, df_node)
model = non_df_model
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment