MLECO-2488: added model optimization options and updated OptimizerOptions constructor.

Signed-off-by: alexander <alexander.efremov@arm.com>
Change-Id: Ic2ad6a46c3830f2526ba8b20ca0db0780be4b9a2
diff --git a/python/pyarmnn/test/test_modeloption.py b/python/pyarmnn/test/test_modeloption.py
new file mode 100644
index 0000000..c03d4a8
--- /dev/null
+++ b/python/pyarmnn/test/test_modeloption.py
@@ -0,0 +1,149 @@
+# Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
+# SPDX-License-Identifier: MIT
+import pytest
+
+from pyarmnn import BackendOptions, BackendOption, BackendId, OptimizerOptions, ShapeInferenceMethod_InferAndValidate
+
+
+@pytest.mark.parametrize("data", (True, -100, 128, 0.12345, 'string'))
+def test_backend_option_ctor(data):
+    bo = BackendOption("name", data)
+    assert "name" == bo.GetName()
+
+
+def test_backend_options_ctor():
+    backend_id = BackendId('a')
+    bos = BackendOptions(backend_id)
+
+    assert 'a' == str(bos.GetBackendId())
+
+    another_bos = BackendOptions(bos)
+    assert 'a' == str(another_bos.GetBackendId())
+
+
+def test_backend_options_add():
+    backend_id = BackendId('a')
+    bos = BackendOptions(backend_id)
+    bo = BackendOption("name", 1)
+    bos.AddOption(bo)
+
+    assert 1 == bos.GetOptionCount()
+    assert 1 == len(bos)
+
+    assert 'name' == bos[0].GetName()
+    assert 'name' == bos.GetOption(0).GetName()
+    for option in bos:
+        assert 'name' == option.GetName()
+
+    bos.AddOption(BackendOption("name2", 2))
+
+    assert 2 == bos.GetOptionCount()
+    assert 2 == len(bos)
+
+
+def test_backend_option_ownership():
+    backend_id = BackendId('b')
+    bos = BackendOptions(backend_id)
+    bo = BackendOption('option', True)
+    bos.AddOption(bo)
+
+    assert bo.thisown
+
+    del bo
+
+    assert 1 == bos.GetOptionCount()
+    option = bos[0]
+    assert not option.thisown
+    assert 'option' == option.GetName()
+
+    del option
+
+    option_again = bos[0]
+    assert not option_again.thisown
+    assert 'option' == option_again.GetName()
+
+
+def test_optimizer_options_with_model_opt():
+    a = BackendOptions(BackendId('a'))
+
+    oo = OptimizerOptions(True,
+                          False,
+                          False,
+                          ShapeInferenceMethod_InferAndValidate,
+                          True,
+                          [a])
+
+    mo = oo.m_ModelOptions
+
+    assert 1 == len(mo)
+    assert 'a' == str(mo[0].GetBackendId())
+
+    b = BackendOptions(BackendId('b'))
+
+    c = BackendOptions(BackendId('c'))
+
+    oo.m_ModelOptions = (a, b, c)
+
+    mo = oo.m_ModelOptions
+
+    assert 3 == len(oo.m_ModelOptions)
+
+    assert 'a' == str(mo[0].GetBackendId())
+    assert 'b' == str(mo[1].GetBackendId())
+    assert 'c' == str(mo[2].GetBackendId())
+
+
+def test_optimizer_option_default():
+    oo = OptimizerOptions(True,
+                          False,
+                          False,
+                          ShapeInferenceMethod_InferAndValidate,
+                          True)
+
+    assert 0 == len(oo.m_ModelOptions)
+
+
+def test_optimizer_options_fail():
+    a = BackendOptions(BackendId('a'))
+
+    with pytest.raises(TypeError) as err:
+        OptimizerOptions(True,
+                         False,
+                         False,
+                         ShapeInferenceMethod_InferAndValidate,
+                         True,
+                         a)
+
+    assert "Wrong number or type of arguments" in str(err.value)
+
+    with pytest.raises(RuntimeError) as err:
+        OptimizerOptions(True,
+                         False,
+                         True,
+                         ShapeInferenceMethod_InferAndValidate,
+                         True,
+                         [a])
+
+    assert "BFloat16 and Float16 optimization cannot be enabled at the same time" in str(err.value)
+
+    with pytest.raises(TypeError) as err:
+        oo = OptimizerOptions(True,
+                              False,
+                              False,
+                              ShapeInferenceMethod_InferAndValidate,
+                              True)
+
+        oo.m_ModelOptions = 'nonsense'
+
+    assert "in method 'OptimizerOptions_m_ModelOptions_set', argument 2" in str(err.value)
+
+    with pytest.raises(TypeError) as err:
+        oo = OptimizerOptions(True,
+                              False,
+                              False,
+                              ShapeInferenceMethod_InferAndValidate,
+                              True)
+
+        oo.m_ModelOptions = ['nonsense', a]
+
+    assert "in method 'OptimizerOptions_m_ModelOptions_set', argument 2" in str(err.value)
diff --git a/python/pyarmnn/test/test_network.py b/python/pyarmnn/test/test_network.py
index c24b113..9b2dbf7 100644
--- a/python/pyarmnn/test/test_network.py
+++ b/python/pyarmnn/test/test_network.py
@@ -6,12 +6,15 @@
 import pytest
 import pyarmnn as ann
 
+
 def test_optimizer_options_default_values():
     opt = ann.OptimizerOptions()
     assert opt.m_ReduceFp32ToFp16 == False
     assert opt.m_Debug == False
     assert opt.m_ReduceFp32ToBf16 == False
     assert opt.m_ImportEnabled == False
+    assert opt.m_shapeInferenceMethod == ann.ShapeInferenceMethod_ValidateOnly
+
 
 def test_optimizer_options_set_values1():
     opt = ann.OptimizerOptions(True, True)
@@ -19,6 +22,8 @@
     assert opt.m_Debug == True
     assert opt.m_ReduceFp32ToBf16 == False
     assert opt.m_ImportEnabled == False
+    assert opt.m_shapeInferenceMethod == ann.ShapeInferenceMethod_ValidateOnly
+
 
 def test_optimizer_options_set_values2():
     opt = ann.OptimizerOptions(False, False, True)
@@ -26,13 +31,17 @@
     assert opt.m_Debug == False
     assert opt.m_ReduceFp32ToBf16 == True
     assert opt.m_ImportEnabled == False
+    assert opt.m_shapeInferenceMethod == ann.ShapeInferenceMethod_ValidateOnly
+
 
 def test_optimizer_options_set_values3():
-    opt = ann.OptimizerOptions(False, False, True, True)
+    opt = ann.OptimizerOptions(False, False, True, ann.ShapeInferenceMethod_InferAndValidate, True)
     assert opt.m_ReduceFp32ToFp16 == False
     assert opt.m_Debug == False
     assert opt.m_ReduceFp32ToBf16 == True
     assert opt.m_ImportEnabled == True
+    assert opt.m_shapeInferenceMethod == ann.ShapeInferenceMethod_InferAndValidate
+
 
 @pytest.fixture(scope="function")
 def get_runtime(shared_data_folder, network_file):
diff --git a/python/pyarmnn/test/test_onnx_parser.py b/python/pyarmnn/test/test_onnx_parser.py
index 99353a0..1424c24 100644
--- a/python/pyarmnn/test/test_onnx_parser.py
+++ b/python/pyarmnn/test/test_onnx_parser.py
@@ -5,7 +5,6 @@
 import pytest
 import pyarmnn as ann
 import numpy as np
-from typing import List
 
 
 @pytest.fixture()
diff --git a/python/pyarmnn/test/test_runtime.py b/python/pyarmnn/test/test_runtime.py
index 295c870..fbdd804 100644
--- a/python/pyarmnn/test/test_runtime.py
+++ b/python/pyarmnn/test/test_runtime.py
@@ -97,6 +97,7 @@
 
     assert not opt_network.thisown
 
+
 def test_load_network(random_runtime):
     preferred_backends = random_runtime[0]
     network = random_runtime[1]
@@ -109,6 +110,7 @@
     assert "" == messages
     assert net_id == 0
 
+
 def test_create_runtime_with_external_profiling_enabled():
 
     options = ann.CreationOptions()
@@ -125,6 +127,7 @@
 
     assert runtime is not None
 
+
 def test_create_runtime_with_external_profiling_enabled_invalid_options():
 
     options = ann.CreationOptions()
@@ -157,6 +160,7 @@
     assert "" == messages
     assert net_id == 0
 
+
 def test_network_properties_constructor(random_runtime):
     preferred_backends = random_runtime[0]
     network = random_runtime[1]
@@ -178,10 +182,12 @@
     assert "" == messages
     assert net_id == 0
 
+
 def test_network_properties_deprecated_constructor():
     with pytest.warns(DeprecationWarning):
         warnings.warn("Deprecated: Use constructor with MemorySource argument instead.", DeprecationWarning)
 
+
 def test_unload_network_fails_for_invalid_net_id(random_runtime):
     preferred_backends = random_runtime[0]
     network = random_runtime[1]
diff --git a/python/pyarmnn/test/test_supported_backends.py b/python/pyarmnn/test/test_supported_backends.py
index e1ca5ee..4ff5eb0 100644
--- a/python/pyarmnn/test/test_supported_backends.py
+++ b/python/pyarmnn/test/test_supported_backends.py
@@ -1,7 +1,5 @@
 # Copyright © 2020 Arm Ltd. All rights reserved.
 # SPDX-License-Identifier: MIT
-import os
-import platform
 import pytest
 import pyarmnn as ann
 
diff --git a/python/pyarmnn/test/test_tflite_parser.py b/python/pyarmnn/test/test_tflite_parser.py
index 8735eef..2764f3f 100644
--- a/python/pyarmnn/test/test_tflite_parser.py
+++ b/python/pyarmnn/test/test_tflite_parser.py
@@ -48,6 +48,7 @@
     parserOptions.m_InferAndValidate = True
     return ann.ITfLiteParser(parserOptions)
 
+
 def test_tflite_parser_with_optional_options_out_of_scope(shared_data_folder):
     parser = create_with_opt()
     network = parser.CreateNetworkFromBinaryFile(os.path.join(shared_data_folder, "mock_model.tflite"))