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