hls4ml icon indicating copy to clipboard operation
hls4ml copied to clipboard

Automatic precision inference

Open vloncar opened this issue 1 year ago • 5 comments

Description

This introduces the ability to specify auto as a precision string, that implies hls4ml should infer the precision in some way. This is not exposed by default via the config_from... functions for now. The goal is to have the framework for inferring types in some ways within hls4ml (e.g., QONNX parser) before fully exposing it to users. An initial inference of precision has been added via the infer_precision_types optimizer, based on previous attempts by various people. It's not advanced in any way. During testing, I encountered some issues with SeparableConv1D templates which I fixed.

Type of change

  • [x] Bug fix (non-breaking change that fixes an issue) - Only related to the SeparableConv1D issue
  • [x] New feature (non-breaking change which adds functionality)

Tests

There are new tests in test_auto_precision.py that cover the few use cases.

Checklist

  • [x] I have read the guidelines for contributing.
  • [x] I have commented my code, particularly in hard-to-understand areas.
  • [x] I have made corresponding changes to the documentation.
  • [x] My changes generate no new warnings.
  • [x] I have installed and run pre-commit on the files I edited or added.
  • [x] I have added tests that prove my fix is effective or that my feature works.

vloncar avatar Aug 20 '23 21:08 vloncar

Clang doesn't seem to like this

(fastml39) Jovans-Mac:hls4mlprj_auto_conv2d_Quartus_io_stream jmitrevs$ bash build_lib.sh 
In file included from firmware/myproject.cpp:2:
In file included from firmware/parameters.h:11:
firmware/nnet_utils/nnet_conv2d_stream.h:135:5: error: no matching function for call to 'shift_line_buffer_2d'
    nnet::shift_line_buffer_2d<data_T, CONFIG_T>(in_elem, line_buffer, shift_buffer);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
firmware/nnet_utils/nnet_conv2d_stream.h:199:13: note: in instantiation of function template specialization 'nnet::compute_output_buffer_2d<nnet::array<ac_fixed<16, 6>, 4>, nnet::array<ac_fixed<35, 15>, 4>, config8>' requested here
            compute_output_buffer_2d<data_T, res_T, CONFIG_T>(padds, res, line_buffer, kernel_window, weights, biases);
            ^
firmware/myproject.cpp:93:11: note: in instantiation of function template specialization 'nnet::conv_2d_cl<nnet::array<ac_fixed<16, 6>, 4>, nnet::array<ac_fixed<35, 15>, 4>, config8>' requested here
    nnet::conv_2d_cl<layer7_t, last_layer_result_t, config8>(layer7_out, layer8_out, w8, b8);
          ^
firmware/nnet_utils/nnet_conv2d_stream.h:69:6: note: candidate template ignored: substitution failure [with data_T = nnet::array<ac_fixed<16, 6>, 4>, CONFIG_T = config8]: zero-length arrays are not permitted in C++
void shift_line_buffer_2d(
     ^
1 error generated.
clang: error: no such file or directory: 'myproject.o'

while g++ compiles it just fine.

jmitrevs avatar Oct 11 '23 00:10 jmitrevs

The issue seems to be that this:

    model.add(Conv2D(4, kernel_size=(1, 1), activation='relu', name='last_layer'))  # Will become PointwiseConv2D

doesn't actually become PointwiseConv2D for Quartus. The bug it uncovered seems tangential to this PR; nevertheless, we need to fix it, either as part of this PR or separately.

jmitrevs avatar Oct 11 '23 03:10 jmitrevs

is this the same issue that was observed in #878?

vloncar avatar Oct 11 '23 18:10 vloncar

is this the same issue that was observed in #878?

I believe so. If you have a filter of size 1, then things like line_buffer[CONFIG_T::filt_height - 1][CONFIG_T::n_chan] wind up with zero-size arrays.

jmitrevs avatar Oct 11 '23 18:10 jmitrevs

I made vloncar #53 into your branch with changes for dense and standard convolution. Let me know what you think. If you like the way I made this, I can also add signed/unsigned support to the other precision propagations (like merge, bn, sepconv) either in that PR or a different one.

jmitrevs avatar Jan 27 '24 00:01 jmitrevs