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