Skip to content

SetFolding rules for Split and Concat operations. #1290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/finn/transformation/fpgadataflow/set_folding.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import numpy as np
import warnings
import functools
from qonnx.custom_op.registry import getCustomOp
from qonnx.transformation.base import Transformation
from qonnx.transformation.general import GiveUniqueNodeNames
Expand All @@ -44,6 +45,15 @@ def divisors(num):
yield x


def common_divisors(numbers):
separate_divisors = []
for num in numbers:
individual_divisors = list(divisors(num))
separate_divisors.append(individual_divisors)

return functools.reduce(np.intersect1d, separate_divisors)


class SetFolding(Transformation):
"""Attempt to set parallelism attributes in all nodes to meet a specific
target expressed as cycles per frame target_cycles_per_frame. For each
Expand Down Expand Up @@ -114,9 +124,12 @@ def apply(self, model):
simd_ops = [
"DownSampler_hls",
"FMPadding_hls",
"FMPadding_rtl",
"FMPadding_Pixel_hls",
"ConvolutionInputGenerator_hls",
"ConvolutionInputGenerator_rtl",
"StreamingSplit_hls",
"StreamingConcat_hls",
]
# these ops are preceded by depthwise SWG and have special behavior,
# as explained in the SetFolding docstring
Expand Down Expand Up @@ -214,6 +227,14 @@ def apply(self, model):
else:
# depthwise SWGs are handled separately
continue
elif op_type == "StreamingConcat_hls" or op_type == "StreamingSplit_hls":
node_inst.set_nodeattr("SIMD", 1)
channels_per_stream = node_inst.get_nodeattr("ChannelsPerStream")
for simd_val in common_divisors(channels_per_stream):
node_inst.set_nodeattr("SIMD", simd_val)
cyc = node_inst.get_exp_cycles()
if cyc < self.target_cycles_per_frame:
break
else:
max_simd = node_inst.get_nodeattr("NumChannels")
self.optimize_attribute_val(node_inst, max_simd, "SIMD")
Expand Down