Skip to content

[tmva][sofie] Extend ONNX operator and type support, fix two codegen bugs, speed up Reduce and TopK - #23331

Merged
guitargeek merged 6 commits into
root-project:masterfrom
GiacomoXT:sofie-onnx-gnn-support
Sep 10, 2026
Merged

[tmva][sofie] Extend ONNX operator and type support, fix two codegen bugs, speed up Reduce and TopK#23331
guitargeek merged 6 commits into
root-project:masterfrom
GiacomoXT:sofie-onnx-gnn-support

Conversation

@GiacomoXT

@GiacomoXT GiacomoXT commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

This Pull request:

Extend ONNX operator and type support, fix two codegen bugs, speed up Reduce and TopK

Changes or fixes:

Adds the ONNX support needed to convert a GNN track finder with a dynamic input dimension, fixes two code-generation bugs found along the way, and speeds up the two operators that dominate its runtime. Full description, measurements and a public reproducer are in the linked issue.

  1. Missing supportReduceMax/ReduceMin; Elu on a parametric dimension; TopK with K from a shape tensor rather than an initializer; Min/Max/Sum/Mean folding to a shape tensor, as BasicBinary already did.
  2. Type support — the n-ary operators were instantiated for float only, so an INT64 Min could not be converted. Adds DOUBLE, INT32, INT64.
  3. CorrectnessReduce emitted unparenthesised strides, so a reduction over an interior axis generated wrong index arithmetic. This affects the already-supported ReduceMean and ReduceSum whenever shapes are dynamic. TopK with sorted=0 ignored largest and returned the K smallest.
  4. Performance — output is bit-identical, verified byte-for-byte against the previous generated code. Reduce over an interior axis no longer does two integer divisions per element (66% → 18% of my model's runtime); TopK selects with nth_element instead of partial_sort and packs (value, index) into one uint64 for float tensors.

All the modifications were done by Claude (Opus 5). I tested everything against my original ONNX model and did not observe difference in terms of numerical performance. More details are in the linked issue or here.

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

This PR fixes #23308

…olic TopK K

Adds the ONNX operators and shape handling needed to convert a GNN model
with a dynamic input dimension:

- ReduceMax and ReduceMin, on all three reduction paths
- Elu on tensors with a parametric dimension (Dim shapes, as in Relu)
- TopK with K taken from a shape tensor, not only an initializer
- Min/Max/Sum/Mean fold to a shape tensor when all inputs are rank <= 1
  INT64 and known at initialization, as BasicBinary already did

Assisted-by: ClaudeCode:claude-opus-5
The parser instantiated the n-ary operators for float only and threw for
anything else, so an INT64 Min could not be converted. Adds DOUBLE, INT32
and INT64, and makes the Mean trait generic, since it was specialised for
float and the integer instantiations would not have compiled. Error
messages now name the operator instead of always saying "Max".

Assisted-by: ClaudeCode:claude-opus-5
… sorted=0

Reduce emitted the strides unparenthesised, so for a reduction over an
interior axis "i / 126*std::min(a,b) % (...)" parses as
"((i / 126) * min) % (...)". The index arithmetic is then wrong and the
output is garbage. This affects ReduceMean and ReduceSum too, whenever the
shape expressions are not single tokens, i.e. for dynamic shapes.

TopK with sorted=0 called std::partial_sort without a comparator, so the
default ascending order on std::pair applied and largest=1 returned the K
smallest elements.

Assisted-by: ClaudeCode:claude-opus-5
All three changes leave the generated output bit-identical; they were
checked byte-for-byte against the previous generated code.

- Reduce recovered the indices with a division and a modulo per element,
  which for dynamic shapes are real integer divisions. Replaced by one
  loop per axis in memory order, so the inner loop is division-free and
  vectorises. Reduce went from 66% to 18% of a GNN model's runtime.
- TopK selects with nth_element + sort over the K selected, O(n) +
  O(K log K), instead of partial_sort's O(n log K).
- TopK packs (value, index) of a float tensor into one uint64 with an
  order-preserving key: one instruction per comparison and 8 bytes per
  element instead of 16. Other types keep the pairs.

Assisted-by: ClaudeCode:claude-opus-5
Eight models in generate_input_models.py with the matching gtest cases:

- ReduceMax, ReduceMin
- EluDynShape, for Elu on a parametric dimension
- TopKWithDynShapeK, where K = min(N, 4) reaches TopK as a shape tensor
- MinInt64, MaxInt64, for the n-ary operators on a non-float type
- ReduceMean_kMiddle_DynShape, a reduction over an interior axis whose
  strides are expressions, i.e. the case that was generated wrong
- TopKLargestUnsorted, largest=1 with sorted=0

Assisted-by: ClaudeCode:claude-opus-5
@GiacomoXT
GiacomoXT requested a review from lmoneta as a code owner September 10, 2026 12:30
@GiacomoXT

Copy link
Copy Markdown
Contributor Author

@guitargeek I opened the PR as requested. :)

@guitargeek guitargeek self-assigned this Sep 10, 2026
@guitargeek guitargeek added in:SOFIE bug AI-Assisted experiment Affects an experiment / reported by its software & computimng experts labels Sep 10, 2026

@guitargeek guitargeek left a comment

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.

LGTM! Thanks a lot for trying out SOFIE and fixing it up for your usecase!

Would it help you if we try to backport these fixes to 6.40, or you don't care about it working in the next 6.40 patch release?

@GiacomoXT

Copy link
Copy Markdown
Contributor Author

I am currently just experimenting few things, so having this in the master branch (and thus in the next nightly builds) would be sufficient!

@guitargeek
guitargeek merged commit 399cd12 into root-project:master Sep 10, 2026
30 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-Assisted bug experiment Affects an experiment / reported by its software & computimng experts in:SOFIE

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sofie] ONNX GNN model fails to convert: missing operators, dynamic-shape gaps, and two codegen bugs

2 participants