blob: fc2591c1d5468ded390329b28097e2bc328acb59 [file] [log] [blame]
# Copyright © 2020 Arm Ltd. All rights reserved.
# SPDX-License-Identifier: MIT
import os
import stat
import pytest
import pyarmnn as ann
@pytest.fixture(scope="function")
def get_runtime(shared_data_folder, network_file):
parser= ann.ITfLiteParser()
preferred_backends = [ann.BackendId('CpuAcc'), ann.BackendId('CpuRef')]
network = parser.CreateNetworkFromBinaryFile(os.path.join(shared_data_folder, network_file))
options = ann.CreationOptions()
runtime = ann.IRuntime(options)
yield preferred_backends, network, runtime
@pytest.mark.parametrize("network_file",
[
'mock_model.tflite',
],
ids=['mock_model'])
def test_optimize_executes_successfully(network_file, get_runtime):
preferred_backends = [ann.BackendId('CpuRef')]
network = get_runtime[1]
runtime = get_runtime[2]
opt_network, messages = ann.Optimize(network, preferred_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
assert len(messages) == 0, 'With only CpuRef, there should be no warnings irrelevant of architecture.'
assert opt_network
@pytest.mark.parametrize("network_file",
[
'mock_model.tflite',
],
ids=['mock_model'])
def test_optimize_owned_by_python(network_file, get_runtime):
preferred_backends = get_runtime[0]
network = get_runtime[1]
runtime = get_runtime[2]
opt_network, _ = ann.Optimize(network, preferred_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
assert opt_network.thisown
@pytest.mark.aarch64
@pytest.mark.parametrize("network_file",
[
'mock_model.tflite'
],
ids=['mock_model'])
def test_optimize_executes_successfully_for_neon_backend_only(network_file, get_runtime):
preferred_backends = [ann.BackendId('CpuAcc')]
network = get_runtime[1]
runtime = get_runtime[2]
opt_network, messages = ann.Optimize(network, preferred_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
assert 0 == len(messages)
assert opt_network
@pytest.mark.parametrize("network_file",
[
'mock_model.tflite'
],
ids=['mock_model'])
def test_optimize_fails_for_invalid_backends(network_file, get_runtime):
invalid_backends = [ann.BackendId('Unknown')]
network = get_runtime[1]
runtime = get_runtime[2]
with pytest.raises(RuntimeError) as err:
ann.Optimize(network, invalid_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
expected_error_message = "None of the preferred backends [Unknown ] are supported."
assert expected_error_message in str(err.value)
@pytest.mark.parametrize("network_file",
[
'mock_model.tflite'
],
ids=['mock_model'])
def test_optimize_fails_for_no_backends_specified(network_file, get_runtime):
empty_backends = []
network = get_runtime[1]
runtime = get_runtime[2]
with pytest.raises(RuntimeError) as err:
ann.Optimize(network, empty_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
expected_error_message = "Invoked Optimize with no backends specified"
assert expected_error_message in str(err.value)
@pytest.mark.parametrize("network_file",
[
'mock_model.tflite'
],
ids=['mock_model'])
def test_serialize_to_dot(network_file, get_runtime, tmpdir):
preferred_backends = get_runtime[0]
network = get_runtime[1]
runtime = get_runtime[2]
opt_network, _ = ann.Optimize(network, preferred_backends,
runtime.GetDeviceSpec(), ann.OptimizerOptions())
dot_file_path = os.path.join(tmpdir, 'mock_model.dot')
"""Check that serialized file does not exist at the start, gets created after SerializeToDot and is not empty"""
assert not os.path.exists(dot_file_path)
opt_network.SerializeToDot(dot_file_path)
assert os.path.exists(dot_file_path)
with open(dot_file_path) as res_file:
expected_data = res_file.read()
assert len(expected_data) > 1
assert '[label=< [1,28,28,1] >]' in expected_data
@pytest.mark.x86_64
@pytest.mark.parametrize("network_file",
[
'mock_model.tflite'
],
ids=['mock_model'])
def test_serialize_to_dot_mode_readonly(network_file, get_runtime, tmpdir):
preferred_backends = get_runtime[0]
network = get_runtime[1]
runtime = get_runtime[2]
opt_network, _ = ann.Optimize(network, preferred_backends,
runtime.GetDeviceSpec(), ann.OptimizerOptions())
"""Create file, write to it and change mode to read-only"""
dot_file_path = os.path.join(tmpdir, 'mock_model.dot')
f = open(dot_file_path, "w+")
f.write("test")
f.close()
os.chmod(dot_file_path, stat.S_IREAD)
assert os.path.exists(dot_file_path)
with pytest.raises(RuntimeError) as err:
opt_network.SerializeToDot(dot_file_path)
expected_error_message = "Failed to open dot file"
assert expected_error_message in str(err.value)
@pytest.mark.parametrize("method", [
'AddActivationLayer',
'AddAdditionLayer',
'AddArgMinMaxLayer',
'AddBatchNormalizationLayer',
'AddBatchToSpaceNdLayer',
'AddComparisonLayer',
'AddConcatLayer',
'AddConstantLayer',
'AddConvolution2dLayer',
'AddDepthToSpaceLayer',
'AddDepthwiseConvolution2dLayer',
'AddDequantizeLayer',
'AddDetectionPostProcessLayer',
'AddDivisionLayer',
'AddElementwiseUnaryLayer',
'AddFloorLayer',
'AddFullyConnectedLayer',
'AddGatherLayer',
'AddInputLayer',
'AddInstanceNormalizationLayer',
'AddLogSoftmaxLayer',
'AddL2NormalizationLayer',
'AddLstmLayer',
'AddMaximumLayer',
'AddMeanLayer',
'AddMergeLayer',
'AddMinimumLayer',
'AddMultiplicationLayer',
'AddNormalizationLayer',
'AddOutputLayer',
'AddPadLayer',
'AddPermuteLayer',
'AddPooling2dLayer',
'AddPreluLayer',
'AddQuantizeLayer',
'AddQuantizedLstmLayer',
'AddReshapeLayer',
'AddResizeLayer',
'AddSliceLayer',
'AddSoftmaxLayer',
'AddSpaceToBatchNdLayer',
'AddSpaceToDepthLayer',
'AddSplitterLayer',
'AddStackLayer',
'AddStandInLayer',
'AddStridedSliceLayer',
'AddSubtractionLayer',
'AddSwitchLayer',
'AddTransposeConvolution2dLayer'
])
def test_network_method_exists(method):
assert getattr(ann.INetwork, method, None)
def test_fullyconnected_layer_optional_none():
net = ann.INetwork()
layer = net.AddFullyConnectedLayer(fullyConnectedDescriptor=ann.FullyConnectedDescriptor(),
weights=ann.ConstTensor())
assert layer
def test_fullyconnected_layer_optional_provided():
net = ann.INetwork()
layer = net.AddFullyConnectedLayer(fullyConnectedDescriptor=ann.FullyConnectedDescriptor(),
weights=ann.ConstTensor(),
biases=ann.ConstTensor())
assert layer
def test_fullyconnected_layer_all_args():
net = ann.INetwork()
layer = net.AddFullyConnectedLayer(fullyConnectedDescriptor=ann.FullyConnectedDescriptor(),
weights=ann.ConstTensor(),
biases=ann.ConstTensor(),
name='NAME1')
assert layer
assert 'NAME1' == layer.GetName()
def test_DepthwiseConvolution2d_layer_optional_none():
net = ann.INetwork()
layer = net.AddDepthwiseConvolution2dLayer(convolution2dDescriptor=ann.DepthwiseConvolution2dDescriptor(),
weights=ann.ConstTensor())
assert layer
def test_DepthwiseConvolution2d_layer_optional_provided():
net = ann.INetwork()
layer = net.AddDepthwiseConvolution2dLayer(convolution2dDescriptor=ann.DepthwiseConvolution2dDescriptor(),
weights=ann.ConstTensor(),
biases=ann.ConstTensor())
assert layer
def test_DepthwiseConvolution2d_layer_all_args():
net = ann.INetwork()
layer = net.AddDepthwiseConvolution2dLayer(convolution2dDescriptor=ann.DepthwiseConvolution2dDescriptor(),
weights=ann.ConstTensor(),
biases=ann.ConstTensor(),
name='NAME1')
assert layer
assert 'NAME1' == layer.GetName()
def test_Convolution2d_layer_optional_none():
net = ann.INetwork()
layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(),
weights=ann.ConstTensor())
assert layer
def test_Convolution2d_layer_optional_provided():
net = ann.INetwork()
layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(),
weights=ann.ConstTensor(),
biases=ann.ConstTensor())
assert layer
def test_Convolution2d_layer_all_args():
net = ann.INetwork()
layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(),
weights=ann.ConstTensor(),
biases=ann.ConstTensor(),
name='NAME1')
assert layer
assert 'NAME1' == layer.GetName()