NXP backend: added support for aten.pad with mode reflect - #21515
NXP backend: added support for aten.pad with mode reflect#21515novak-vaclav wants to merge 1 commit into
aten.pad with mode reflect#21515Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21515
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 New Failure, 9 PendingAs of commit 8c50a26 with merge base 4b4df96 ( NEW FAILURE - The following job has failed:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
9b9736c to
97731d1
Compare
|
Fixed minor issues I found out about after creating the PR. |
97731d1 to
76b13f3
Compare
|
And rebased onto current main to run the tests on Neutron Software 3.2.0 |
76b13f3 to
fc14b2c
Compare
fc14b2c to
bc44109
Compare
bc44109 to
6bf8da0
Compare
|
Resolved comments from code review, resolved conflicts with main and rebased. |
roman-janik-nxp
left a comment
There was a problem hiding this comment.
Just move the comment, otherwise GJ!
6bf8da0 to
f5b65ca
Compare
|
Fixed all found issues in code review, rebased onto |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
backends/nxp/backend/ir/converter/node_converters/ops_converters/pad_converter.py:33
PadConverter._get_mode()only looks at positional args. Ifaten.padis emitted with keyword arguments (common in FX graphs),modemay be present innode.kwargsand this will incorrectly default to "constant", causing reflect padding to be treated as unsupported and decomposed.
@staticmethod
def _get_mode(node: Node) -> str:
return node.args[2] if len(node.args) > 2 else "constant"
backends/nxp/backend/ir/converter/node_converters/ops_converters/pad_converter.py:87
_convert_paddings_to_tflite()is annotated to returnlist[int], but it actually returns a list of 2-element pairs (rank x 2). Also,paddings_reversedbecomes a list of NumPy row arrays, which then gets concatenated with Python lists; converting to plainlist[list[int]]early avoids mixed element types and matches whatMirrorPadexpects.
@staticmethod
def _convert_paddings_to_tflite(
paddings: Collection[int], input_tensor: tflite_model.Tensor
) -> list[int]:
# Group `padding` by two elements per list.
backends/nxp/neutron_partitioner.py:559
- Docstring has a mismatched bracket in the return-type description (
Optional[Callable[[torch.fx.Node], bool]]]:). This makes the rendered/parsed type unclear.
Returns:
List[torch._ops.OpOverload]: a list of ops that should not be decomposed.
Optional[Callable[[torch.fx.Node], bool]]]: an optional filter, called for each node in the
graph, that lets a node be decomposed even though its op is in the list above. A node is kept
(not decomposed) only if the filter returns True for it; if it returns False, the node is decomposed.
f5b65ca to
8c50a26
Compare
|
Github CI seemed to fail for some unrelated reason, so I rebased onto main and will wait till tests pass. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (4)
backends/nxp/tests/models.py:370
PadModule(and similarlyPadConvModule) annotatesvalueasfloat | None, but callers/tests may pass anint(and the previous API allowedfloat | int | None). Consider widening the annotation tofloat | int | Noneto match actual usage and avoid type-checker friction.
class PadModule(torch.nn.Module):
def __init__(
self,
paddings: Collection[int],
mode: str = "constant",
value: float | None = None,
):
backends/nxp/backend/ir/converter/node_converters/ops_converters/pad_converter.py:32
aten.padmode can be provided via keyword arguments in FX (node.kwargs.get('mode')), not only positionally. With the current implementation, a node likepad(x, pad, mode='reflect')captured in kwargs could be misclassified asconstant, making the converter incorrectly report unsupported and causing decomposition instead of delegation. Update_get_modeto checknode.kwargsfirst (and fall back to positional/default).
def _get_mode(node: Node) -> str:
return node.args[2] if len(node.args) > 2 else "constant"
backends/nxp/backend/ir/converter/node_converters/ops_converters/pad_converter.py:78
- Two issues here: (1) the return annotation says
list[int], but the function returns a 2D structure (list[list[int]]/ array of pairs), which is what MirrorPad expects. (2) this code will raise (or produce invalid padding) whenlen(paddings)is odd or whenlen(paddings)/2 > input_tensor.rank(negative complement). It would be safer to validate these conditions in_is_supported_in_IR(returnFalse) or raise a clearer error before hitting NumPy reshape / negative rank math.
def _convert_paddings_to_tflite(
paddings: Collection[int], input_tensor: tflite_model.Tensor
) -> list[int]:
# Group `padding` by two elements per list.
paddings_grouped = np.array(paddings).reshape(-1, 2)
# In TFLite, `padding` order is reversed.
paddings_reversed = list(reversed(paddings_grouped))
# Add complementary zero pairs to `padding` to match input tensor rank.
zero_pair_compl = [[0, 0]] * (input_tensor.rank - len(paddings_reversed))
padding_tfl = zero_pair_compl + paddings_reversed
backends/nxp/neutron_partitioner.py:560
- Docstring type markup has a bracket mismatch:
Optional[Callable[[torch.fx.Node], bool]]]:has an extra]. This makes the docstring harder to read and can confuse generated docs; please fix the bracket structure.
) -> tuple[list[torch._ops.OpOverload], Callable[[torch.fx.Node], bool] | None]:
"""
Method to determine which operators SHOULD NOT be decomposed to simpler edge ops.
Returns:
List[torch._ops.OpOverload]: a list of ops that should not be decomposed.
Optional[Callable[[torch.fx.Node], bool]]]: an optional filter, called for each node in the
graph, that lets a node be decomposed even though its op is in the list above. A node is kept
(not decomposed) only if the filter returns True for it; if it returns False, the node is decomposed.
"""
Summary
Added support for
aten.padwith modereflectusing new Neutron MLIR flow.Test plan
tests can be manually run using
pytest -c /dev/null backends/nxp/tests/cc @robert-kalmar @JakeStevens @digantdesai @rascani @MartinPavella