XLS backend#1475
Conversation
… pass, merge of dense_relu written as an opt pass
This fixes two test cases in test_softmax.py (one of them still fails due to another error) TODO: check layer.class_name == 'Input' instead of taking layers[0]?
This fixes DSLX compilation error in test_softmax.py
# Conflicts: # docs/requirements.txt # hls4ml/backends/__init__.py # hls4ml/model/graph.py # hls4ml/report/__init__.py # test/pytest/test_activations.py # test/pytest/test_keras_api.py # test/pytest/test_softmax.py
These things were removed in fastmachinelearning#1321
See fastmachinelearning#1443 Setting 'strategy' for Softmax layer did not affect anything, and the code always chose the default implementation=stable. TODO: all backends fail when implementation=latency (low accuracy, probably due to overflow).
… speed up tests. This should fix timeout failure on CI: https://gitlab.cern.ch/fastmachinelearning/hls4ml/-/jobs/75309630 Note that XLS tests can be slow due to big (fully unrolled) IR size.
This fixes test failure introduced by b689c7b (fix for fastmachinelearning#1443), see e.g. https://gitlab.cern.ch/fastmachinelearning/hls4ml/-/jobs/75627941
Now each XLS test case takes less than 2 minutes on my machine. All XLS tests take ~1hr. Previously, some test cases could take more than 30 minutes. Note that XLS tests are slower than C++ due to big (fully unrolled) IR size.
|
I reduced XLS dimensions in many tests to make them fast enough, but the test https://gitlab.cern.ch/fastmachinelearning/hls4ml/-/jobs/75768174 failed due to 2hr timeout. That's surprising - on my laptop, |
|
This timeout looks like CI issue, not something real in the code. |
|
If it is not doing synthesis (and it seems that it skips that path), what does it do that takes a long time? |
I feel like that the slowness is not due to the tests themselves, more likely the runner itself stalls on random tests one in a while... https://gitlab.cern.ch/fastmachinelearning/hls4ml/-/jobs/75680057 |
|
Hmm, seems that all tests always run only on -05, other nodes are never used. Gitlab reports them as "stale". Turns out they are not configured right, always reporting as -05, but only the real -05 is used. I've reconfigured 06 and 08 to be separate, they are in the pool now. Sadly 07 doesn't respond, will need to ping an openlab admin to configure that one. Hopefully then it will be a bit less crowded and tests will run faster |
There was a problem hiding this comment.
Pull request overview
Adds an experimental Google XLS backend to hls4ml, enabling generation of (System)Verilog from hls4ml models via DSLX → XLS IR → optimized IR → codegen, and integrates it into docs, packaging extras, CI, and the pytest backend matrix.
Changes:
- Introduces new
XLSBackendandXLSWriter, plus XLS-specific optimizer passes and IR/JIT-based simulation support. - Adds an XLS template firmware tree (
templates/xls/**) implementing core nnet utilities in DSLX and Vivado build scripts. - Extends tests/CI and documentation to include the new backend and optional dependency group (
hls4ml[xls]).
Reviewed changes
Copilot reviewed 52 out of 54 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| test/pytest/test_softmax.py | Adds XLS to backend matrix; updates softmax implementation selection and data generation |
| test/pytest/test_sepconv2d.py | Adds XLS case and reduces dimensions for XLS runtime |
| test/pytest/test_sepconv1d.py | Adds XLS case |
| test/pytest/test_reshape.py | Adds XLS backend + io_parallel-only skip |
| test/pytest/test_pytorch_api.py | Adds XLS backend + io_parallel-only skips (notes failing squeeze case) |
| test/pytest/test_pooling.py | Adds XLS backend; reduces dimensions for XLS runtime |
| test/pytest/test_pointwiseconv.py | Adds XLS backend; reduces dimensions for XLS runtime |
| test/pytest/test_multi_dense.py | Adds XLS backend + io_parallel-only skip |
| test/pytest/test_merge.py | Adds XLS backend + io_parallel-only skips across merge ops |
| test/pytest/test_keras_v3_api.py | Adds XLS backend; reduces dimensions for XLS runtime |
| test/pytest/test_keras_api.py | Adds XLS backend; reduces dimensions for XLS runtime |
| test/pytest/test_depthconv2d.py | Adds XLS case |
| test/pytest/test_depthconv1d.py | Adds XLS case |
| test/pytest/test_causalpadding.py | Adds XLS backend + io_parallel-only skip |
| test/pytest/test_binary_cnn.py | Adds XLS case and reduces dimensions for XLS runtime |
| test/pytest/test_auto_precision.py | Adds XLS backend; backend-dependent shapes/fixtures to reduce XLS runtime |
| test/pytest/test_activations.py | Adds XLS backend + io_parallel-only skip; XLS-specific LUT sizing tweak |
| test/pytest/synthesis_helpers.py | Skips synthesis for XLS backend |
| test/pytest/ci-template.yml | Adds xls extra deps to CI environments |
| pyproject.toml | Adds optional-dependencies.xls (xls-python) |
| hls4ml/writer/xls_writer.py | New writer to emit DSLX project and copy XLS templates |
| hls4ml/writer/init.py | Registers XLSWriter |
| hls4ml/templates/xls/firmware/nnet_utils/transpose.x | New DSLX transpose utilities |
| hls4ml/templates/xls/firmware/nnet_utils/reshape.x | New DSLX reshape utilities |
| hls4ml/templates/xls/firmware/nnet_utils/merge.x | New DSLX merge/concat/dot utilities |
| hls4ml/templates/xls/firmware/nnet_utils/lookup_table.x | New DSLX lookup table implementation |
| hls4ml/templates/xls/firmware/nnet_utils/depthwise_conv.x | New DSLX depthwise conv utilities |
| hls4ml/templates/xls/firmware/nnet_utils/dense.x | New DSLX dense utilities |
| hls4ml/templates/xls/firmware/nnet_utils/data_format.x | New DSLX data-format helpers |
| hls4ml/templates/xls/firmware/nnet_utils/conv1d.x | New DSLX conv1d utilities |
| hls4ml/templates/xls/firmware/nnet_utils/batchnorm.x | New DSLX batchnorm utilities |
| hls4ml/templates/xls/firmware/nnet_utils/activations.x | New DSLX activations/softmax utilities |
| hls4ml/templates/xls/firmware/myproject.x | New top-level DSLX template |
| hls4ml/templates/xls/firmware/layer.x | New per-layer DSLX template |
| hls4ml/templates/xls/constraints.xdc | New Vivado constraints template |
| hls4ml/templates/xls/build_prj.tcl | New Vivado build script for XLS-generated SV |
| hls4ml/report/xls_report.py | New Vivado utilization report parser for XLS builds |
| hls4ml/report/init.py | Exposes parse_xls_report |
| hls4ml/model/graph.py | Adds backend hook for custom top-function retrieval |
| hls4ml/backends/xls/xls_types.py | New XLS/DSLX type/value helpers and LUT builder helpers |
| hls4ml/backends/xls/xls_backend.py | New XLS backend: flows, DSLX→IR compile, JIT predict hook, SV codegen + Vivado build |
| hls4ml/backends/xls/passes/build_tables.py | New XLS optimizer pass to generate LUTs |
| hls4ml/backends/xls/passes/build_attr.py | New XLS optimizer pass to build writer-facing layer attrs |
| hls4ml/backends/xls/init.py | Initializes XLS backend package |
| hls4ml/backends/init.py | Registers XLSBackend |
| docs/intro/status.rst | Lists XLS as experimental backend in support matrix |
| docs/intro/setup.rst | Documents pip install hls4ml[xls] |
| docs/index.rst | Adds XLS backend docs page to toctree |
| docs/backend/xls.rst | New XLS backend documentation page |
| .gitignore | Ignores .idea/ |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| # Only signed types are supported in XLS | ||
| if not fixed_precision.signed: | ||
| if not allow_unsigned: | ||
| raise ValueError(f'Expected signed precision, got: {precision}') |
There was a problem hiding this comment.
Looks like bit exactness issue when data is defined as unsigned type? Consider warn instead of raise since it is a bit-exactness compromise instead of something unrecoverable.
There was a problem hiding this comment.
Currently we don't have a warning/error for constants like weights and biases (allow_unsigned = True).
But we throw an error (which should be a warning, as you suggest) e.g. when input/output variable type is unsigned.
@jmitrevs noted that we could even skip all warnings and simply mention in the docs that all unsigned types are converted to signed.
In that case, I could simplify the code a bit by removing the allow_unsigned parameter (21 usage) .
What do you think? Are such warnings helpful?
| self.binary_exponent = binary_exponent | ||
|
|
||
| @classmethod | ||
| def from_precision(cls, precision: PrecisionType, allow_unsigned: bool = False): |
There was a problem hiding this comment.
Why do you need a new precision type here? The ${BACKEND}WhateverType in other backends are converted by metaclass to add write method, but this one seems to be a plain thin wrapper?
There was a problem hiding this comment.
The class XLSFixedPointType and its __str__() method plays a role similar to ACFixedPrecisionDefinition and its cpp_definition() method.
I could try and refactor the code to make it similar to *Definition / *Converter / TransformTypes logic used in other backends.
…vado after that. XLS backend should not have anything vendor-specific. It is up to user to choose the tools for the next stages (RTL -> IP conversion). Removed all Vivado references from XLS, leaving only build_prj.tcl (Vivado script) as an example.
…loats use quantizers.get_fixed_quantizer_np()
# Conflicts: # pyproject.toml # test/pytest/ci-template.yml
Description
This PR adds XLS backend. It is based on PR #1343, with most of the code rewritten and new features added.
Google XLS is an open-source (Apache 2) High Level Syntesis toolchain that produces an RTL (Verilog or SystemVerilog) design from a high-level description (DSLX or C++).
Adding XLS as a new hls4ml backend allows to generate RTL without vendor-specific dependencies and benefit from the developments that XLS brings to HLS field.
XLS workflow
XLS backend performs the following transformations:
write(): hls4ml representation -> DSLX projectcompile(): DSLX -> XLS IR -> Optimized XLS IRbuild(): Optimized XLS IR -> (System)Verilog -> IPDSLX -> IR -> (System)Verilog conversion is done by XLS.
IP is generated by Vivado. One can choose another vendor and generate IP from Verilog file manually.
XLS features
XLS backend supports the following layers:
Input,ApplyAlpha,BatchNormalization,Dense,Conv1D,DepthwiseConv1D,Conv2D,DepthwiseConv2D,Pooling1D,Pooling2D,GlobalPooling1D,GlobalPooling2D,Merge,Concatenate,Dot,Activation,HardActivation,ParametrizedActivation,PReLU,Reshape,Softmax,Transpose,TernaryTanh.You can override default codegen options as follows:
DSLX standard library has only signed FixedPoint type (similar to
ap_fixed). Thus, unsigned types are not supported.Currently, XLS backend implements only
IOType: io_parallel.Strategyis ignored.All operations are fully unrolled.
io_streamcould be implemented via DSLX procs. @calad0i and I are going to work on that after finishing this PR.Other changes
I made some minor changes in non-XLS code:
test_softmax.pydoes not testargmaxandlatencyimplementations;latencyfails #1443, since it was needed to test all softmax implementations in XLS.ModelGraphto call custombackend.get_top_function(). This is needed for XLS because it uses optimized XLS IR file instead of.solibrary generated by other backends.docs/ir/attributes.rst. Aside from adding XLS, this commit some other missing layers and attributes.Dependencies
XLS backend uses xls-python to access XLS API. It is enabled by dependency group
xls:xls-pythoncomes with batteries (libxls.soand DSLX standard library) included, no separate XLS installation is required.The code has been tested for the version
xls-python=0.1.9875.Known issues
XLS doesn't work with
Denselayer imported from PyTorchLinearlayer because of shape mismatch: PyTorch storesLinearweights as(out_features, in_features), while hls4mlDenselayers use the Keras-style layout(in_features, out_features).Repro: add XLS backend to test_pytorch_api.py/test_squeeze and run the test.
Note that the weights in this test are constant, and other backends flatten them without checking shape.
So, it is unclear whether they handle this situation correctly or not.
Type of change
Tests
XLS has been added to the following tests:
test_activations.py,test_auto_precision.py,test_binary_cnn.py,test_causalpadding.py,test_depthconv1d.py,test_depthconv2d.py,test_keras_api.py,test_keras_v3_api.py,test_merge.py,test_multi_dense.py,test_pointwiseconv.py,test_pooling.py,test_pytorch_api.py,test_reshape.py,test_sepconv1d.py,test_sepconv2d.py,test_softmax.py.Test Configuration
Add
xlsdependency, e.g.and run tests, e.g.:
Notes on performance
Some test cases are very slow for XLS (e.g. ~30 minutes vs ~10 seconds on other backends).
This happens because XLS generates (in
model.compile()) and uses (inmodel.predict()) an optimized XLS IR code, where all loops are fully unrolled. The resulting file can be huge and thus slow for the likes ofConv2D.During development, I made test faster by reducing dimensions in some tests.
For example, in test_keras_api.py/test_conv2d I replaced
with
I haven't pushed such changes, but that could be one of the ways of speeding things up.
UPD: I reduced XLS dimensions in many tests, see 8578a62 and 75a04fb.
Checklist
pre-commiton the files I edited or added.