blob: e7e4bbbcd56ef53e37d6d727f5ec37a3750f2f8b [file] [log] [blame]
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +01001# Copyright (C) 2020 Arm Limited or its affiliates. All rights reserved.
2#
3# SPDX-License-Identifier: Apache-2.0
4#
5# Licensed under the Apache License, Version 2.0 (the License); you may
6# not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an AS IS BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# Description:
17# Utility functions for creating Network Operations.
18from typing import Optional
Fredrik Svedberge82be7c2021-01-18 15:21:03 +010019from typing import Tuple
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010020
21from .data_type import DataType
22from .high_level_command_to_npu_op import ifm_ifm2_correct_order
23from .operation import ActivationFunction
24from .operation import Op
25from .operation import Operation
Michael McGeagh16895482020-12-14 15:51:20 +000026from .operation import Padding
Patrik Gustavsson3a269202021-01-21 08:28:55 +010027from .shape4d import Shape4D
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010028from .tensor import QuantizationParameters
29from .tensor import Tensor
30
31
32def create_avgpool_nop(name: str) -> Operation:
33 op = Operation(Op.AvgPool, name)
Michael McGeagh16895482020-12-14 15:51:20 +000034 op.attrs["padding"] = Padding.VALID
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010035 op.attrs["stride_w"] = 1
36 op.attrs["stride_h"] = 1
37 op.attrs["filter_width"] = 1
38 op.attrs["filter_height"] = 1
39 op.attrs["strides"] = [1, 1, 1, 1]
40 op.attrs["ksize"] = [1, 1, 1, 1]
41 op.attrs["skirt"] = [0, 0, 0, 0]
42 op.attrs["explicit_padding"] = [0, 0, 0, 0]
43 return op
44
45
46def create_depthwise_maxpool(
Patrik Gustavsson3a269202021-01-21 08:28:55 +010047 name: str,
48 ifm: Tensor,
49 inp_shape: Shape4D,
50 quantization: QuantizationParameters,
51 activation: Optional[ActivationFunction] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010052) -> Operation:
53 op = Operation(Op.MaxPool, name)
Patrik Gustavsson3a269202021-01-21 08:28:55 +010054 height = inp_shape.height * inp_shape.width
55 width = inp_shape.depth
56 ifm_shape = Shape4D([1, height, width, 1])
57
Michael McGeagh16895482020-12-14 15:51:20 +000058 op.attrs["padding"] = Padding.VALID
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010059 op.attrs["stride_w"] = 1
60 op.attrs["stride_h"] = 1
61 op.attrs["filter_width"] = width
62 op.attrs["filter_height"] = 1
63 op.attrs["strides"] = [1, op.attrs["stride_h"], op.attrs["stride_w"], 1]
64 op.attrs["ksize"] = [1, op.attrs["filter_height"], op.attrs["filter_width"], 1]
65 op.activation = activation
Patrik Gustavsson3a269202021-01-21 08:28:55 +010066 op.inputs = [ifm]
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010067 ofm = Tensor([1, height, 1, 1], ifm.dtype, op.name + "_tens0")
68 ofm.quantization = quantization
69 op.set_output_tensor(ofm)
Patrik Gustavsson3a269202021-01-21 08:28:55 +010070 op.ifm_shapes.append(ifm_shape)
71 op.ofm_shapes.append(Shape4D(ofm.shape))
72 op.ifm.avoid_NHCWB16 = True
73 op.ofm.avoid_NHCWB16 = True
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010074 return op
75
76
77def create_reduce_sum(
78 name: str, ifm: Tensor, quantization: QuantizationParameters, activation: Optional[ActivationFunction] = None
79) -> Operation:
80 op = Operation(Op.ReduceSum, name)
Michael McGeagh16895482020-12-14 15:51:20 +000081 op.attrs["padding"] = Padding.VALID
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010082 op.attrs["stride_w"] = 1
83 op.attrs["stride_h"] = 1
84 op.attrs["filter_width"] = 1
85 op.attrs["filter_height"] = 1
86 op.attrs["strides"] = [1, op.attrs["stride_h"], op.attrs["stride_w"], 1]
87 op.attrs["ksize"] = [1, op.attrs["filter_height"], op.attrs["filter_width"], 1]
88 op.add_input_tensor(ifm)
89 op.activation = activation
90 ofm_shape = [1, ifm.shape[1], ifm.shape[2], 1]
91 sum_of_exp = Tensor(ofm_shape, DataType.int32, op.name + "_tens0")
92 sum_of_exp.quantization = quantization
93 op.set_output_tensor(sum_of_exp)
Patrik Gustavsson2349d422020-12-01 16:02:29 +010094 op.set_ifm_ofm_shapes()
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +010095 return op
96
97
98def create_add(
99 name: str,
100 ifm: Tensor,
101 ifm2: Tensor,
102 quantization: QuantizationParameters,
103 activation: Optional[ActivationFunction] = None,
104 dtype: Optional[DataType] = None,
105 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100106 ifm_shape: Optional[Shape4D] = None,
107 ifm2_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100108) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100109 return create_binary_elementwise(
110 Op.Add, name, ifm, ifm2, quantization, activation, dtype, attrs, ifm_shape, ifm2_shape
111 )
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100112
113
Fredrik Svedberge82be7c2021-01-18 15:21:03 +0100114def create_rescale_add(
115 name: str,
116 ifm: Tensor,
117 ifm2: Tensor,
118 rescale: Tuple[int, int],
119 quantization: QuantizationParameters,
120 activation: Optional[ActivationFunction] = None,
121 dtype: Optional[DataType] = None,
122 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100123 ifm_shape: Optional[Shape4D] = None,
124 ifm2_shape: Optional[Shape4D] = None,
Fredrik Svedberge82be7c2021-01-18 15:21:03 +0100125) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100126 op = create_binary_elementwise(
127 Op.RescaleAdd, name, ifm, ifm2, quantization, activation, dtype, attrs, ifm_shape, ifm2_shape
128 )
Fredrik Svedberge82be7c2021-01-18 15:21:03 +0100129 op.rescale = rescale
130 return op
131
132
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100133def create_clz(
134 name: str,
135 ifm: Tensor,
136 quantization: QuantizationParameters,
137 activation: Optional[ActivationFunction] = None,
138 dtype: Optional[DataType] = None,
139 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100140 ifm_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100141) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100142 return create_unary_elementwise(Op.CLZ, name, ifm, quantization, activation, dtype, attrs, ifm_shape)
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100143
144
145def create_mul(
146 name: str,
147 ifm: Tensor,
148 ifm2: Tensor,
149 quantization: QuantizationParameters,
150 activation: Optional[ActivationFunction] = None,
151 dtype: Optional[DataType] = None,
152 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100153 ifm_shape: Optional[Shape4D] = None,
154 ifm2_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100155) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100156 return create_binary_elementwise(
157 Op.Mul, name, ifm, ifm2, quantization, activation, dtype, attrs, ifm_shape, ifm2_shape
158 )
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100159
160
161def create_shl(
162 name: str,
163 ifm: Tensor,
164 ifm2: Tensor,
165 quantization: QuantizationParameters,
166 activation: Optional[ActivationFunction] = None,
167 dtype: Optional[DataType] = None,
168 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100169 ifm_shape: Optional[Shape4D] = None,
170 ifm2_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100171) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100172 return create_binary_elementwise(
173 Op.SHL, name, ifm, ifm2, quantization, activation, dtype, attrs, ifm_shape, ifm2_shape
174 )
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100175
176
177def create_shr(
178 name: str,
179 ifm: Tensor,
180 ifm2: Tensor,
181 quantization: QuantizationParameters,
182 activation: Optional[ActivationFunction] = None,
183 dtype: Optional[DataType] = None,
184 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100185 ifm_shape: Optional[Shape4D] = None,
186 ifm2_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100187) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100188 return create_binary_elementwise(
189 Op.SHR, name, ifm, ifm2, quantization, activation, dtype, attrs, ifm_shape, ifm2_shape
190 )
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100191
192
193def create_sub(
194 name: str,
195 ifm: Tensor,
196 ifm2: Tensor,
197 quantization: QuantizationParameters,
198 activation: Optional[ActivationFunction] = None,
199 dtype: Optional[DataType] = None,
200 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100201 ifm_shape: Optional[Shape4D] = None,
202 ifm2_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100203) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100204 return create_binary_elementwise(
205 Op.Sub, name, ifm, ifm2, quantization, activation, dtype, attrs, ifm_shape, ifm2_shape
206 )
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100207
208
209def create_unary_elementwise(
210 op_type: Op,
211 name: str,
212 ifm: Tensor,
213 quantization: QuantizationParameters,
214 activation: Optional[ActivationFunction] = None,
215 dtype: Optional[DataType] = None,
216 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100217 ifm_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100218) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100219 return create_binary_elementwise(op_type, name, ifm, None, quantization, activation, dtype, attrs, ifm_shape, None)
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100220
221
222def create_binary_elementwise(
223 op_type: Op,
224 name: str,
225 ifm: Tensor,
226 ifm2: Tensor,
227 quantization: QuantizationParameters,
228 activation: Optional[ActivationFunction] = None,
229 dtype: Optional[DataType] = None,
230 attrs: Optional[dict] = None,
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100231 ifm_shape: Optional[Shape4D] = None,
232 ifm2_shape: Optional[Shape4D] = None,
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100233) -> Operation:
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100234 if ifm_shape is None:
235 ifm_shape = Shape4D(ifm.shape)
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100236 op = Operation(op_type, name)
237 op.add_input_tensor(ifm)
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100238 op.ifm_shapes.append(ifm_shape)
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100239 if ifm2:
240 op.add_input_tensor(ifm2)
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100241 if ifm2_shape is None:
242 ifm2_shape = Shape4D(ifm2.shape)
243 op.ifm_shapes.append(ifm2_shape)
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100244 op.activation = activation
245 if not dtype:
246 dtype = ifm.dtype
247 if attrs:
248 op.attrs.update(attrs)
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100249
250 if ifm2 is None:
251 ofm_shape = ifm_shape
252 else:
253 in_shape = [] if ifm.shape == [] else ifm_shape.as_list()
254 in2_shape = [] if ifm2.shape == [] else ifm2_shape.as_list()
255 ofm_shape = ifm_shape if ifm_ifm2_correct_order(in_shape, in2_shape) else ifm2_shape
256
257 ofm = Tensor(ofm_shape.as_list(), dtype, f"{op.name}_tens0")
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100258 ofm.quantization = quantization
259 op.set_output_tensor(ofm)
Patrik Gustavsson3a269202021-01-21 08:28:55 +0100260 op.ofm_shapes.append(ofm_shape)
Fredrik Svedbergd9c2c422020-12-01 16:33:45 +0100261 return op