ultralytics-thop 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,351 @@
1
+ import numpy as np
2
+ import torch
3
+ from onnx import numpy_helper
4
+
5
+ from thop.vision.basic_hooks import zero_ops
6
+
7
+ from .calc_func import (
8
+ calculate_avgpool,
9
+ calculate_conv,
10
+ calculate_norm,
11
+ calculate_softmax,
12
+ calculate_zero_ops,
13
+ counter_div,
14
+ counter_matmul,
15
+ counter_mul,
16
+ counter_pow,
17
+ counter_sqrt,
18
+ )
19
+
20
+
21
+ def onnx_counter_matmul(diction, node):
22
+ input1 = node.input[0]
23
+ input2 = node.input[1]
24
+ input1_dim = diction[input1]
25
+ input2_dim = diction[input2]
26
+ out_size = np.append(input1_dim[0:-1], input2_dim[-1])
27
+ output_name = node.output[0]
28
+ macs = counter_matmul(input1_dim, out_size[-2:])
29
+ return macs, out_size, output_name
30
+
31
+
32
+ def onnx_counter_add(diction, node):
33
+ if np.array(diction[node.input[1]]).size >= np.array(diction[node.input[0]]).size:
34
+ out_size = diction[node.input[1]]
35
+ else:
36
+ out_size = diction[node.input[0]]
37
+ output_name = node.output[0]
38
+ macs = calculate_zero_ops()
39
+ # if '140' in diction:
40
+ # print(diction['140'],output_name)
41
+ return macs, out_size, output_name
42
+
43
+
44
+ def onnx_counter_conv(diction, node):
45
+ # print(node)
46
+ # bias,kernelsize,outputsize
47
+ dim_bias = 0
48
+ input_count = 0
49
+ for i in node.input:
50
+ input_count += 1
51
+ if input_count == 3:
52
+ dim_bias = 1
53
+ dim_weight = diction[node.input[1]]
54
+ else:
55
+ dim_weight = diction[node.input[1]]
56
+ for attr in node.attribute:
57
+ # print(attr)
58
+ if attr.name == "kernel_shape":
59
+ dim_kernel = attr.ints # kw,kh
60
+ if attr.name == "strides":
61
+ dim_stride = attr.ints
62
+ if attr.name == "pads":
63
+ dim_pad = attr.ints
64
+ if attr.name == "dilations":
65
+ dim_dil = attr.ints
66
+ if attr.name == "group":
67
+ group = attr.i
68
+ # print(dim_dil)
69
+ dim_input = diction[node.input[0]]
70
+ output_size = np.append(dim_input[0 : -np.array(dim_kernel).size - 1], dim_weight[0])
71
+ hw = np.array(dim_input[-np.array(dim_kernel).size :])
72
+ for i in range(hw.size):
73
+ hw[i] = int((hw[i] + 2 * dim_pad[i] - dim_dil[i] * (dim_kernel[i] - 1) - 1) / dim_stride[i] + 1)
74
+ output_size = np.append(output_size, hw)
75
+ macs = calculate_conv(dim_bias, np.prod(dim_kernel), np.prod(output_size), dim_weight[1], group)
76
+ output_name = node.output[0]
77
+
78
+ # if '140' in diction:
79
+ # print("conv",diction['140'],output_name)
80
+ return macs, output_size, output_name
81
+
82
+
83
+ def onnx_counter_constant(diction, node):
84
+ # print("constant",node)
85
+ macs = calculate_zero_ops()
86
+ output_name = node.output[0]
87
+ output_size = [1]
88
+ # print(macs, output_size, output_name)
89
+ return macs, output_size, output_name
90
+
91
+
92
+ def onnx_counter_mul(diction, node):
93
+ if np.array(diction[node.input[1]]).size >= np.array(diction[node.input[0]]).size:
94
+ input_size = diction[node.input[1]]
95
+ else:
96
+ input_size = diction[node.input[0]]
97
+ macs = counter_mul(np.prod(input_size))
98
+ output_size = diction[node.input[0]]
99
+ output_name = node.output[0]
100
+ return macs, output_size, output_name
101
+
102
+
103
+ def onnx_counter_bn(diction, node):
104
+ input_size = diction[node.input[0]]
105
+ macs = calculate_norm(np.prod(input_size))
106
+ output_name = node.output[0]
107
+ output_size = input_size
108
+ return macs, output_size, output_name
109
+
110
+
111
+ def onnx_counter_relu(diction, node):
112
+ input_size = diction[node.input[0]]
113
+ macs = calculate_zero_ops()
114
+ output_name = node.output[0]
115
+ output_size = input_size
116
+ # print(macs, output_size, output_name)
117
+ # if '140' in diction:
118
+ # print("relu",diction['140'],output_name)
119
+ return macs, output_size, output_name
120
+
121
+
122
+ def onnx_counter_reducemean(diction, node):
123
+ keep_dim = 0
124
+ for attr in node.attribute:
125
+ if "axes" in attr.name:
126
+ dim_axis = np.array(attr.ints)
127
+ elif "keepdims" in attr.name:
128
+ keep_dim = attr.i
129
+
130
+ input_size = diction[node.input[0]]
131
+ macs = calculate_zero_ops()
132
+ output_name = node.output[0]
133
+ if keep_dim == 1:
134
+ output_size = input_size
135
+ else:
136
+ output_size = np.delete(input_size, dim_axis)
137
+ # output_size = input_size
138
+ return macs, output_size, output_name
139
+
140
+
141
+ def onnx_counter_sub(diction, node):
142
+ input_size = diction[node.input[0]]
143
+ macs = calculate_zero_ops()
144
+ output_name = node.output[0]
145
+ output_size = input_size
146
+ return macs, output_size, output_name
147
+
148
+
149
+ def onnx_counter_pow(diction, node):
150
+ if np.array(diction[node.input[1]]).size >= np.array(diction[node.input[0]]).size:
151
+ input_size = diction[node.input[1]]
152
+ else:
153
+ input_size = diction[node.input[0]]
154
+ macs = counter_pow(np.prod(input_size))
155
+ output_name = node.output[0]
156
+ output_size = input_size
157
+ return macs, output_size, output_name
158
+
159
+
160
+ def onnx_counter_sqrt(diction, node):
161
+ input_size = diction[node.input[0]]
162
+ macs = counter_sqrt(np.prod(input_size))
163
+ output_name = node.output[0]
164
+ output_size = input_size
165
+ return macs, output_size, output_name
166
+
167
+
168
+ def onnx_counter_div(diction, node):
169
+ if np.array(diction[node.input[1]]).size >= np.array(diction[node.input[0]]).size:
170
+ input_size = diction[node.input[1]]
171
+ else:
172
+ input_size = diction[node.input[0]]
173
+ macs = counter_div(np.prod(input_size))
174
+ output_name = node.output[0]
175
+ output_size = input_size
176
+ return macs, output_size, output_name
177
+
178
+
179
+ def onnx_counter_instance(diction, node):
180
+ input_size = diction[node.input[0]]
181
+ macs = calculate_norm(np.prod(input_size))
182
+ output_name = node.output[0]
183
+ output_size = input_size
184
+ return macs, output_size, output_name
185
+
186
+
187
+ def onnx_counter_softmax(diction, node):
188
+ input_size = diction[node.input[0]]
189
+ dim = node.attribute[0].i
190
+ nfeatures = input_size[dim]
191
+ batch_size = np.prod(input_size) / nfeatures
192
+ macs = calculate_softmax(nfeatures, batch_size)
193
+ output_name = node.output[0]
194
+ output_size = input_size
195
+ return macs, output_size, output_name
196
+
197
+
198
+ def onnx_counter_pad(diction, node):
199
+ # # TODO add constant name and output real vector
200
+ # if
201
+ # if (np.array(diction[node.input[1]]).size >= np.array(diction[node.input[0]]).size):
202
+ # input_size = diction[node.input[1]]
203
+ # else:
204
+ # input_size = diction[node.input[0]]
205
+ input_size = diction[node.input[0]]
206
+ macs = calculate_zero_ops()
207
+ output_name = node.output[0]
208
+ output_size = input_size
209
+ return macs, output_size, output_name
210
+
211
+
212
+ def onnx_counter_averagepool(diction, node):
213
+ # TODO add support of ceil_mode and floor
214
+ macs = calculate_avgpool(np.prod(diction[node.input[0]]))
215
+ output_name = node.output[0]
216
+ dim_pad = None
217
+ for attr in node.attribute:
218
+ # print(attr)
219
+ if attr.name == "kernel_shape":
220
+ dim_kernel = attr.ints # kw,kh
221
+ elif attr.name == "strides":
222
+ dim_stride = attr.ints
223
+ elif attr.name == "pads":
224
+ dim_pad = attr.ints
225
+ elif attr.name == "dilations":
226
+ dim_dil = attr.ints
227
+ # print(dim_dil)
228
+ dim_input = diction[node.input[0]]
229
+ hw = dim_input[-np.array(dim_kernel).size :]
230
+ if dim_pad is not None:
231
+ for i in range(hw.size):
232
+ hw[i] = int((hw[i] + 2 * dim_pad[i] - dim_kernel[i]) / dim_stride[i] + 1)
233
+ output_size = np.append(dim_input[0 : -np.array(dim_kernel).size], hw)
234
+ else:
235
+ for i in range(hw.size):
236
+ hw[i] = int((hw[i] - dim_kernel[i]) / dim_stride[i] + 1)
237
+ output_size = np.append(dim_input[0 : -np.array(dim_kernel).size], hw)
238
+ # print(macs, output_size, output_name)
239
+ return macs, output_size, output_name
240
+
241
+
242
+ def onnx_counter_flatten(diction, node):
243
+ # print(node)
244
+ macs = calculate_zero_ops()
245
+ output_name = node.output[0]
246
+ axis = node.attribute[0].i
247
+ input_size = diction[node.input[0]]
248
+ output_size = np.append(input_size[axis - 1], np.prod(input_size[axis:]))
249
+ # print("flatten",output_size)
250
+ return macs, output_size, output_name
251
+
252
+
253
+ def onnx_counter_gemm(diction, node):
254
+ # print(node)
255
+ # Compute Y = alpha * A' * B' + beta * C
256
+ input_size = diction[node.input[0]]
257
+ dim_weight = diction[node.input[1]]
258
+ # print(input_size,dim_weight)
259
+ macs = np.prod(input_size) * dim_weight[1] + dim_weight[0]
260
+ output_size = np.append(input_size[0:-1], dim_weight[0])
261
+ output_name = node.output[0]
262
+ return macs, output_size, output_name
263
+ pass
264
+
265
+
266
+ def onnx_counter_maxpool(diction, node):
267
+ # TODO add support of ceil_mode and floor
268
+ # print(node)
269
+ macs = calculate_zero_ops()
270
+ output_name = node.output[0]
271
+ dim_pad = None
272
+ for attr in node.attribute:
273
+ # print(attr)
274
+ if attr.name == "kernel_shape":
275
+ dim_kernel = attr.ints # kw,kh
276
+ elif attr.name == "strides":
277
+ dim_stride = attr.ints
278
+ elif attr.name == "pads":
279
+ dim_pad = attr.ints
280
+ elif attr.name == "dilations":
281
+ dim_dil = attr.ints
282
+ # print(dim_dil)
283
+ dim_input = diction[node.input[0]]
284
+ hw = dim_input[-np.array(dim_kernel).size :]
285
+ if dim_pad is not None:
286
+ for i in range(hw.size):
287
+ hw[i] = int((hw[i] + 2 * dim_pad[i] - dim_kernel[i]) / dim_stride[i] + 1)
288
+ output_size = np.append(dim_input[0 : -np.array(dim_kernel).size], hw)
289
+ else:
290
+ for i in range(hw.size):
291
+ hw[i] = int((hw[i] - dim_kernel[i]) / dim_stride[i] + 1)
292
+ output_size = np.append(dim_input[0 : -np.array(dim_kernel).size], hw)
293
+ # print(macs, output_size, output_name)
294
+ return macs, output_size, output_name
295
+
296
+
297
+ def onnx_counter_globalaveragepool(diction, node):
298
+ macs = calculate_zero_ops()
299
+ output_name = node.output[0]
300
+ input_size = diction[node.input[0]]
301
+ output_size = input_size
302
+ return macs, output_size, output_name
303
+
304
+
305
+ def onnx_counter_concat(diction, node):
306
+ # print(node)
307
+ # print(diction[node.input[0]])
308
+ axis = node.attribute[0].i
309
+ input_size = diction[node.input[0]]
310
+ for i in node.input:
311
+ dim_concat = diction[i][axis]
312
+ output_size = input_size
313
+ output_size[axis] = dim_concat
314
+ output_name = node.output[0]
315
+ macs = calculate_zero_ops()
316
+ return macs, output_size, output_name
317
+
318
+
319
+ def onnx_counter_clip(diction, node):
320
+ macs = calculate_zero_ops()
321
+ output_name = node.output[0]
322
+ input_size = diction[node.input[0]]
323
+ output_size = input_size
324
+ return macs, output_size, output_name
325
+
326
+
327
+ onnx_operators = {
328
+ "MatMul": onnx_counter_matmul,
329
+ "Add": onnx_counter_add,
330
+ "Conv": onnx_counter_conv,
331
+ "Mul": onnx_counter_mul,
332
+ "Constant": onnx_counter_constant,
333
+ "BatchNormalization": onnx_counter_bn,
334
+ "Relu": onnx_counter_relu,
335
+ "ReduceMean": onnx_counter_reducemean,
336
+ "Sub": onnx_counter_sub,
337
+ "Pow": onnx_counter_pow,
338
+ "Sqrt": onnx_counter_sqrt,
339
+ "Div": onnx_counter_div,
340
+ "InstanceNormalization": onnx_counter_instance,
341
+ "Softmax": onnx_counter_softmax,
342
+ "Pad": onnx_counter_pad,
343
+ "AveragePool": onnx_counter_averagepool,
344
+ "MaxPool": onnx_counter_maxpool,
345
+ "Flatten": onnx_counter_flatten,
346
+ "Gemm": onnx_counter_gemm,
347
+ "GlobalAveragePool": onnx_counter_globalaveragepool,
348
+ "Concat": onnx_counter_concat,
349
+ "Clip": onnx_counter_clip,
350
+ None: None,
351
+ }