Skip to content

[tmva][sofie] Add support for the ONNX PRelu operator - #23847

Merged
guitargeek merged 1 commit into
root-project:masterfrom
SirAlper:sofie-prelu
Nov 3, 2026
Merged

guitargeek merged 1 commit into
root-project:masterfrom
SirAlper:sofie-prelu

Conversation

@SirAlper

@SirAlper SirAlper commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

This PR adds support for the ONNX PRelu operator, which was still unchecked in the operator status list (#10360).

Implementation

slope is unidirectionally broadcast to the shape of X, as required since opset 7. Instead of expanding the slope to the size of X (which would turn e.g. a 64-element per-channel slope into a 1×64×112×112 weight tensor), the generated loop computes the slope index from the strides of X, skipping the broadcast axes. For the per-channel [C,1,1] slope exported by PyTorch's nn.PReLU(C) on a [1,3,2,2] input this gives:

tensor_Y[id] = ((tensor_X[id] >= 0 )? tensor_X[id] : tensor_Slope[(id / 4) % 3] * tensor_X[id]);

A slope with the same shape as X is indexed by id directly and a single slope by 0. A slope that cannot be broadcast to X is rejected in Initialize().

Limitations

  • Only float is supported for now.
  • Static shapes only.

Tests

  • Four model tests, with reference outputs from the ONNX reference evaluator: same shape, last-axis broadcast ([5]), per-channel ([3,1,1]) and a single slope ([1]).
  • Two parser tests: a non-broadcastable slope throws, and a per-channel slope is indexed in place instead of being expanded.
  • Locally, a Conv2d + nn.PReLU(4) model exported from PyTorch 2.14 goes through SOFIE and matches the PyTorch output exactly.

Implement ROperator_PRelu and its ONNX parser. The slope is unidirectionally
broadcast to the shape of X as required since opset 7: instead of expanding
the slope to the size of X, the generated loop computes the slope index from
the strides of X, skipping the broadcast axes, e.g. tensor_slope[(id / 4) % 3]
for a [1,3,2,2] input with the per-channel [3,1,1] slope exported by PyTorch's
nn.PReLU. A slope that cannot be broadcast to X is rejected in Initialize().
Only float is supported for now.

Add four model tests (same shape, last-axis, per-channel and single slope) and
two parser tests checking the error for a non-broadcastable slope and that a
per-channel slope is not expanded.
@github-actions

Copy link
Copy Markdown

Test Results

    24 files      24 suites   3d 22h 15m 18s ⏱️
 3 898 tests  3 898 ✅ 0 💤 0 ❌
83 460 runs  83 460 ✅ 0 💤 0 ❌

Results for commit 046c3aa.

@SirAlper

SirAlper commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Hi @lmoneta @guitargeek, gentle ping on this one: CI is green and there are no merge conflicts, so it's ready for review whenever you have time. I'm happy to make any changes you'd like. Thanks!

@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!

@guitargeek
guitargeek merged commit e87f5bc into root-project:master Nov 3, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants