Skip to content

fix(onnx): reduce extrema over all dimensions for empty axes - #4024

Open
hulkbig wants to merge 1 commit into
huggingface:mainfrom
hulkbig:codex/candle-empty-axes-20261005
Open

hulkbig wants to merge 1 commit into
huggingface:mainfrom
hulkbig:codex/candle-empty-axes-20261005

Conversation

@hulkbig

@hulkbig hulkbig commented Oct 5, 2026

Copy link
Copy Markdown

Fixes #4023

ReduceMax and ReduceMin currently return the input unchanged for explicitly empty axes, even with the default noop_with_empty_axes=0. For example, an opset 18 model reducing [[3, -2, 7], [4, 6, 1]] with empty axes and keepdims=0 returns a [2, 3] tensor instead of scalar 7/-2.

Treat empty axes like omitted axes before choosing the existing reduction branch. This preserves modern noop_with_empty_axes=1, keepdims, nonempty axes, duplicate-axis handling and the existing zero-size-input error. The change is limited to the two extrema branches.

Add four integration tests exercising 192 serialized ONNX model combinations through simple_eval: opset 13 axes attributes; opset 18 optional axes inputs; empty/omitted axes; positive/negative and unsorted multi-axis controls; default/0/1 keepdims and modern default/0/1 no-op. Legacy graphs do not use modern parameters. Tests check shape, values and dtype.

Validation on macOS arm64, Rust 1.94.1, protoc 33.6:

  • Unmodified evaluator: 18/192 matrix cases fail; patched evaluator: 192/192 pass.
  • Independent ONNX checker + ReferenceEvaluator: 192 models pass; patched Candle matches all 192 serialized fixture outputs.
  • Existing ONNX operation tests: 67 pass, one pre-existing GELU precision failure. The same failure occurs on unmodified main at tests/ops.rs:1919, comparing 0.8413447 and 0.8413448. A supplemental run excluding that one test passes all 67 existing tests and all four new tests, plus doc-test targets.
  • cargo test --locked -p candle-core --lib --tests: 204 pass, one ignored.
  • ONNX and core cargo build ... --all-targets: pass. ONNX and workspace format checks: pass.
  • Strict ONNX Clippy fails with the same 10 diagnostics on the baseline and patched evaluator: six generated-protobuf documentation warnings and four existing evaluator warnings (comparison_to_empty, needless_borrow, clone_on_copy, wildcard_in_or_patterns). The new regression target passes Clippy when only those five already-observed lint categories are allowed. This supplemental check is not a strict-Clippy pass.

Core strict Clippy (cargo clippy --locked -p candle-core --all-targets -- -D warnings) also passes. Local CPU verification does not establish remote CI or other-platform results.

AI-assisted implementation and testing; final code and baseline exceptions independently reviewed before submission.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ONNX ReduceMax/ReduceMin treat explicitly empty axes as a no-op by default

1 participant