Xilinx / finn-base

Open Source Compiler Framework using ONNX as Frontend and IR
https://finn-base.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
29 stars 17 forks source link

Add support for Bipolar and Binary FINN datatype for Quant op. #41

Closed heborras closed 3 years ago

heborras commented 3 years ago

Hi, this PR adds support for 1 bit ops, as they are used by as example the TFC W1A1 network, here: TFC_1W1A.zip

However, an issue remains with this: Since the binary and bipolar representation are currently not properly implemented in the quant node, the inference_cost function will discount all weights as being sparse, though they are not. Thus on has to pass discount_sparsity=False to get the correct number of bitops.

Previously, when running inference_cost on this network the calculation would fail with the following Exception for the TFC W1A1 network:

--------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/Dropbox/a_local/Work/Xilinx/coding/PyCharm/finn-base/src/finn/transformation/infer_datatypes.py in _infer_node_datatype(model, node)
     54             inst = registry.getCustomOp(node)
---> 55             inst.infer_node_datatype(model)
     56         except KeyError:

~/Dropbox/a_local/Work/Xilinx/coding/PyCharm/finn-base/src/finn/custom_op/general/quant.py in infer_node_datatype(self, model)
    181         try:
--> 182             (scale, zeropt, bitwidth, finn_dt) = self.get_quant_config(model)
    183         except AssertionError:

~/Dropbox/a_local/Work/Xilinx/coding/PyCharm/finn-base/src/finn/custom_op/general/quant.py in get_quant_config(self, model)
    168             if signed:
--> 169                 finn_dt = DataType["INT" + str(bitwidth)]
    170             else:

/usr/lib/python3.8/enum.py in __getitem__(cls, name)
    386     def __getitem__(cls, name):
--> 387         return cls._member_map_[name]
    388 

KeyError: 'INT1'

During handling of the above exception, another exception occurred:

Exception                                 Traceback (most recent call last)
<ipython-input-3-cc115ea19bc6> in <module>
----> 1 inference_cost(network_to_test, discount_sparsity=False)

~/Dropbox/a_local/Work/Xilinx/coding/PyCharm/finn-base/src/finn/util/inference_cost.py in inference_cost(model_filename, output_json, preprocess, save_final, discount_sparsity)
     94         model = model.transform(InferShapes())
     95         model = model.transform(GiveUniqueParameterTensors())
---> 96         model = model.transform(InferDataTypes())
     97         model = model.transform(FoldConstants())
     98         model = model.transform(RemoveUnusedTensors())

~/Dropbox/a_local/Work/Xilinx/coding/PyCharm/finn-base/src/finn/core/modelwrapper.py in transform(self, transformation, make_deepcopy, cleanup, fix_float64)
    137         model_was_changed = True
    138         while model_was_changed:
--> 139             (transformed_model, model_was_changed) = transformation.apply(
    140                 transformed_model
    141             )

~/Dropbox/a_local/Work/Xilinx/coding/PyCharm/finn-base/src/finn/transformation/infer_datatypes.py in apply(self, model)
    102         graph_modified = False
    103         for node in graph.node:
--> 104             graph_modified |= _infer_node_datatype(model, node)
    105         return (model, graph_modified)

~/Dropbox/a_local/Work/Xilinx/coding/PyCharm/finn-base/src/finn/transformation/infer_datatypes.py in _infer_node_datatype(model, node)
     56         except KeyError:
     57             # exception if op_type is not supported
---> 58             raise Exception("Custom op_type %s is currently not supported." % op_type)
     59     else:
     60         if node.op_type == "Sign":

Exception: Custom op_type Quant is currently not supported.
heborras commented 3 years ago

This commit should probably also be merged into the itu_competition branch, which is probably more important than the one it currently points at. In that branch the same issue exists.

maltanar commented 3 years ago

@HenniOVP thanks for catching this bug and submitting the PR. I think the requirement to call discount_sparsity=False is a bit disruptive (e.g. for the ITU competition), so until the Brevitas Quant op export for bipolar cases is resolved let's opt for a custom execution path inside the quantize function -- I'll push something for this and do the merge afterwards, both for the feature/qonnx_compute_cost and the itu_competition branches.