MCPcopy Create free account
hub / github.com/pytorch/executorch / MemoryFormatOpsPass

Class MemoryFormatOpsPass

exir/passes/memory_format_ops_pass.py:24–91  ·  view source on GitHub ↗

This pass replaces ops which takes torch.memory_format as an argument with 'equivalent' op which takes dim_order. This is towards the larger ExecuTorch goal to move away from torch.memory_format. There is a 1:1 mapping between the aten op and the new edge dialect dim_order op.

Source from the content-addressed store, hash-verified

22
23
24class MemoryFormatOpsPass(ExportPass):
25 """
26 This pass replaces ops which takes torch.memory_format as an argument with
27 'equivalent' op which takes dim_order. This is towards the larger ExecuTorch
28 goal to move away from torch.memory_format. There is a 1:1 mapping between
29 the aten op and the new edge dialect dim_order op.
30 """
31
32 def call_operator(self, op, args, kwargs, meta):
33 if not (isinstance(op, EdgeOpOverload) and op in DimOrderOpsMap):
34 return super().call_operator(
35 op,
36 args,
37 kwargs,
38 meta,
39 )
40
41 # new kwargs with dim_order, and no memory_format for the new op
42 nkwargs = dict(copy.deepcopy(kwargs)) # orig kwargs are immutable
43
44 # Get the target memory format for the EdgeOp, defaulting to
45 # preserve_format (clone() with no memory_format kwarg preserves
46 # the input's layout instead of forcing contiguous).
47 mem_format = nkwargs.pop("memory_format", torch.preserve_format)
48
49 # Get input tensor and ndim
50 input_tensor: Optional[torch.Tensor] = None
51 if isinstance(args[0], ProxyValue) and args[0].is_tensor():
52 input_tensor = args[0].to_tensor()
53 ndim = input_tensor.dim()
54 elif isinstance(args[0], torch.Tensor):
55 input_tensor = args[0]
56 ndim = input_tensor.dim()
57 elif isinstance(args[0], torch.fx.immutable_collections.immutable_list):
58 ndim = len(args[0])
59 else:
60 assert (
61 0
62 ), f"Expecting a Tensor, a ProxyValue, or a Sequence, but got {type(args[0])}"
63
64 # Derive dim_order based on memory format
65 dim_order: List[int]
66 if mem_format in (None, torch.preserve_format):
67 # preserve_format: inherit dim_order from input tensor
68 if input_tensor is not None:
69 dim_order = [int(d) for d in input_tensor.dim_order()]
70 else:
71 # Fallback to contiguous if no single input tensor is available
72 # (e.g. list inputs like torch.stack).
73 dim_order = list(range(ndim))
74 else:
75 # Explicit memory format (contiguous_format, channels_last, etc.)
76 dim_order = get_dim_order(mem_format, ndim)
77
78 nkwargs["dim_order"] = dim_order
79 logger.debug(
80 f"{op.__name__} = rank: {ndim}, memory_format: {mem_format}."
81 f" {DimOrderOpsMap[op].__name__} = dim_order: {nkwargs['dim_order']}"

Callers 2

_to_edgeFunction · 0.90
_generate_edge_programFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected