Skip to content

All the reduce ops cause an error with None axis and noop_with_empty_axes=1 #25095

Open
@vacu9708

Description

@vacu9708

Describe the issue

Test 1 works but Test 2 causes an error.

  • Test 1: empty axis list [ ] and noop_with_empty_axes=1
    • This correctly returns the input data unchanged.
  • Test 2: empty axis list None and noop_with_empty_axes=1
    • This should return the input data unchanged but causes an error.

In summary:

Axes list noop_with_empty_axes Behavior Correct behavior
[ ] 1 Returns the input unchanged
[ ] 0 Reduces all dimensions
None 1 Raises a runtime error Returns the input unchanged
None 0 Reduces all dimensions

Implementation

The official ONNX spec ambiguously describes "empty axes" — it’s unclear whether it refers to None or to an empty list [ ]. However, the "Inputs" section states there can be one or two inputs and that axes is optional, thus I think interpreting "empty axes" as either None or [ ] aligns with the specification.

Error

The error below occurs

2025-06-17 22:41:27.297103445 [E:onnxruntime:, sequential_executor.cc:572 ExecuteKernel] Non-zero status code returned while running ReduceL1 node. Name:'' Status Message: /onnxruntime_src/onnxruntime/core/providers/cpu/reduction/reduction_ops.cc:484 void onnxruntime::ValidateNoTransposeReduce(int64_t) count == 1 was false. Reduction on all axes, output size should be 1.

Traceback (most recent call last):
  File "/home/ysy/Documents/open_source/tvm/source/me/reduce_test.py", line 107, in <module>
    test2()
  File "/home/ysy/Documents/open_source/tvm/source/me/reduce_test.py", line 98, in test2
    result = sess.run(None, {"x": x})
  File "/home/ysy/.local/lib/python3.10/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 273, in run
    return self._sess.run(output_names, input_feed, run_options)
onnxruntime.capi.onnxruntime_pybind11_state.RuntimeException: [ONNXRuntimeError] : 6 : RUNTIME_EXCEPTION : Non-zero status code returned while running ReduceL1 node. Name:'' Status Message: /onnxruntime_src/onnxruntime/core/providers/cpu/reduction/reduction_ops.cc:484 void onnxruntime::ValidateNoTransposeReduce(int64_t) count == 1 was false. Reduction on all axes, output size should be 1.

To reproduce

import numpy as np
import onnx
from onnx import helper, TensorProto
import onnxruntime as ort

def test1():
    # 1. Create input data
    x = np.array([[1, 2, 3],
                [4, 5, 6]], dtype=np.int64)

    # 2. Create axes initializer for axis 1
    axes = np.array([], dtype=np.int64)
    axes_initializer = helper.make_tensor(
        name="axes",
        data_type=TensorProto.INT64,
        dims=axes.shape,
        vals=axes,
    )

    # 3. Build Reduce node (opset-18)
    node = helper.make_node(
        "ReduceL1",
        inputs=["x", "axes"],
        outputs=["y"],
        keepdims=1,
        noop_with_empty_axes=1,
    )

    # 4. Build the graph
    graph = helper.make_graph(
        [node],
        "Reduce_v18_graph",
        inputs=[helper.make_tensor_value_info("x", TensorProto.INT64, x.shape)],
        initializer=[axes_initializer],
        outputs=[helper.make_tensor_value_info("y", TensorProto.INT64, None)],
    )

    # 5. Create model with opset 18
    model = helper.make_model(
        graph,
        producer_name="reduce_l1_v18",
        opset_imports=[helper.make_opsetid("", 18)],
    )

    # 6. Save the model to disk
    onnx.save(model, "reduce_l1_v18.onnx")

    # 7. Run the model using ONNX Runtime
    sess = ort.InferenceSession("reduce_l1_v18.onnx")
    result = sess.run(None, {"x": x})

    # 8. Print the input
    print("Input array x:")
    print(x)

    # Print the output
    print("Output array y:")
    print(result[0])
test1()

def test2():
    # Create input data
    x = np.array([[1, 2, 3],
                [4, 5, 6]], dtype=np.int64)

    # Build Reduce node (opset-18)
    node = helper.make_node(
        "ReduceL1",
        inputs=["x"],
        outputs=["y"],
        keepdims=1,
        noop_with_empty_axes=1,
    )

    # Build the graph
    graph = helper.make_graph(
        [node],
        "Reduce_v18_graph",
        inputs=[helper.make_tensor_value_info("x", TensorProto.INT64, x.shape)],
        # initializer=[axes_initializer],
        outputs=[helper.make_tensor_value_info("y", TensorProto.INT64, None)],
    )

    # Create model with opset 18
    model = helper.make_model(
        graph,
        producer_name="reduce_l1_v18",
        opset_imports=[helper.make_opsetid("", 18)],
    )

    # Save the model to disk
    onnx.save(model, "reduce_l1_v18.onnx")

    # Run the model using ONNX Runtime
    sess = ort.InferenceSession("reduce_l1_v18.onnx")
    print("Active providers:", sess.get_providers())
    result = sess.run(None, {"x": x})

    # Print the input
    print("Input array x:")
    print(x)

    # Print the output
    print("Output array y:")
    print(result[0])
test2()

Urgency

No response

Platform

Linux

OS Version

ubuntu 22.04

ONNX Runtime Installation

Released Package

ONNX Runtime Version or Commit ID

1.22.0

ONNX Runtime API

Python

Architecture

X64

Execution Provider

Default CPU

Execution Provider Library Version

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    ep:tvmissues related to TVM execution provider

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions