Skip to content

Softmax update - #1494

Open
bugracyln wants to merge 65 commits into
fastmachinelearning:mainfrom
bugracyln:softmax_updated
Open

Softmax update#1494
bugracyln wants to merge 65 commits into
fastmachinelearning:mainfrom
bugracyln:softmax_updated

Conversation

@bugracyln

@bugracyln bugracyln commented Jun 25, 2026

Copy link
Copy Markdown

Description

📝 Please include a summary of the change.

The softmax table generation logic was updated. The implementation for writing the softmax tables was revised, and memory attributes were added to enable a more efficient FPGA compilation flow. In addition, the templates were modified to use weights directly from the configuration.

  • Please also include relevant motivation and context.

The primary motivation for these changes was to bring the oneAPI backend closer to the Vivado backend in terms of implementation.

Memory attributes were added to enable memory banking on the FPGA, allowing for more efficient memory access. The weights are now copied directly into the configuration so that the compiler can recognise the entire table as a set of fixed values. This enables the memory to be implemented more efficiently, resulting in improved resource utilisation during FPGA compilation.

  • List any dependencies that are required for this change.

N/A

Type of change

For a new feature or function, please create an issue first to discuss it
with us before submitting a pull request.

Note: Please delete options that are not relevant.

  • Bug fix (non-breaking change that fixes an issue)
  • Documentation update
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality not to work as expected)
  • A new research paper code implementation
  • Other (Specify)

Tests

📝 Please describe the tests that you ran to verify your changes.

The changes were primarily verified using black-box tests on an isolated softmax unit. Testing was performed for both quantised and non-quantised implementations. For the quantised version, both configurations, with and without exp and inv table quantisers (QuantiserConfig(...)), were tested.

Additional testing included:

  • Generating FPGA RTL reports.
  • Building the emulator.
  • Performing a hardware compilation using the new Intel oneAPI compiler.

This PR currently supports only the Intel oneAPI compiler. Support for the Altera HLS compiler will be added in a future PR.

The implementation was also evaluated with different table sizes, and the resulting RTL reports were inspected to verify improvements in resource utilisation.

  • Provide instructions so we can reproduce.

A Python test file and a Keras model containing only a single softmax layer (Softmax or QSoftmax) were used. For the quantised implementation, the input and output quantisers for the exp and inv lookup tables were configured using QuantiserConfig(...). Tests were run with both the quantisers enabled and disabled.

The test configuration included:

  • Standard Softmax and QSoftmax models.
  • Explicit exp and inv table input output quantisation.
  • FPGA RTL generation.
  • Emulator build.
  • Hardware compilation with the Altera HLS (newer version of Intel oneAPI)compiler.
  • Please also list any relevant details for your test configuration.

Test Configuration:

Checklist

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

@jmitrevs jmitrevs added the please test Trigger testing by creating local PR branch label Jul 3, 2026
def __write_exp_table(self, model, path):
table_name = 'exp_table'
table_size = self.__get_table_size(model, 'softmax')
def __get_table_precision(self, model, activation, table_name='table_precision'):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function used?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not anymore, removed this

Comment thread hls4ml/writer/oneapi_writer.py Outdated
@jmitrevs jmitrevs added please test Trigger testing by creating local PR branch and removed please test Trigger testing by creating local PR branch labels Jul 7, 2026
Comment thread hls4ml/writer/oneapi_writer.py Outdated
real_val = f.exp_float()
h_file.write(sep + str(real_val))
sep = ', '
# Default fixed point precision

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for default here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was a redundant code from old version that i forgot to remove.

Comment thread hls4ml/writer/oneapi_writer.py Outdated
h_file.close()
# Exp table should use the same precision as exp_table, as seen in Vivado code
# init_exp_table<data_T, CONFIG_T>(exp_table);
for layer in model.get_layers():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why loop again for layers here within the loop for layers on line 824? This looks like a bug.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was from the old version that i forgot to remove, now removed the inner loop and fixed it.

Comment thread hls4ml/writer/oneapi_writer.py Outdated

h_file.write('};\n')
h_file.close()
# Exp table should use the same precision as exp_table, as seen in Vivado code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the comment, that the exp table should use the same precision as exp table. Isn't that true inherently?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also was from the previous version, irrelevant in our case

Comment thread hls4ml/writer/oneapi_writer.py Outdated
sep = ', '
# Default fixed point precision, in case values from layer attributes cannot be extracted
# 8 bits for integer part, 10 bits for decimal - total, 18
fp_bits = 18

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again I don't think you need defaults here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed them

Comment thread hls4ml/writer/oneapi_writer.py Outdated
h_file.close()
# Invert table should use the same precision as exp_table, as seen in Vivado code
# init_invert_table<typename CONFIG_T::exp_table_t, CONFIG_T>(invert_table);
for layer in model.get_layers():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And again a layer loop inside of a layer loop.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@jmitrevs jmitrevs added please test Trigger testing by creating local PR branch and removed please test Trigger testing by creating local PR branch labels Jul 23, 2026
@jmitrevs jmitrevs added please test Trigger testing by creating local PR branch and removed please test Trigger testing by creating local PR branch labels Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

please test Trigger testing by creating local PR branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants