Skip to content

Commit a836e28

Browse files
author
Lukas Stasytis
committed
analytical fifo sizing
1 parent 58fa637 commit a836e28

19 files changed

Lines changed: 2823 additions & 199 deletions

run-docker.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,4 @@ else
300300
fi
301301

302302
echo $CMD_TO_RUN
303-
$CMD_TO_RUN
303+
$CMD_TO_RUN

src/finn/analysis/fpgadataflow/dataflow_performance.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from qonnx.custom_op.registry import getCustomOp
3131

32+
from finn.util.basic import decompress_string_to_numpy
3233
from finn.util.fpgadataflow import is_hls_node, is_rtl_node
3334

3435

@@ -76,3 +77,84 @@ def dataflow_performance(model):
7677
"max_cycles": int(max_cycles),
7778
"max_cycles_node_name": max_node_name,
7879
}
80+
81+
82+
def max_period(model):
83+
"""Extract maximum period among all nodes in the graph
84+
85+
Preconditions:
86+
- model consists of HLS/RTL nodes
87+
- model has cycle estimates annotated (see AnnotateCycles transformation)
88+
- nodes have unique names (see GiveUniqueNodeNames)
89+
- model has been characteristically derived and contains specific chr periods
90+
91+
Returns:
92+
- max_cycles : number of cycles for slowest node
93+
- max_cycles_node_name : name of slowest node
94+
- critical_path_cycles : pessimistic expected latency from input to output
95+
"""
96+
max_cycles = 0
97+
98+
for node in model.graph.node:
99+
if node is not None and node.op_type not in [
100+
"AddStreams_hls",
101+
"DuplicateStreams_hls",
102+
"StreamingFIFO_hls",
103+
"StreamingFIFO_rtl",
104+
]:
105+
if is_hls_node(node) or is_rtl_node(node):
106+
inst = getCustomOp(node)
107+
node_cycles_in = (
108+
len(decompress_string_to_numpy(inst.get_nodeattr("io_chrc_in"))[0]) // 2
109+
)
110+
node_cycles_out = (
111+
len(decompress_string_to_numpy(inst.get_nodeattr("io_chrc_out"))[0]) // 2
112+
)
113+
node_cycles = max(node_cycles_in, node_cycles_out)
114+
115+
if node_cycles > max_cycles:
116+
max_cycles = node_cycles
117+
118+
return {
119+
"max_cycles": int(max_cycles),
120+
}
121+
122+
123+
def max_remaining_period(model, node):
124+
"""Extract maximum period among all nodes in the graph
125+
126+
Preconditions:
127+
- model consists of HLS/RTL nodes
128+
- model has cycle estimates annotated (see AnnotateCycles transformation)
129+
- nodes have unique names (see GiveUniqueNodeNames)
130+
- model has been characteristically derived and contains specific chr periods
131+
132+
Returns:
133+
- max_cycles : number of cycles for slowest node
134+
- max_cycles_node_name : name of slowest node
135+
- critical_path_cycles : pessimistic expected latency from input to output
136+
"""
137+
max_cycles = 0
138+
node_index = list(model.graph.node).index(node)
139+
for node in model.graph.node[node_index:]:
140+
if node is not None and node.op_type not in [
141+
"AddStreams_hls",
142+
"DuplicateStreams_hls",
143+
"StreamingFIFO_hls",
144+
"StreamingFIFO_rtl",
145+
]:
146+
if is_hls_node(node) or is_rtl_node(node):
147+
inst = getCustomOp(node)
148+
node_cycles = int(inst.get_nodeattr("io_chrc_period"))
149+
node_cycles_in = (
150+
len(decompress_string_to_numpy(inst.get_nodeattr("io_chrc_in"))[0]) // 2
151+
)
152+
node_cycles_out = (
153+
len(decompress_string_to_numpy(inst.get_nodeattr("io_chrc_out"))[0]) // 2
154+
)
155+
node_cycles = max(node_cycles_in, node_cycles_out)
156+
if node_cycles > max_cycles:
157+
max_cycles = node_cycles
158+
return {
159+
"max_cycles": int(max_cycles),
160+
}

src/finn/builder/build_dataflow_config.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,30 @@
4040

4141
class AutoFIFOSizingMethod(str, Enum):
4242
"Select the type of automatic FIFO sizing strategy."
43-
44-
CHARACTERIZE = "characterize"
43+
ANALYTIC = "analytical"
4544
LARGEFIFO_RTLSIM = "largefifo_rtlsim"
4645

4746

47+
class TAVGenerationMethod(str, Enum):
48+
"Select the strategy for constructing token access vectors of an operator."
49+
RTLSIM = "rtlsim"
50+
TREE_MODEL = "tree_model"
51+
52+
53+
class TAVUtilizationMethod(str, Enum):
54+
"""Select the strategy for utilizing token access vectors of an operator
55+
for buffer sizing."""
56+
57+
# worst-case ratio of data rates between a consumer and producer
58+
CONSERVATIVE_RELAXATION = "conservative_relaxation"
59+
60+
# average-case ratio of data rates between a consumer and producer
61+
AGGRESSIVE_RELAXATION = "aggressive_relaxation"
62+
63+
# no relaxation, use the token access vectors as-is
64+
NO_RELAXATION = "no_relaxation"
65+
66+
4867
class ShellFlowType(str, Enum):
4968
"""For builds that produce a bitfile, select the shell flow that will integrate
5069
the FINN-generated accelerator."""
@@ -117,9 +136,9 @@ class VerificationStepType(str, Enum):
117136
"step_apply_folding_config",
118137
"step_minimize_bit_width",
119138
"step_generate_estimate_reports",
139+
"step_set_fifo_depths",
120140
"step_hw_codegen",
121141
"step_hw_ipgen",
122-
"step_set_fifo_depths",
123142
"step_create_stitched_ip",
124143
"step_measure_rtlsim_performance",
125144
"step_out_of_context_synthesis",
@@ -274,6 +293,26 @@ class DataflowBuildConfig:
274293
#: setting the FIFO sizes.
275294
auto_fifo_strategy: Optional[AutoFIFOSizingMethod] = AutoFIFOSizingMethod.LARGEFIFO_RTLSIM
276295

296+
#: Which strategy will be used for token access vector generation for FIFO sizing.
297+
#: RTLSIM will result in performing RTLSIM for each node
298+
#: to deduce the token access vectors empirically
299+
#: TREE_MODEL will use the tree mode of an operator if available, avoiding the generation
300+
#: of IP cores.
301+
tav_generation_strategy: Optional[TAVGenerationMethod] = TAVGenerationMethod.RTLSIM
302+
303+
#: Which strategy will be used for token access vector generation for FIFO sizing.
304+
#: RTLSIM will result in performing RTLSIM for each node
305+
#: to deduce the token access vectors empirically
306+
#: TREE_MODEL will use the tree mode of an operator if available, avoiding the generation
307+
#: of IP cores.
308+
tav_utilization_strategy: Optional[
309+
TAVUtilizationMethod
310+
] = TAVUtilizationMethod.CONSERVATIVE_RELAXATION
311+
312+
#: Avoid using C++ rtlsim for auto FIFO sizing and rtlsim throughput test
313+
#: if set to True, always using Python instead
314+
force_python_rtlsim: Optional[bool] = False
315+
277316
#: Memory resource type for large FIFOs
278317
#: Only relevant when `auto_fifo_depths = True`
279318
large_fifo_mem_style: Optional[LargeFIFOMemStyle] = LargeFIFOMemStyle.AUTO

0 commit comments

Comments
 (0)