Skip to content

Commit 59fc93d

Browse files
Arm backend: Serialise TOSA shape operations (pytorch#20326)
Add support for serializing TOSA shape operators introduced in TOSA-1.1 spec. draft. cc @digantdesai @freddan80 @per @zingo @mansnils @Sebastian-Larsson @robell @rascani --------- Signed-off-by: Oscar Andersson <oscar.andersson@arm.com> Co-authored-by: Per Åstrand <per.astrand@arm.com>
1 parent 47f046d commit 59fc93d

2 files changed

Lines changed: 396 additions & 3 deletions

File tree

‎backends/arm/operators/op_tosa_shapes.py‎

Lines changed: 215 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
NodeVisitor,
1414
register_node_visitor,
1515
)
16+
from executorch.backends.arm.tosa import TosaSpecification
1617
from executorch.backends.arm.tosa.mapping import TosaArg
1718
from executorch.backends.arm.tosa.utils import normalize_symint
1819

@@ -21,9 +22,6 @@
2122
class TosaConstShapeVisitor(NodeVisitor):
2223
target = "tosa.CONST_SHAPE.default"
2324

24-
def __init__(self, *args):
25-
super().__init__(*args)
26-
2725
def define_node(
2826
self,
2927
node: torch.fx.Node,
@@ -43,3 +41,217 @@ def define_node(
4341
vals=vals,
4442
name=output.name,
4543
)
44+
45+
46+
class TosaShapeNodeVisitor(NodeVisitor):
47+
48+
tosa_specs = TosaSpecification.all_profiles_for_version("1.1")
49+
50+
def define_node(
51+
self,
52+
node: torch.fx.Node,
53+
tosa_graph: Any,
54+
inputs: List[TosaArg],
55+
output: TosaArg,
56+
) -> None:
57+
tosa_graph = cast(ts.TosaSerializer, tosa_graph)
58+
tosa_graph.currRegion.currBasicBlock.addShape(
59+
output.name,
60+
output.shape[0],
61+
)
62+
63+
64+
class TosaBasicShapeVisitor(TosaShapeNodeVisitor):
65+
tosa_op: ts.Op
66+
attr_method: str
67+
68+
def define_node(
69+
self,
70+
node: torch.fx.Node,
71+
tosa_graph: Any,
72+
inputs: List[TosaArg],
73+
output: TosaArg,
74+
) -> None:
75+
super().define_node(node, tosa_graph, inputs, output)
76+
self.serialize(
77+
node,
78+
tosa_graph,
79+
tosa_op=self.tosa_op,
80+
inputs=inputs,
81+
output=output,
82+
attr_method=self.attr_method,
83+
)
84+
85+
86+
@register_node_visitor
87+
class TosaDimShapeVisitor(TosaShapeNodeVisitor):
88+
target = "tosa.DIM.default"
89+
90+
def define_node(
91+
self,
92+
node: torch.fx.Node,
93+
tosa_graph: Any,
94+
inputs: List[TosaArg],
95+
output: TosaArg,
96+
) -> None:
97+
super().define_node(node, tosa_graph, inputs, output)
98+
99+
attr = ts.TosaSerializerAttribute()
100+
attr.DimAttribute(axis=node.kwargs["axis"])
101+
self._serialize_operator(
102+
node,
103+
tosa_graph,
104+
ts.Op.DIM,
105+
[inputs[0].name],
106+
[output.name],
107+
attr,
108+
)
109+
110+
111+
@register_node_visitor
112+
class TosaAddShapeVisitor(TosaBasicShapeVisitor):
113+
target = "tosa.ADD_SHAPE.default"
114+
115+
tosa_op = ts.Op.ADD_SHAPE
116+
attr_method = "AddShapeAttribute"
117+
118+
119+
@register_node_visitor
120+
class TosaSubShapeVisitor(TosaBasicShapeVisitor):
121+
target = "tosa.SUB_SHAPE.default"
122+
123+
tosa_op = ts.Op.SUB_SHAPE
124+
attr_method = "SubShapeAttribute"
125+
126+
127+
@register_node_visitor
128+
class TosaAssertEqualShapeVisitor(TosaShapeNodeVisitor):
129+
target = "tosa.ASSERT_EQUAL_SHAPE.default"
130+
131+
def define_node(
132+
self,
133+
node: torch.fx.Node,
134+
tosa_graph: Any,
135+
inputs: List[TosaArg],
136+
output: TosaArg,
137+
) -> None:
138+
super().define_node(node, tosa_graph, inputs, output)
139+
tosa_graph = cast(ts.TosaSerializer, tosa_graph)
140+
attr = ts.TosaSerializerAttribute()
141+
attr.AssertEqualShapeAttribute(allow_broadcast=node.kwargs["allow_broadcast"])
142+
self._serialize_operator(
143+
node,
144+
tosa_graph,
145+
ts.Op.ASSERT_EQUAL_SHAPE,
146+
[inputs[0].name, inputs[1].name],
147+
[output.name],
148+
attr,
149+
)
150+
151+
152+
@register_node_visitor
153+
class TosaCatShapeVisitor(TosaShapeNodeVisitor):
154+
target = "tosa.CONCAT_SHAPE.default"
155+
156+
def define_node(
157+
self,
158+
node: torch.fx.Node,
159+
tosa_graph: Any,
160+
inputs: List[TosaArg],
161+
output: TosaArg,
162+
) -> None:
163+
super().define_node(node, tosa_graph, inputs, output)
164+
tosa_graph = cast(ts.TosaSerializer, tosa_graph)
165+
166+
input_shape_list = [input.name for input in inputs[0].special]
167+
168+
attr = ts.TosaSerializerAttribute()
169+
attr.ConcatShapeAttribute()
170+
self._serialize_operator(
171+
node,
172+
tosa_graph,
173+
ts.Op.CONCAT_SHAPE,
174+
input_shape_list,
175+
[output.name],
176+
attr,
177+
)
178+
179+
180+
@register_node_visitor
181+
class TosaDivCeilShapeVisitor(TosaBasicShapeVisitor):
182+
target = "tosa.DIV_CEIL_SHAPE.default"
183+
184+
tosa_op = ts.Op.DIV_CEIL_SHAPE
185+
attr_method = "DivCeilShapeAttribute"
186+
187+
188+
@register_node_visitor
189+
class TosaDivShapeVisitor(TosaBasicShapeVisitor):
190+
target = "tosa.DIV_FLOOR_SHAPE.default"
191+
192+
tosa_op = ts.Op.DIV_FLOOR_SHAPE
193+
attr_method = "DivFloorShapeAttribute"
194+
195+
196+
@register_node_visitor
197+
class TosaExp2ShapeVisitor(TosaBasicShapeVisitor):
198+
target = "tosa.EXP2_SHAPE.default"
199+
200+
tosa_op = ts.Op.EXP2_SHAPE
201+
attr_method = "Exp2ShapeAttribute"
202+
203+
204+
@register_node_visitor
205+
class TosaLog2CeilShapeVisitor(TosaBasicShapeVisitor):
206+
target = "tosa.LOG2_CEIL_SHAPE.default"
207+
208+
tosa_op = ts.Op.LOG2_CEIL_SHAPE
209+
attr_method = "Log2CeilShapeAttribute"
210+
211+
212+
@register_node_visitor
213+
class TosaLog2FloorShapeVisitor(TosaBasicShapeVisitor):
214+
target = "tosa.LOG2_FLOOR_SHAPE.default"
215+
216+
tosa_op = ts.Op.LOG2_FLOOR_SHAPE
217+
attr_method = "Log2FloorShapeAttribute"
218+
219+
220+
@register_node_visitor
221+
class TosaMaxShapeVisitor(TosaBasicShapeVisitor):
222+
target = "tosa.MAX_SHAPE.default"
223+
224+
tosa_op = ts.Op.MAX_SHAPE
225+
attr_method = "MaxShapeAttribute"
226+
227+
228+
@register_node_visitor
229+
class TosaMinShapeVisitor(TosaBasicShapeVisitor):
230+
target = "tosa.MIN_SHAPE.default"
231+
232+
tosa_op = ts.Op.MIN_SHAPE
233+
attr_method = "MinShapeAttribute"
234+
235+
236+
@register_node_visitor
237+
class TosaMulShapeVisitor(TosaBasicShapeVisitor):
238+
target = "tosa.MUL_SHAPE.default"
239+
240+
tosa_op = ts.Op.MUL_SHAPE
241+
attr_method = "MulShapeAttribute"
242+
243+
244+
@register_node_visitor
245+
class TosaSliceShapeVisitor(TosaBasicShapeVisitor):
246+
target = "tosa.SLICE_SHAPE.default"
247+
248+
tosa_op = ts.Op.SLICE_SHAPE
249+
attr_method = "SliceShapeAttribute"
250+
251+
252+
@register_node_visitor
253+
class TosaModShapeVisitor(TosaBasicShapeVisitor):
254+
target = "tosa.MOD_SHAPE.default"
255+
256+
tosa_op = ts.Op.MOD_SHAPE
257+
attr_method = "ModShapeAttribute"

0 commit comments

Comments
 (0)