Skip to content

Commit

Permalink
[RTL Thresholding] UPdate code generation to allow for independent in…
Browse files Browse the repository at this point in the history
…put and threshold values
  • Loading branch information
auphelia committed May 15, 2024
1 parent deb07a5 commit 460c70d
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ module $MODULE_NAME_AXI_WRAPPER$ #(
//- AXI Stream - Input --------------
output in0_V_TREADY,
input in0_V_TVALID,
input [((PE*K+7)/8)*8-1:0] in0_V_TDATA,
input [((PE*WI+7)/8)*8-1:0] in0_V_TDATA,

//- AXI Stream - Output -------------
input out_V_TREADY,
Expand Down
11 changes: 6 additions & 5 deletions src/finn/custom_op/fpgadataflow/rtl/thresholding_rtl.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,15 @@ def prepare_codegen_rtl_values(self, model):
# Additionally, increase number of threshold steps to reflect new shape
expected_thresholds = 2**o_bitwidth - 1
n_thres_steps = self.get_nodeattr("numSteps")
wdt = self.get_weight_datatype()
if expected_thresholds != n_thres_steps:
min_val = DataType[input_data_type].min()
min_val = wdt.min()
thresholds = np.insert(thresholds, 0, min_val, axis=1)
bias = bias - 1
n_thres_steps += 1

# add dummy dimension as final dimension (that's what gets packed with next call)
t_expand = np.expand_dims(thresholds, axis=-1)
wdt = self.get_weight_datatype()
bw_hexdigit = roundup_to_integer_multiple(wdt.bitwidth(), 4)
t_packed = pack_innermost_dim_as_hex_string(
t_expand,
Expand Down Expand Up @@ -242,9 +242,10 @@ def prepare_codegen_rtl_values(self, model):
i_bitwidth = DataType[input_data_type].bitwidth()

code_gen_dict["$N$"] = [str(o_bitwidth)] # output precision - convert bitwidth to string
code_gen_dict["$M$"] = [
str(i_bitwidth)
] # input/threshold precision - convert bitwidth to string
code_gen_dict["$WT$"] = [
str(wdt.bitwidth())
] # threshold precision - convert bitwidth to string
code_gen_dict["$WI$"] = [str(i_bitwidth)] # input precision - convert bitwidth to string
code_gen_dict["$C$"] = [str(num_channels)] # number of channels
code_gen_dict["$BIAS$"] = [str(bias)] # activation bias value
code_gen_dict["$PE$"] = [str(pe)] # requires C = M*PE
Expand Down
10 changes: 8 additions & 2 deletions src/finn/transformation/fpgadataflow/convert_to_hw_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,16 @@ def apply(self, model):
thl_in_shape = model.get_tensor_shape(thl_input)
thl_thres_shape = model.get_tensor_shape(thl_threshold)
idt = model.get_tensor_datatype(thl_input)

tdt = model.get_tensor_datatype(thl_threshold)
# skip conversion for layers with float input
if not idt.is_integer():
continue
assert tdt.is_integer(), (
node.name
+ """: MultiThreshold cannot be converted
because thresholds are float type. Input data type is integer,
please run RoundAndClipThresholds to convert thresholds to integer."""
)

# check layout of inputs/outputs, and convert if needed
# check layout and convert if necessary
Expand Down Expand Up @@ -253,7 +259,7 @@ def apply(self, model):
PE=pe,
numSteps=thl_thres_shape[1],
inputDataType=idt.name,
weightDataType=idt.name,
weightDataType=tdt.name,
outputDataType=odt.name,
numInputVectors=list(thl_in_shape[:-1]),
ActVal=actval,
Expand Down
25 changes: 18 additions & 7 deletions tests/fpgadataflow/test_fpgadataflow_thresholding.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@


def generate_random_threshold_values(
input_data_type, num_input_channels, num_steps, narrow=False, per_tensor=False
data_type, num_input_channels, num_steps, narrow=False, per_tensor=False
):
if per_tensor:
num_input_channels = 1
if narrow:
num_steps -= 1

return np.random.randint(
input_data_type.min(),
input_data_type.max() + 1,
data_type.min(),
data_type.max() + 1,
(num_input_channels, num_steps),
).astype(np.float32)

Expand All @@ -76,6 +76,7 @@ def sort_thresholds_increasing(thresholds):
def make_single_multithresholding_modelwrapper(
thresholds,
input_data_type,
threshold_data_type,
output_data_type,
activation_bias,
num_input_vecs,
Expand Down Expand Up @@ -115,7 +116,7 @@ def make_single_multithresholding_modelwrapper(
model.set_tensor_datatype("inp", input_data_type)
model.set_tensor_datatype("outp", output_data_type)

model.set_tensor_datatype("thresh", input_data_type)
model.set_tensor_datatype("thresh", threshold_data_type)
model.set_initializer("thresh", thresholds)
return model

Expand All @@ -129,7 +130,15 @@ def make_single_multithresholding_modelwrapper(
],
)
@pytest.mark.parametrize("activation", [DataType["INT4"], DataType["BIPOLAR"]])
@pytest.mark.parametrize("input_data_type", [DataType["INT8"], DataType["UINT8"]])
@pytest.mark.parametrize(
"idt_tdt_cfg",
[
(DataType["INT8"], DataType["INT8"]),
(DataType["INT8"], DataType["INT9"]),
(DataType["UINT8"], DataType["UINT8"]),
(DataType["UINT8"], DataType["UINT9"]),
],
)
@pytest.mark.parametrize("fold", [-1, 1, 2])
@pytest.mark.parametrize("narrow", [True, False])
@pytest.mark.parametrize("per_tensor", [True, False])
Expand All @@ -143,7 +152,7 @@ def test_fpgadataflow_thresholding(
num_input_channels,
num_input_vecs,
activation,
input_data_type,
idt_tdt_cfg,
fold,
narrow,
per_tensor,
Expand All @@ -161,6 +170,7 @@ def test_fpgadataflow_thresholding(
)
if narrow and activation == DataType["BIPOLAR"]:
pytest.skip("Narrow needs to be false with biploar activation.")
input_data_type, threshold_data_type = idt_tdt_cfg
num_steps = activation.get_num_possible_values() - 1

if fold == -1:
Expand All @@ -179,7 +189,7 @@ def test_fpgadataflow_thresholding(

# Generate random thresholds and sort in ascending order
thresholds = generate_random_threshold_values(
input_data_type, num_input_channels, num_steps, narrow, per_tensor
threshold_data_type, num_input_channels, num_steps, narrow, per_tensor
)

# provide non-decreasing/ascending thresholds
Expand All @@ -189,6 +199,7 @@ def test_fpgadataflow_thresholding(
model = make_single_multithresholding_modelwrapper(
thresholds,
input_data_type,
threshold_data_type,
output_data_type,
activation_bias,
num_input_vecs,
Expand Down

0 comments on commit 460c70d

Please sign in to comment.