Skip to content

Raise NotImplementedError at conversion time for reflect/replicate pad >2D (fixes #2576, #2571)#2701

Open
LeSingh1 wants to merge 2 commits into
apple:mainfrom
LeSingh1:fix/pad-reflect-replicate-3d-validation
Open

Raise NotImplementedError at conversion time for reflect/replicate pad >2D (fixes #2576, #2571)#2701
LeSingh1 wants to merge 2 commits into
apple:mainfrom
LeSingh1:fix/pad-reflect-replicate-3d-validation

Conversation

@LeSingh1
Copy link
Copy Markdown
Contributor

Summary

mb.pad only supports reflect / replicate modes when at most the final two dimensions carry non-zero padding. The generic pad torch converter forwards the mode through unconditionally, so torch.export-decomposed torch.nn.ReflectionPad3d / torch.nn.ReplicationPad3d (which decompose to aten.pad with mode="reflect" / "replicate" and 3 padded dims) currently convert successfully and then explode at predict() time with:

RuntimeError: Error compiling model: "Failed to parse the model specification.
Error: Unable to parse ML Program: in operation pad_cast_fp16:
Padding for more than two dimensions only supports `constant` mode".

The two original issues (#2576 ReflectionPad3D, #2571 ReplicationPad3d) reported this exact failure mode and asked for an ahead-of-time error instead.

Fix

Added a static check inside _translate_torch_args in the pad op converter (coremltools/converters/mil/frontend/torch/ops.py). When mode in ("reflect", "replicate"), the pad list is fully static, and more than two dimensions have non-zero pad, raise NotImplementedError with a message that names the mode, the padded-dim count, and the typical culprit modules.

The check is scoped tightly:

  • only static-list pad (dynamic-padding path was already raising for other reasons);
  • only reflect / replicate modes (constant and circular unaffected);
  • only triggers when padded_dims > 2 — valid 2D cases (ReflectionPad2d, etc.) still convert unchanged.

Tests

Added TestPad::test_pad_reflect_replicate_3d_raises parameterized over both torch.nn.ReflectionPad3d and torch.nn.ReplicationPad3d:

tests/...::test_pad_reflect_replicate_3d_raises[mode=reflect-...]   PASSED
tests/...::test_pad_reflect_replicate_3d_raises[mode=replicate-...] PASSED
======================== 2 passed in 0.64s =========================

I also manually verified torch.nn.ReflectionPad2d(padding=2) on a rank-4 input still passes the new guard and proceeds to the rest of the converter.

Issues

Fixes #2576
Fixes #2571

…d >2D

`mb.pad` only supports `reflect` / `replicate` modes when at most the final
two dimensions carry non-zero padding. The generic `pad` converter
forwarded the mode through unconditionally, which produced a confusing
model-compile-time failure inside `predict()`:

    Failed to parse the model specification. Error: Unable to parse ML
    Program: in operation pad_cast_fp16: Padding for more than two
    dimensions only supports `constant` mode

This patch checks the (static) padding profile inside `_translate_torch_args`
and raises a clear `NotImplementedError` at conversion time instead. The
check fires for the torch.export-decomposed shape of `ReflectionPad3d` /
`ReplicationPad3d` with non-trivial padding (`aten.pad` with mode=reflect
or replicate and >2 dims of non-zero pad).

A regression test under `TestPad` covers both torch modules.

Fixes apple#2576
Fixes apple#2571
)
if padded_dims > 2:
raise NotImplementedError(
f"CoreML's pad operation only supports `{mode}` mode when "
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just stick with the error message from the Core ML Framework, I think it clearer: Padding for more than two dimensions only supports constant mode".

],
)
def test_pad_reflect_replicate_3d_raises(self, mode, torch_module):
# Regression test for issues #2576 and #2571: MIL `mb.pad` only supports
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's update this comment using the language mentioned in my other comment.

@TobyRoseman
Copy link
Copy Markdown
Collaborator

Per @TobyRoseman's review on apple#2701:

- ops.py: replace the verbose multi-line error with the existing Core ML
  Framework wording ('Padding for more than two dimensions only supports
  constant mode') so the conversion-time and runtime errors match.
- test_torch_ops.py: update the docstring to the same language and match
  the new error string in pytest.raises (the previous regex matched the
  mode name, which is no longer in the message).
@LeSingh1
Copy link
Copy Markdown
Contributor Author

Thanks for the review @TobyRoseman! Updated in abb9faa — now raising the Core ML Framework's own wording verbatim ("Padding for more than two dimensions only supports constant mode") and updated the test comment + pytest.raises match to use the same string.

@TobyRoseman
Copy link
Copy Markdown
Collaborator

This may be a better fix: #2697

@LeSingh1
Copy link
Copy Markdown
Contributor Author

Agreed @TobyRoseman#2697's approach is better, since it actually makes >2D reflect/replicate pads work via the new split_non_constant_pads backend pass instead of just surfacing the error sooner. I'm happy to close this PR once #2697 lands, or sooner if you'd prefer. Let me know which is cleaner for you.

@TobyRoseman
Copy link
Copy Markdown
Collaborator

@LeSingh1 - Thanks for confirming. If you don't mind, please review #2697. Does the fix look good to you? Are there any additional tests you recommend adding? Feel free to comment directly in that pull request.

cc: @tritolol.

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.

ReflectionPad3D fails at runtime torch.nn.ReplicationPad3d fails at runtime when there is padding

2 participants