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.
- thop/__init__.py +8 -0
- thop/__version__.py +1 -0
- thop/fx_profile.py +224 -0
- thop/onnx_profile.py +76 -0
- thop/profile.py +233 -0
- thop/rnn_hooks.py +195 -0
- thop/utils.py +56 -0
- thop/vision/__init__.py +0 -0
- thop/vision/basic_hooks.py +146 -0
- thop/vision/calc_func.py +118 -0
- thop/vision/efficientnet.py +9 -0
- thop/vision/onnx_counter.py +351 -0
- ultralytics_thop-0.0.1.dist-info/LICENSE +661 -0
- ultralytics_thop-0.0.1.dist-info/METADATA +846 -0
- ultralytics_thop-0.0.1.dist-info/RECORD +17 -0
- ultralytics_thop-0.0.1.dist-info/WHEEL +5 -0
- ultralytics_thop-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -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
|
+
}
|