diff options
author | Hyeongseok Oh <hseok82.oh@samsung.com> | 2023-04-12 15:42:02 +0900 |
---|---|---|
committer | Hyeongseok Oh <hseok82.oh@samsung.com> | 2023-04-12 15:42:02 +0900 |
commit | 323663bb115ef625642391a5a8e9b35fee8b2ae3 (patch) | |
tree | 17e2a6b91535e6f53f4cacda5e4db6aa0303dd22 /compiler/visq-unittest | |
parent | c690d52bdd137ed6a17353aa7af35e8141ece77b (diff) | |
download | nnfw-323663bb115ef625642391a5a8e9b35fee8b2ae3.tar.gz nnfw-323663bb115ef625642391a5a8e9b35fee8b2ae3.tar.bz2 nnfw-323663bb115ef625642391a5a8e9b35fee8b2ae3.zip |
Imported Upstream version 1.22.0upstream/1.22.0
Diffstat (limited to 'compiler/visq-unittest')
-rw-r--r-- | compiler/visq-unittest/CMakeLists.txt | 66 | ||||
-rw-r--r-- | compiler/visq-unittest/README.md | 3 | ||||
-rw-r--r-- | compiler/visq-unittest/requires.cmake | 3 | ||||
-rw-r--r-- | compiler/visq-unittest/test/__init__.py | 1 | ||||
-rw-r--r-- | compiler/visq-unittest/test/testDotBuilder.py | 44 | ||||
-rw-r--r-- | compiler/visq-unittest/test/testPalette.py | 42 | ||||
-rw-r--r-- | compiler/visq-unittest/test/testQErrorComputer.py | 150 | ||||
-rw-r--r-- | compiler/visq-unittest/test/testUtil.py | 55 |
8 files changed, 364 insertions, 0 deletions
diff --git a/compiler/visq-unittest/CMakeLists.txt b/compiler/visq-unittest/CMakeLists.txt new file mode 100644 index 000000000..4eefa8dfd --- /dev/null +++ b/compiler/visq-unittest/CMakeLists.txt @@ -0,0 +1,66 @@ +if(NOT ENABLE_TEST) + return() +endif(NOT ENABLE_TEST) + +unset(VISQ_TEST_DEPS) + +### +### Copy test files +### +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/test ${CMAKE_CURRENT_BINARY_DIR}/test) + +list(APPEND VISQ_TEST_DEPS ${CMAKE_CURRENT_BINARY_DIR}/test) + +### +### Import visqlib module +### +get_target_property(VISQ_BIN_PATH visq BINARY_DIR) +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/visqlib + COMMAND ${CMAKE_COMMAND} -E create_symlink + ${VISQ_BIN_PATH}/visqlib ${CMAKE_CURRENT_BINARY_DIR}/visqlib) + +list(APPEND VISQ_TEST_DEPS ${CMAKE_CURRENT_BINARY_DIR}/visqlib) + +### +### Import pics module +### +get_target_property(PICS_BIN_PATH pics BINARY_DIR) +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/circle + COMMAND ${CMAKE_COMMAND} -E create_symlink + ${PICS_BIN_PATH}/circle ${CMAKE_CURRENT_BINARY_DIR}/circle) + +list(APPEND VISQ_TEST_DEPS ${CMAKE_CURRENT_BINARY_DIR}/circle) + +### +### Generate Resources.py +### +set(RESOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/test/Resources.py") + +get_target_property(FP32_MODEL_DIR testDataGenerator BINARY_DIR) + +add_custom_command( + OUTPUT ${RESOURCE_FILE} + COMMAND ${CMAKE_COMMAND} -E echo 'fp32_model_dir=\"${FP32_MODEL_DIR}\"' >> ${RESOURCE_FILE} + COMMENT "Generate file to specify resource location" +) + +list(APPEND VISQ_TEST_DEPS ${RESOURCE_FILE}) + +add_custom_target(visq_unittest ALL DEPENDS ${VISQ_TEST_DEPS}) + +# Use Python in venv to run unittest with pydot module +add_test( + NAME visq_unittest + COMMAND ${NNCC_OVERLAY_DIR}/venv_2_8_0/bin/python -m unittest + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +) + +if(ONE_UBUNTU_CODENAME_JAMMY) + add_test( + NAME visq_210_unittest + COMMAND ${NNCC_OVERLAY_DIR}/venv_2_10_1/bin/python -m unittest + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) +endif(ONE_UBUNTU_CODENAME_JAMMY) diff --git a/compiler/visq-unittest/README.md b/compiler/visq-unittest/README.md new file mode 100644 index 000000000..e90837b4e --- /dev/null +++ b/compiler/visq-unittest/README.md @@ -0,0 +1,3 @@ +# visq-unittest + +_visq-unittest_ is a module to test visq diff --git a/compiler/visq-unittest/requires.cmake b/compiler/visq-unittest/requires.cmake new file mode 100644 index 000000000..bf7a41fcd --- /dev/null +++ b/compiler/visq-unittest/requires.cmake @@ -0,0 +1,3 @@ +require("pics") +require("common-artifacts") +require("visq") diff --git a/compiler/visq-unittest/test/__init__.py b/compiler/visq-unittest/test/__init__.py new file mode 100644 index 000000000..0c29109f0 --- /dev/null +++ b/compiler/visq-unittest/test/__init__.py @@ -0,0 +1 @@ +# DO NOT REMOVE THIS FILE diff --git a/compiler/visq-unittest/test/testDotBuilder.py b/compiler/visq-unittest/test/testDotBuilder.py new file mode 100644 index 000000000..b657d60c5 --- /dev/null +++ b/compiler/visq-unittest/test/testDotBuilder.py @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test visqlib.DotBuilder module""" + +import unittest +import pydot +from pathlib import Path + +from visqlib.DotBuilder import DotBuilder +from test.Resources import fp32_model_dir + + +class VisqDotBuilderTest(unittest.TestCase): + def test_dot_builder_wrong_input_file(self): + self.assertRaises(FileNotFoundError, DotBuilder, "wrong", "wrong", "wrong", + "wrong") + + def test_dot_builder(self): + test_colors = [{"b": 0, "e": 0.5, "c": "green"}, {"b": 0.5, "e": 1, "c": "red"}] + test_qerror_map = dict() + test_qerror_map["ofm"] = 0.1 + builder = DotBuilder(fp32_model_dir + "/Add_000.circle", "Add_000.dot", "MPEIR", + test_colors) + builder.save(test_qerror_map) + + graph = pydot.graph_from_dot_file("Add_000.dot")[0] + # Why 1? 0 is output + ofm_node = graph.get_node("\"ofm\"")[1] + self.assertEqual("green", ofm_node.get_fillcolor()) + + +if __name__ == "__main__": + unittest.main() diff --git a/compiler/visq-unittest/test/testPalette.py b/compiler/visq-unittest/test/testPalette.py new file mode 100644 index 000000000..bf5fbb42e --- /dev/null +++ b/compiler/visq-unittest/test/testPalette.py @@ -0,0 +1,42 @@ +# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +'''Test visqlib.Palette module''' + +import unittest + +from visqlib.Palette import YLORRD9Palette + + +class VisqPaletteTest(unittest.TestCase): + def test_ylorrd9(self): + min_test = [0.0, 0, -100, -100] + max_test = [1.0, 500, 100, -10] + + for min_val, max_val in zip(min_test, max_test): + palette = YLORRD9Palette(qerror_min=min_val, qerror_max=max_val) + cs = palette.colorscheme() + self.assertEqual(9, len(cs)) + + def test_ylorrd9_wrong_minmax(self): + min_test = [0.0, 10] + max_test = [0.0, 0] + + for min_val, max_val in zip(min_test, max_test): + # min must be less than max + self.assertRaises( + RuntimeError, YLORRD9Palette, qerror_min=min_val, qerror_max=max_val) + + +if __name__ == '__main__': + unittest.main() diff --git a/compiler/visq-unittest/test/testQErrorComputer.py b/compiler/visq-unittest/test/testQErrorComputer.py new file mode 100644 index 000000000..1c6b18556 --- /dev/null +++ b/compiler/visq-unittest/test/testQErrorComputer.py @@ -0,0 +1,150 @@ +# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +'''Test visqlib.QErrorComputer module''' + +import unittest +import tempfile +import numpy as np +import os + +from visqlib.QErrorComputer import MPEIRComputer +from visqlib.QErrorComputer import MSEComputer +from visqlib.QErrorComputer import TAEComputer + + +class VisqQErrorComputerTest(unittest.TestCase): + def setUp(self): + "Called before running each test" + self.fp32_dir = tempfile.TemporaryDirectory() + self.fq_dir = tempfile.TemporaryDirectory() + + def tearDown(self): + "Called after running each test" + self.fp32_dir.cleanup() + self.fq_dir.cleanup() + + def _setUpSingleTensorData(self): + with open(self.fp32_dir.name + '/tensors.txt', 'w') as f: + f.write('test') + with open(self.fq_dir.name + '/tensors.txt', 'w') as f: + f.write('test') + os.mkdir(self.fp32_dir.name + '/0') + os.mkdir(self.fq_dir.name + '/0') + test_data = np.zeros(16) + np.save(self.fp32_dir.name + '/0/test.npy', test_data) + np.save(self.fq_dir.name + '/0/test.npy', test_data) + + def _setUpTwoTensorData(self): + with open(self.fp32_dir.name + '/tensors.txt', 'w') as f: + f.write('test') + with open(self.fq_dir.name + '/tensors.txt', 'w') as f: + f.write('test') + os.mkdir(self.fp32_dir.name + '/0') + os.mkdir(self.fp32_dir.name + '/1') + os.mkdir(self.fq_dir.name + '/0') + os.mkdir(self.fq_dir.name + '/1') + test_data_one = np.ones(16) + test_data_zero = np.zeros(16) + np.save(self.fp32_dir.name + '/0/test.npy', test_data_one) + np.save(self.fp32_dir.name + '/1/test.npy', test_data_zero) + np.save(self.fq_dir.name + '/0/test.npy', test_data_zero) + np.save(self.fq_dir.name + '/1/test.npy', test_data_zero) + # Golden: (1 + 0) / 2 = 0.5 for MSE + + def _setUpDifferentTensorData(self): + # Two fp32 data (test, test2) + # One fq data (test) + # NOTE When does this happen? + # This case can happen because visq ignores nodes that do not affect qerrors. + # For example, RESHAPE Op does not affect qerrors, so its fq data is not dumped, + # although it is listed in 'tensors.txt'. + with open(self.fp32_dir.name + '/tensors.txt', 'w') as f: + f.writelines(['test\n', 'test2']) + with open(self.fq_dir.name + '/tensors.txt', 'w') as f: + f.writelines(['test\n', 'test2']) + os.mkdir(self.fp32_dir.name + '/0') + os.mkdir(self.fq_dir.name + '/0') + test_data = np.zeros(16) + np.save(self.fp32_dir.name + '/0/test.npy', test_data) + np.save(self.fp32_dir.name + '/0/test2.npy', test_data) + np.save(self.fq_dir.name + '/0/test.npy', test_data) + + def test_MPEIR(self): + self._setUpSingleTensorData() + + computer = MPEIRComputer(self.fp32_dir.name, self.fq_dir.name) + qmap = computer.run() + self.assertAlmostEqual(0.0, qmap['test']) + + def test_MPEIR_different_tensors(self): + self._setUpDifferentTensorData() + + computer = MPEIRComputer(self.fp32_dir.name, self.fq_dir.name) + qmap = computer.run() + self.assertAlmostEqual(0.0, qmap['test']) + + def test_MSE(self): + self._setUpSingleTensorData() + + computer = MSEComputer(self.fp32_dir.name, self.fq_dir.name) + qmap, qmin, qmax = computer.run() + self.assertAlmostEqual(0.0, qmap['test']) + self.assertAlmostEqual(0.0, qmin) + self.assertAlmostEqual(0.0, qmax) + + def test_MSE_two(self): + self._setUpTwoTensorData() + + computer = MSEComputer(self.fp32_dir.name, self.fq_dir.name) + qmap, qmin, qmax = computer.run() + self.assertAlmostEqual(0.5, qmap['test']) + self.assertAlmostEqual(0.0, qmin) + self.assertAlmostEqual(1.0, qmax) + + def test_MSE_different_tensors(self): + self._setUpDifferentTensorData() + + computer = MSEComputer(self.fp32_dir.name, self.fq_dir.name) + qmap, qmin, qmax = computer.run() + self.assertAlmostEqual(0.0, qmap['test']) + self.assertAlmostEqual(0.0, qmin) + self.assertAlmostEqual(0.0, qmax) + + def test_TAE(self): + self._setUpSingleTensorData() + + computer = TAEComputer(self.fp32_dir.name, self.fq_dir.name) + qmap, qmin, qmax = computer.run() + self.assertAlmostEqual(0.0, qmap['test']) + + def test_TAE_different_options(self): + self._setUpDifferentTensorData() + + computer = TAEComputer(self.fp32_dir.name, self.fq_dir.name) + qmap, qmin, qmax = computer.run() + self.assertAlmostEqual(0.0, qmap['test']) + self.assertAlmostEqual(0.0, qmin) + self.assertAlmostEqual(0.0, qmax) + + def test_TAE_two(self): + self._setUpTwoTensorData() + computer = TAEComputer(self.fp32_dir.name, self.fq_dir.name) + qmap, qmin, qmax = computer.run() + self.assertAlmostEqual(0.0, qmin) + self.assertAlmostEqual(8.0, qmap['test']) + self.assertAlmostEqual(16.0, qmax) + + +if __name__ == '__main__': + unittest.main() diff --git a/compiler/visq-unittest/test/testUtil.py b/compiler/visq-unittest/test/testUtil.py new file mode 100644 index 000000000..51f6eb98c --- /dev/null +++ b/compiler/visq-unittest/test/testUtil.py @@ -0,0 +1,55 @@ +# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +'''Test visqlib.Util module''' + +import unittest + +from visqlib.Util import to_filename +from visqlib.Util import valid_attr +from visqlib.Util import pretty_float + + +class VisqUtilTest(unittest.TestCase): + def test_to_filename(self): + data = 'abc/d/e' + self.assertEqual('abc_d_e', to_filename(data)) + + long_data = 'x' * 300 + self.assertEqual('x' * 255, to_filename(long_data)) + + def test_valid_attr(self): + class Test: + def __init__(self): + self.a = 'a' + + test = Test() + self.assertTrue(valid_attr(test, 'a')) + self.assertFalse(valid_attr(test, 'b')) + + def test_pretty_float(self): + test_configs = [0.123456, 12.3456, [0.123456], {'test': [0.123456]}] + three_digits_ans = [0.123, 12.346, [0.123], {'test': [0.123]}] + for test_data, ans in zip(test_configs, three_digits_ans): + res = pretty_float(test_data, ndigits=3) + self.assertEqual(res, ans) + + test_configs = [0.123456, 12.3456, [0.123456], {'test': [0.123456]}] + four_digits_ans = [0.1235, 12.3456, [0.1235], {'test': [0.1235]}] + for test_data, ans in zip(test_configs, four_digits_ans): + res = pretty_float(test_data, ndigits=4) + self.assertEqual(res, ans) + + +if __name__ == '__main__': + unittest.main() |