feat: add sparse CNN support (sparsepixels)#1468
Conversation
|
Adding how sparse CNN flows in HLS Every sparse layer operates on two parallel arrays that travel together through the network:
Keeping the hash alongside the features is what makes sparse convolution possible without materializing the full
|
# Conflicts: # hls4ml/model/optimizer/passes/bit_exact.py # pyproject.toml
…r input reduction; add maxpooling
| } | ||
|
|
||
| if (acc != 0) { | ||
| acc += b[i_filt]; |
There was a problem hiding this comment.
Just to double check: Is it correct to drop the bias if the MAC happens to sum to zero incidentally?
There was a problem hiding this comment.
Thanks for flagging this, it is an intended design choice in this first version. The sparse arrays are fixed length (n_max_pixels slots) and currently carry no explicit per-slot validity flag, so an invalid (inactive) pixel is encoded as exact zero in the feature values. With this representation, the kernel uses the non-zero acc as a guard to avoid adding bias to inactive pixels, so an inactive pixel always stays inactive in sparse convolution. The corner case you mentioned is indeed possible but is rare practically, and we have made the training library to exactly mirror the HLS side so there is no mismatch. A possible improvement on this is to add a separate validity flag per slot to guard the acc, which requires some tests and could be done in future.
There was a problem hiding this comment.
Thanks for the clarification. That's all good then.
| import numpy as np | ||
| import pytest | ||
|
|
||
| sparsepixels = pytest.importorskip('sparsepixels') |
There was a problem hiding this comment.
So I guess currently this test will never be run? I think it should be added to the keras 3 test list here https://github.com/fastmachinelearning/hls4ml/blob/main/test/pytest/generate_ci_yaml.py#L38 and add the sparsepixels package to the ones installed for these tests in https://github.com/fastmachinelearning/hls4ml/blob/main/pyproject.toml#L72
|
I think the ci pytests failed with the unrelated pquant_keras, ours has passed? |
|
Indeed, just a time-out. Test succeeded on the second try. Looks good to me, let others have a chance to chime in, otherwise I'll merge tomorrow morning. |
| try: | ||
| from hls4ml.converters.keras_v3.sparsepixels import post_process_sparse_layer_list | ||
|
|
||
| post_process_sparse_layer_list(layer_list) |
There was a problem hiding this comment.
I was hoping that this can be refactored not to be here, rather to be a separate pass later on, but didn't investigate the feasibility. What's the blocker for moving it to a "convert" flow on the parsed model?
There was a problem hiding this comment.
Now refactored that to the convert flow. Tested locally, the conversion stays the same.
Dear experts, this PR is to add feature support for sparse CNN models built from the
sparsepixelslibrary, which is the code implementation of the paper arXiv:2512.06208. Issue is opened at #<1467>. Please see below the descriptions. Thanks.Description
Add end-to-end conversion of sparse CNN models, built with the
sparsepixelsKeras package (HGQ2-based), to HLS firmware via the Vivado and Vitis backends. Sparse CNNs propagate only active pixels (those above a threshold) plus their spatial hash coordinates through the network instead of operating on the full image grid, drastically reducing FPGA latency and resource usage compared to dense convolution on naturally sparse inputs (e.g., particle detector data, neutrino events, sparse imaging).What's added:
hls4ml/model/layers.py:SparseInputReduce,SparseConv2D,SparseActivation,SparsePooling2D,SparseFlattenInputReduce,QConv2DSparse,AveragePooling2DSparse)nnet_sparsepixels.hPatch is fully self-contained. Every new pass and dispatch is gated on the new layer types via
isinstance, so no existing model conversion path is touched.Backends: Vivado, Vitis,
io_parallel. Other backends andio_streamare out of scope at the moment.Dependency: sparsepixels (optional for pytest only).
Type of change
Tests
test/pytest/test_sparsepixels.pybuilds a small sparse CNN, converts it via hls4ml, compiles, and compares HLS vs Keras outputs over random inputs on both Vivado and Vitis backends.Test Configuration:
Checklist
pre-commiton the files I edited or added.Happy to add to docs as a separate PR.