• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Export IR Specification
2
3Export IR is an intermediate representation (IR) for the result of
4`torch.export`. To read more on the details of Export IR, please read this
5[document](https://pytorch.org/docs/main/export.ir_spec.html).
6
7The Exported IR is a specification that consists of the following parts:
8
91. A definition of computation graph model.
102. Set of operators allowed in the graph.
11
12A **dialect** is an Exported IR graph composed with the operations defined
13below, but with additional properties (such as restrictions on operator set or
14metadata) that are meant for a specific purpose.
15
16The EXIR dialects that currently exist are:
17
18* [ATen Dialect](#aten-dialect)
19* [Edge Dialect](#edge-dialect)
20* [Backend Dialect](#backend-dialect)
21
22These dialects represent stages that a captured program goes through from
23program capture to conversion into an executable format. For example, the
24ExecuTorch compilation process starts from a Python program capture into ATen
25Dialect, then ATen Dialect is converted to Edge Dialect, Edge to Backend, and
26finally to a binary format for execution.
27
28## ATen Dialect
29
30ATen dialect will be used as the entry point of the ExecuTorch compilation
31pipeline. It is the first time an eager mode PyTorch program becomes an Exported
32IR graph. At this stage, functionalization is performed, removing any tensor
33aliases and mutations, and allowing for more flexible graph transformations to
34be made. Additionally, all tensors are converted to continuous format.
35
36The goal of this dialect is to capture users' programs as faithfully as possible
37(while remaining valid Exported IR). Registered custom operators that user has called
38in eager mode will preserve as-is in ATen dialect. However, we should refrain
39from adding custom ops in the graph via passes.
40
41For now, the function of ATen dialect is to further lower to Edge dialect.
42However, in the future we can see this one as the common integration point for
43other export use cases.
44
45### ATen Dialect Properties
46
47An ATen dialect graph is a valid Export IR graph with the following additional
48properties:
49
501. All operators in `call_function` nodes are either ATen operators (in the
51  `torch.ops.aten` namespace, higher order operators (like control flow
52  operators), or a registered custom operator. A registered custom operator is
53  an operator registered into the current PyTorch eager mode runtime, usually
54  with `TORCH_LIBRARY` call (implies schema). Details for how to register a
55  custom operator can be found
56  [here](https://docs.google.com/document/d/1_W62p8WJOQQUzPsJYa7s701JXt0qf2OfLub2sbkHOaU/edit#heading=h.3rgxk3v387wl).
572. Every operator must also have a meta kernel. A meta kernel is a
58  function that, given the shapes of the input tensors, can return the shape of
59  output tensor. Details on how to write a meta kernel can be found
60  [here](https://docs.google.com/document/d/1GgvOe7C8_NVOMLOCwDaYV1mXXyHMXY7ExoewHqooxrs/edit#heading=h.64r4npvq0w0).
613. Input value type must be “Pytree-able”. As a consequence, the output
62  types are also Pytree-able because all operators output are pytree-able.
634. Ops of ATen dialect can choose to work Dynamic dtypes, implicit type
64  promotions and implicit broadcasting of tensors.
655. All tensors memory formats are in `torch.contiguous_format`.
66
67### ATen Operator Definition
68
69The operator set definition can be found [here](./ir-ops-set-definition.md).
70
71## Edge Dialect
72
73This dialect is meant to introduce specializations that are useful for Edge
74devices but not necessarily for general (server) export. However, we still
75withhold specializing further to each different hardware. In other words, we
76don’t want to introduce any new hardware dependent concepts or data; besides
77those already present in users’ original python program.
78
79### Edge Dialect Properties
80
81An Edge dialect graph is a valid Export IR graph with the following additional
82properties:
83
841. All operators in OpCall nodes are either from a predefined operator set,
85   called **“Edge Operators”**, or a registered custom operator. An Edge operator is a
86   ATen operator with dtype specialization. This allows users to register
87   kernels that only work for certain dtypes to reduce binary size.
882. Input and output of the graph, and as well as to every node, cannot be Scalar. I.e.
89   All scalar types (such as float, int) are converted to Tensor.
90
91### Using the Edge Dialect
92
93The Edge dialect is represented with `exir.EdgeProgramManager` Python class in
94memory. This contains one or multiple `torch.export.ExportedProgram`s which
95contain the graph representation of a method.
96
97```python
98import torch
99from executorch import exir
100
101class MyModule(torch.nn.Module):
102    ...
103
104a = MyModule()
105tracing_inputs = (torch.rand(2, 2),)
106aten_dialect_program = torch.export.export(a, tracing_inputs)
107edge_dialect_program: exir.EdgeProgramManager = exir.to_edge(aten_dialect)
108print(edge_dialect_program.exported_program)
109```
110
111At this point, user defined graph transformation can be run through
112`edge_dialect_program.transform(pass)`. Order matters. Note: If the custom pass
113is touching `node.target`, be aware that all of the `node.target` at this stage
114are "Edge ops" (more details below) and not torch ops like in the ATen dialect.
115A tutorial on pass writing can be found
116[here](./compiler-custom-compiler-passes.md). After all these passes are
117executed, `to_edge()` will make sure the graph is still valid.
118
119### Edge Operators
120
121As mentioned before, an edge operator is an ATen core operator with type
122specialization. This means an instance of the edge operator contains a set of
123dtype constraints, that describe all the tensor dtypes supported by both the
124ExecuTorch runtime and their ATen kernels. These dtype constraints are expressed
125in a DSL defined in
126[edge.yaml](https://github.com/pytorch/executorch/blob/main/exir/dialects/edge/edge.yaml).
127Here's an example of the dtype constraints:
128
129```
130- func: sigmoid
131  namespace: edge
132  inherits: aten::sigmoid
133  type_alias:
134    T0: [Bool, Byte, Char, Int, Long, Short]
135    T1: [Double, Float]
136    T2: [Float]
137  type_constraint:
138  - self: T0
139    __ret_0: T2
140  - self: T1
141    __ret_0: T1
142```
143This is saying if `self` tensor is one of the type `Bool, Byte, Char, Int, Long, Short`, then the return tensor would be `Float`. If `self` is one of `Double, Float`, the return tensor will be the same dtype.
144
145After these dtype constraints are collected and documented in edge.yaml, EXIR
146consumes the file, and loads the constraints into EXIR Edge operators. This
147makes it convenient for developers to learn the supported dtypes of any argument
148in the Edge op schema. For example we can do:
149
150
151```python
152from executorch.exir.dialects._ops import ops as exir_ops # import dialects ops
153sigmoid = exir_ops.edge.aten.sigmoid.default
154print(sigmoid._schema)
155# aten::sigmoid(Tensor self) -> Tensor
156self_arg = sigmoid._schema.arguments[0]
157_return = sigmoid._schema.returns[0]
158
159print(self_arg.allowed_types)
160# {torch.float32, torch.int8, torch.float64, torch.int16, torch.int32, torch.int64, torch.uint8, torch.bool}
161
162print(_return.allowed_types)
163# {torch.float32, torch.float64}
164```
165
166These constraints are helpful for someone who wants to write a custom kernel for this operator. Also inside EXIR, we offer a validator to check if the graph is still complying with these dtype constraints, after custom transformations.
167
168### Op Set (WIP)
169
170Check out
171[edge.yaml](https://github.com/pytorch/executorch/blob/main/exir/dialects/edge/edge.yaml)
172for the complete list of operators having dtype constraints specified. We are
173gradually expanding this operator set and targeting to provide dtype constraints
174for all core ATen ops.
175
176## Backend Dialect
177
178See this [doc](./compiler-backend-dialect.md)
179