Skip to content

ChannelsLastTaggedReshapePass crashes with immutable_list when using dynamic quantization #18944

@jgibson2

Description

@jgibson2

Bug

ChannelsLastTaggedReshapePass.input_to_nhwc crashes with AttributeError: 'immutable_list' object has no attribute 'graph' when lowering a dynamically quantized model to XNNPACK without per_op_mode.

Root Cause

Two issues in channels_last_tagged_reshape_pass.py:

1. input_to_nhwc while loop (line ~402)

if is_dynamic_input:
    while getattr(input_node, "args", None):
        input_node = input_node.args[0]

When tracing back through dynamic quantization nodes, args[0] can be an immutable_list (e.g., from a cat op where the first argument is a list of tensors). The loop assigns this list to input_node, then graph.inserting_after(input_node) crashes because immutable_list has no .graph attribute.

Fix: Add an isinstance check:

if is_dynamic_input:
    while getattr(input_node, "args", None) and isinstance(input_node.args[0], torch.fx.Node):
        input_node = input_node.args[0]

2. call method (line ~508)

self.input_to_nhwc(graph_module, node.args[0], node)

For ops like cat, node.args[0] is an immutable_list of tensors, not a single Node. This is passed directly as input_node to input_to_nhwc.

Fix: Guard with isinstance:

if isinstance(node.args[0], torch.fx.Node):
    self.input_to_nhwc(graph_module, node.args[0], node)

Reproduction

  1. Export a model containing torch.cat operations
  2. Apply dynamic quantization via XNNPACKQuantizer with get_symmetric_quantization_config(is_per_channel=True, is_dynamic=True)
  3. Lower with to_edge_transform_and_lower using XnnpackPartitioner() (without per_op_mode)

The crash occurs during the ChannelsLastTaggedReshapePass preprocessing step. Using per_op_mode=True works around the issue.

Stack Trace

File ".../channels_last_tagged_reshape_pass.py", line 508, in call
    self.input_to_nhwc(graph_module, node.args[0], node)
File ".../channels_last_tagged_reshape_pass.py", line 405, in input_to_nhwc
    with graph_module.graph.inserting_after(input_node):
File ".../torch/fx/graph.py", line 1583, in inserting_after
    if n.graph != self:
AttributeError: 'immutable_list' object has no attribute 'graph'

Environment

  • ExecuTorch 1.1.0
  • PyTorch 2.9.1
  • macOS (Apple Silicon)

Workaround

Use XnnpackPartitioner(per_op_mode=True) to bypass the fusion pass.

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