Skip to content

Import ONNX Pad including negative-padding crop semantics #22

Description

@matthargett

ONNX Pad is unsupported at 0bcd517, including a crop used to retain convolution history in this small Mamba fixture.

  • Minimal reproducer: opset 13, FP32 input [1,2,10], constant INT64 pads [0,0,-6,0,0,0], constant mode, omitted constant_value.
    • Expected output: [1,2,4], exactly the last four values along the final axis. ONNX checker and ONNX Runtime CPU agree.
    • convert-onnx --input crop.onnx --inline-weights fails with unsupported operator: Pad.
  • The model's negative padding is cropping, not an error or zero padding. WebNN's nonnegative padding arguments therefore need a slice composition; adding only positive pad support would not unblock this export.

Suggested acceptance checklist:

  • Resolve constant pads, optional scalar value and opset-18 axes; normalize axes and validate ranks/ranges.
  • Lower cropping to slice, then add any positive padding; cover pure crop and mixed crop/pad.
  • Map constant/edge/reflect semantics, including ONNX reflect to WebNN reflection.
  • Reject unresolved runtime parameters explicitly; do not substitute maximum dimensions. Dynamic producer provenance is tracked separately in Preserve producer-based provenance for dynamic Slice and Range bounds #20.
  • Test shapes and values against ONNX Runtime, including omitted optional inputs, and verify emitted JS uses WebNN's positional padding arguments.

This is an importer/decomposition gap, not a request to change WebNN pad. The fixture also has a separate hard-unrolled sequence-length restriction, so importing it will not establish general dynamic decode correctness.

Minimal fixture (Python onnx):

import onnx
from onnx import helper as h, TensorProto as T
x = h.make_tensor_value_info("x", T.FLOAT, [1, 2, 10])
y = h.make_tensor_value_info("y", T.FLOAT, [1, 2, 4])
pads = h.make_tensor("pads", T.INT64, [6], [0, 0, -6, 0, 0, 0])
graph = h.make_graph([h.make_node("Pad", ["x", "pads"], ["y"])], "crop", [x], [y], [pads])
model = h.make_model(graph, opset_imports=[h.make_opsetid("", 13)], ir_version=8)
onnx.checker.check_model(model)
onnx.save(model, "crop.onnx")

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions