blob: 5334cc50c0d46a94b5770d20234145141cb7ef26 [file] [log] [blame]
Matthew Bentham245d64c2019-12-02 12:59:43 +00001# Copyright © 2019 Arm Ltd. All rights reserved.
2# SPDX-License-Identifier: MIT
3import os
4import stat
5import platform
6
7import pytest
8import pyarmnn as ann
9
10
11@pytest.fixture(scope="function")
12def get_runtime(shared_data_folder, network_file):
13 parser= ann.ITfLiteParser()
14 preferred_backends = [ann.BackendId('CpuAcc'), ann.BackendId('CpuRef')]
15 network = parser.CreateNetworkFromBinaryFile(os.path.join(shared_data_folder, network_file))
16 options = ann.CreationOptions()
17 runtime = ann.IRuntime(options)
18
19 yield preferred_backends, network, runtime
20
21
22@pytest.mark.parametrize("network_file",
23 [
24 'inception_v3_quant.tflite',
25 'ssd_mobilenetv1.tflite'
26 ],
27 ids=['inception v3', 'mobilenetssd v1'])
28def test_optimize_executes_successfully(network_file, get_runtime):
29 preferred_backends = [ann.BackendId('CpuRef')]
30 network = get_runtime[1]
31 runtime = get_runtime[2]
32
33 opt_network, messages = ann.Optimize(network, preferred_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
34
35 assert len(messages) == 0, 'With only CpuRef, there should be no warnings irrelevant of architecture.'
36 assert opt_network
37
38
39@pytest.mark.parametrize("network_file",
40 [
41 'inception_v3_quant.tflite',
42 ],
43 ids=['inception v3'])
44def test_optimize_owned_by_python(network_file, get_runtime):
45 preferred_backends = get_runtime[0]
46 network = get_runtime[1]
47 runtime = get_runtime[2]
48
49 opt_network, _ = ann.Optimize(network, preferred_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
50 assert opt_network.thisown
51
52
53@pytest.mark.juno
54@pytest.mark.parametrize("network_file",
55 [
56 ('inception_v3_quant.tflite')
57 ],
58 ids=['inception v3'])
59def test_optimize_executes_successfully_for_neon_backend_only(network_file, get_runtime):
60 preferred_backends = [ann.BackendId('CpuAcc')]
61 network = get_runtime[1]
62 runtime = get_runtime[2]
63
64 opt_network, messages = ann.Optimize(network, preferred_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
65 assert 0 == len(messages)
66 assert opt_network
67
68
69@pytest.mark.parametrize("network_file",
70 [
71 'inception_v3_quant.tflite'
72 ],
73 ids=['inception v3'])
74def test_optimize_fails_for_invalid_backends(network_file, get_runtime):
75 invalid_backends = [ann.BackendId('Unknown')]
76 network = get_runtime[1]
77 runtime = get_runtime[2]
78
79 with pytest.raises(RuntimeError) as err:
80 ann.Optimize(network, invalid_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
81
82 expected_error_message = "None of the preferred backends [Unknown ] are supported."
83 assert expected_error_message in str(err.value)
84
85
86@pytest.mark.parametrize("network_file",
87 [
88 'inception_v3_quant.tflite'
89 ],
90 ids=['inception v3'])
91def test_optimize_fails_for_no_backends_specified(network_file, get_runtime):
92 empty_backends = []
93 network = get_runtime[1]
94 runtime = get_runtime[2]
95
96 with pytest.raises(RuntimeError) as err:
97 ann.Optimize(network, empty_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
98
99 expected_error_message = "Invoked Optimize with no backends specified"
100 assert expected_error_message in str(err.value)
101
102
103@pytest.mark.parametrize("network_file",
104 [
105 'inception_v3_quant.tflite'
106 ],
107 ids=['inception v3'])
108def test_serialize_to_dot(network_file, get_runtime, tmpdir):
109 preferred_backends = get_runtime[0]
110 network = get_runtime[1]
111 runtime = get_runtime[2]
112 opt_network, _ = ann.Optimize(network, preferred_backends,
113 runtime.GetDeviceSpec(), ann.OptimizerOptions())
114 dot_file_path = os.path.join(tmpdir, 'ssd.dot')
115 """Check that serialized file does not exist at the start, gets created after SerializeToDot and is not empty"""
116 assert not os.path.exists(dot_file_path)
117 opt_network.SerializeToDot(dot_file_path)
118
119 assert os.path.exists(dot_file_path)
120
121 with open(dot_file_path) as res_file:
122 expected_data = res_file.read()
123 assert len(expected_data) > 1
124 assert '[label=< [1,299,299,3] >]' in expected_data
125
126
127@pytest.mark.skipif(platform.processor() != 'x86_64', reason="Platform specific test")
128@pytest.mark.parametrize("network_file",
129 [
130 'inception_v3_quant.tflite'
131 ],
132 ids=['inception v3'])
133def test_serialize_to_dot_mode_readonly(network_file, get_runtime, tmpdir):
134 preferred_backends = get_runtime[0]
135 network = get_runtime[1]
136 runtime = get_runtime[2]
137 opt_network, _ = ann.Optimize(network, preferred_backends,
138 runtime.GetDeviceSpec(), ann.OptimizerOptions())
139 """Create file, write to it and change mode to read-only"""
140 dot_file_path = os.path.join(tmpdir, 'ssd.dot')
141 f = open(dot_file_path, "w+")
142 f.write("test")
143 f.close()
144 os.chmod(dot_file_path, stat.S_IREAD)
145 assert os.path.exists(dot_file_path)
146
147 with pytest.raises(RuntimeError) as err:
148 opt_network.SerializeToDot(dot_file_path)
149
150 expected_error_message = "Failed to open dot file"
151 assert expected_error_message in str(err.value)
152
153
154@pytest.mark.juno
155@pytest.mark.parametrize("network_file",
156 [
157 'ssd_mobilenetv1.tflite'
158 ],
159 ids=['mobilenetssd v1'])
160def test_optimize_error_tuple(network_file, get_runtime):
161 preferred_backends = get_runtime[0]
162 network = get_runtime[1]
163 runtime = get_runtime[2]
164
165 opt_network, error_messages = ann.Optimize(network, preferred_backends,
166 runtime.GetDeviceSpec(), ann.OptimizerOptions())
167
168 assert type(error_messages) == tuple
169 assert 'WARNING: Layer of type DetectionPostProcess is not supported on requested backend CpuAcc for input data ' \
170 'type QAsymm8' in error_messages[0]
171
172
173@pytest.mark.parametrize("method", [
174 'AddAbsLayer',
175 'AddActivationLayer',
176 'AddAdditionLayer',
177 'AddArgMinMaxLayer',
178 'AddBatchNormalizationLayer',
179 'AddBatchToSpaceNdLayer',
180 'AddComparisonLayer',
181 'AddConcatLayer',
182 'AddConstantLayer',
183 'AddConvolution2dLayer',
184 'AddDepthToSpaceLayer',
185 'AddDepthwiseConvolution2dLayer',
186 'AddDequantizeLayer',
187 'AddDetectionPostProcessLayer',
188 'AddDivisionLayer',
189 'AddFloorLayer',
190 'AddFullyConnectedLayer',
191 'AddGatherLayer',
192 'AddInputLayer',
193 'AddInstanceNormalizationLayer',
194 'AddLogSoftmaxLayer',
195 'AddL2NormalizationLayer',
196 'AddLstmLayer',
197 'AddMaximumLayer',
198 'AddMeanLayer',
199 'AddMergeLayer',
200 'AddMinimumLayer',
201 'AddMultiplicationLayer',
202 'AddNormalizationLayer',
203 'AddOutputLayer',
204 'AddPadLayer',
205 'AddPermuteLayer',
206 'AddPooling2dLayer',
207 'AddPreluLayer',
208 'AddQuantizeLayer',
209 'AddQuantizedLstmLayer',
210 'AddReshapeLayer',
211 'AddResizeLayer',
212 'AddRsqrtLayer',
213 'AddSliceLayer',
214 'AddSoftmaxLayer',
215 'AddSpaceToBatchNdLayer',
216 'AddSpaceToDepthLayer',
217 'AddSplitterLayer',
218 'AddStackLayer',
219 'AddStandInLayer',
220 'AddStridedSliceLayer',
221 'AddSubtractionLayer',
222 'AddSwitchLayer',
223 'AddTransposeConvolution2dLayer'
224])
225def test_network_method_exists(method):
226 assert getattr(ann.INetwork, method, None)
227
228
229def test_fullyconnected_layer_optional_none():
230 net = ann.INetwork()
231 layer = net.AddFullyConnectedLayer(fullyConnectedDescriptor=ann.FullyConnectedDescriptor(),
232 weights=ann.ConstTensor())
233
234 assert layer
235
236
237def test_fullyconnected_layer_optional_provided():
238 net = ann.INetwork()
239 layer = net.AddFullyConnectedLayer(fullyConnectedDescriptor=ann.FullyConnectedDescriptor(),
240 weights=ann.ConstTensor(),
241 biases=ann.ConstTensor())
242
243 assert layer
244
245
246def test_fullyconnected_layer_all_args():
247 net = ann.INetwork()
248 layer = net.AddFullyConnectedLayer(fullyConnectedDescriptor=ann.FullyConnectedDescriptor(),
249 weights=ann.ConstTensor(),
250 biases=ann.ConstTensor(),
251 name='NAME1')
252
253 assert layer
254 assert 'NAME1' == layer.GetName()
255
256
257def test_DepthwiseConvolution2d_layer_optional_none():
258 net = ann.INetwork()
259 layer = net.AddDepthwiseConvolution2dLayer(convolution2dDescriptor=ann.DepthwiseConvolution2dDescriptor(),
260 weights=ann.ConstTensor())
261
262 assert layer
263
264
265def test_DepthwiseConvolution2d_layer_optional_provided():
266 net = ann.INetwork()
267 layer = net.AddDepthwiseConvolution2dLayer(convolution2dDescriptor=ann.DepthwiseConvolution2dDescriptor(),
268 weights=ann.ConstTensor(),
269 biases=ann.ConstTensor())
270
271 assert layer
272
273
274def test_DepthwiseConvolution2d_layer_all_args():
275 net = ann.INetwork()
276 layer = net.AddDepthwiseConvolution2dLayer(convolution2dDescriptor=ann.DepthwiseConvolution2dDescriptor(),
277 weights=ann.ConstTensor(),
278 biases=ann.ConstTensor(),
279 name='NAME1')
280
281 assert layer
282 assert 'NAME1' == layer.GetName()
283
284
285def test_Convolution2d_layer_optional_none():
286 net = ann.INetwork()
287 layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(),
288 weights=ann.ConstTensor())
289
290 assert layer
291
292
293def test_Convolution2d_layer_optional_provided():
294 net = ann.INetwork()
295 layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(),
296 weights=ann.ConstTensor(),
297 biases=ann.ConstTensor())
298
299 assert layer
300
301
302def test_Convolution2d_layer_all_args():
303 net = ann.INetwork()
304 layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(),
305 weights=ann.ConstTensor(),
306 biases=ann.ConstTensor(),
307 name='NAME1')
308
309 assert layer
310 assert 'NAME1' == layer.GetName()