-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Manually unrolled HLS #41
Conversation
Is there a particular version of XGBoost/Scikit-Learn used here? Trying out the example pruned_xgboost_to_hls.py: With XGBoost 2.0.0 I get In either case I have not been able to get pruned trees to compile. |
This is likely an issue with the XGBoost converter rather than the pruned model support. I can confirm though that this was tested with XGBoost 1.7.5. I just tried with 2.0.0 and I see the same issue as you with the XGBoost converter tests. I'm not sure about the issue you see with 1.7.6, we can look into that. It might be a corner case only in that model. I'll open a new issue about updating the XGBoost converter again for 2.0.0 |
Thanks @thesps! In the mean time can you confirm that the XGBoost converter works for pruned trees with 1.7.5? I still get For completeness I use scikit-learn==1.3.0, conifer==1.2 |
Thanks for the info, I checked that example as well and I replicated your error. I haven't worked out the fix yet but I can give some insight into the issue:
So somehow the xgboost converter has read those out of range values from the model. This is where those child indices are set: https://github.com/thesps/conifer/blob/master/conifer/converters/xgboost.py#L51-L52 I will keep investigating! |
This PR is inspired by #30.
In the main branch, the loop over ensemble trees in the HLS is like this (simplified):
Vivado/Vitis HLS seems to have a hard time unrolling this loop, for an unknown reason. In this PR we manually unroll this loop in the backend writer instead. So for a model with 5 trees this looks like (simplified):
Now we also need to create instances of each tree (
tree_0
,tree_1
etc) instead of an array of them inparameters.h
, and create one model specific function with the unrolled inference code.The impact is:
For large models (e.g. in the scan referenced below with 100 trees and depth of 8) master branch may not be able to synthesize the model while this PR can.
The old implementation with a
for
loop in the C++ is still available, with a new configuration parameter'Unroll'
made available to select between the implementations (defaults toTrue
).For reference, here are some plots from a scan of randomized trees (blue markers are
master
branch, red markers are this PR):