summaryrefslogtreecommitdiff
path: root/compiler/visq-unittest
diff options
context:
space:
mode:
authorHyeongseok Oh <hseok82.oh@samsung.com>2023-04-12 15:42:02 +0900
committerHyeongseok Oh <hseok82.oh@samsung.com>2023-04-12 15:42:02 +0900
commit323663bb115ef625642391a5a8e9b35fee8b2ae3 (patch)
tree17e2a6b91535e6f53f4cacda5e4db6aa0303dd22 /compiler/visq-unittest
parentc690d52bdd137ed6a17353aa7af35e8141ece77b (diff)
downloadnnfw-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.txt66
-rw-r--r--compiler/visq-unittest/README.md3
-rw-r--r--compiler/visq-unittest/requires.cmake3
-rw-r--r--compiler/visq-unittest/test/__init__.py1
-rw-r--r--compiler/visq-unittest/test/testDotBuilder.py44
-rw-r--r--compiler/visq-unittest/test/testPalette.py42
-rw-r--r--compiler/visq-unittest/test/testQErrorComputer.py150
-rw-r--r--compiler/visq-unittest/test/testUtil.py55
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()