Skip to content

[Bug] Relax ONNX Slice crashes on negative-step empty result #19532

@ALinrunrun

Description

@ALinrunrun

Expected behavior

TVM Relax should handle ONNX Slice with a negative step consistently with ONNX Runtime.
For this case:

X shape: [10]
starts = [0]
ends = [5]
axes = [0]
steps = [-1]

ONNX Runtime returns an empty tensor:

ORT shape: (0,) value: []

TVM should either produce the same empty result or otherwise preserve ONNX Slice semantics.

Actual behavior

TVM Relax crashes while importing/legalizing/building the ONNX model:

ORT shape: (0,) value: []
TVM crashed: Check failed: (strides[i] < 0 ? (end_i <= begin_i) : (begin_i <= end_i)) is false: : Input [Begin=0, End=5] is invalid for axis=0

The issue appears for a valid ONNX Slice pattern with steps=[-1] that produces an empty result in ONNX Runtime.

Environment

TVM: 0.14 environment / Relax ONNX frontend
ONNX Runtime: 1.23
Python: 3.11
Target: llvm
OS: Linux

Steps to reproduce

import numpy as np
import onnx
from onnx import helper, TensorProto
import onnxruntime as ort
import tvm
from tvm import relax
from tvm.relax.frontend.onnx import from_onnx


x_info = helper.make_tensor_value_info("X", TensorProto.FLOAT, [10])
y_info = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [None])

starts = helper.make_tensor("starts", TensorProto.INT64, [1], [0])
ends = helper.make_tensor("ends", TensorProto.INT64, [1], [5])
axes = helper.make_tensor("axes", TensorProto.INT64, [1], [0])
steps = helper.make_tensor("steps", TensorProto.INT64, [1], [-1])

node = helper.make_node(
    "Slice",
    ["X", "starts", "ends", "axes", "steps"],
    ["Y"],
)

graph = helper.make_graph(
    [node],
    "g",
    [x_info],
    [y_info],
    initializer=[starts, ends, axes, steps],
)

model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 17)])
model.ir_version = 9
onnx.checker.check_model(model)

x = np.arange(10, dtype=np.float32)

ort_out = ort.InferenceSession(
    model.SerializeToString(),
    providers=["CPUExecutionProvider"],
).run(None, {"X": x})[0]

print("ORT shape:", ort_out.shape, "value:", ort_out.tolist())

mod = from_onnx(model)
mod = relax.transform.LegalizeOps()(mod)
ex = relax.build(mod, tvm.target.Target("llvm"))

dev = tvm.cpu(0)
vm = relax.VirtualMachine(ex, dev)
tvm_out = vm["main"](tvm.runtime.tensor(x, device=dev)).numpy()

print("TVM shape:", tvm_out.shape, "value:", tvm_out.tolist())

Triage

  • needs-triage

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triagePRs or issues that need to be investigated by maintainers to find the right assignees to address ittype: bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions