diff options
author | Chunseok Lee <chunseok.lee@samsung.com> | 2022-09-07 19:04:21 +0900 |
---|---|---|
committer | Chunseok Lee <chunseok.lee@samsung.com> | 2022-09-07 19:04:21 +0900 |
commit | c690d52bdd137ed6a17353aa7af35e8141ece77b (patch) | |
tree | dbb7dd99133132dfbffcb8c9e9af4f1ffc2f4808 /compiler/one-cmds | |
parent | 3ad689f0803519e343c36d5700646e86059df961 (diff) | |
download | nnfw-tizen_7.0_hotfix.tar.gz nnfw-tizen_7.0_hotfix.tar.bz2 nnfw-tizen_7.0_hotfix.zip |
Imported Upstream version 1.21.0upstream/1.21.0tizen_7.0_m2_releaseaccepted/tizen/unified/20220912.170817accepted/tizen/unified/20220912.164738accepted/tizen/7.0/unified/hotfix/20221116.105341accepted/tizen/7.0/unified/20221110.060236tizen_7.0_hotfixtizen_7.0accepted/tizen_7.0_unified_hotfixaccepted/tizen_7.0_unified
Diffstat (limited to 'compiler/one-cmds')
139 files changed, 5214 insertions, 212 deletions
diff --git a/compiler/one-cmds/CMakeLists.txt b/compiler/one-cmds/CMakeLists.txt index 8732340ae..90e989a00 100644 --- a/compiler/one-cmds/CMakeLists.txt +++ b/compiler/one-cmds/CMakeLists.txt @@ -8,7 +8,9 @@ set(ONE_COMMAND_FILES one-optimize one-quantize one-pack + one-partition one-profile + one-infer one-codegen one-prepare-venv onecc @@ -74,7 +76,11 @@ endforeach(ONE_UTILITY) # make python directory set(ONE_PYTHON_FILES constant.py - make_cmd.py) + make_cmd.py + CfgRunner.py + OptionBuilder.py + TopologicalSortHelper.py + WorkflowRunner.py) foreach(ONE_PYTHON_FILE IN ITEMS ${ONE_PYTHON_FILES}) diff --git a/compiler/one-cmds/dummy-driver/CMakeLists.txt b/compiler/one-cmds/dummy-driver/CMakeLists.txt index 690a60776..2552a02db 100644 --- a/compiler/one-cmds/dummy-driver/CMakeLists.txt +++ b/compiler/one-cmds/dummy-driver/CMakeLists.txt @@ -1,16 +1,25 @@ # dummy driver for interface test set(DUMMY_DRIVER_SRC src/dummy-compile.cpp) set(HELP_DRIVER_SRC src/help-compile.cpp) +set(DUMMY_INFER_SRC src/dummy-infer.cpp) +set(DUMMY_INFER_V2_SRC src/dummy-inferV2.cpp) +set(HELP_INFER_SRC src/help-infer.cpp) set(DUMMY_PROFILE_SRC src/dummy-profile.cpp) set(HELP_PROFILE_SRC src/help-profile.cpp) add_executable(dummy-compile ${DUMMY_DRIVER_SRC}) add_executable(help-compile ${HELP_DRIVER_SRC}) +add_executable(dummy-infer ${DUMMY_INFER_SRC}) +add_executable(dummy-inferV2 ${DUMMY_INFER_V2_SRC}) +add_executable(help-infer ${HELP_INFER_SRC}) add_executable(dummy-profile ${DUMMY_PROFILE_SRC}) add_executable(help-profile ${HELP_PROFILE_SRC}) set(DUMMY_DRIVER "${CMAKE_CURRENT_BINARY_DIR}/dummy-compile") set(HELP_DRIVER "${CMAKE_CURRENT_BINARY_DIR}/help-compile") +set(DUMMY_INFER "${CMAKE_CURRENT_BINARY_DIR}/dummy-infer") +set(DUMMY_INFER_V2 "${CMAKE_CURRENT_BINARY_DIR}/dummy-inferV2") +set(HELP_INFER "${CMAKE_CURRENT_BINARY_DIR}/help-infer") set(DUMMY_PROFILE "${CMAKE_CURRENT_BINARY_DIR}/dummy-profile") set(HELP_PROFILE "${CMAKE_CURRENT_BINARY_DIR}/help-profile") @@ -26,6 +35,24 @@ install(FILES ${HELP_DRIVER} WORLD_READ WORLD_EXECUTE DESTINATION test) +install(FILES ${DUMMY_INFER} + PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE + DESTINATION test) + +install(FILES ${DUMMY_INFER_V2} + PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE + DESTINATION test) + +install(FILES ${HELP_INFER} + PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE + DESTINATION test) + install(FILES ${DUMMY_PROFILE} PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE diff --git a/compiler/one-cmds/dummy-driver/src/dummy-infer.cpp b/compiler/one-cmds/dummy-driver/src/dummy-infer.cpp new file mode 100644 index 000000000..60f5faefa --- /dev/null +++ b/compiler/one-cmds/dummy-driver/src/dummy-infer.cpp @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/** + * dummy-infer only tests its interface rather than its functionality. + * + * ./dummy-infer ${INPUT_NAME} + * dummy-infer dummy output!!! + */ + +#include <iostream> + +int main(int argc, char **argv) +{ + if (argc != 2) + return EXIT_FAILURE; + + std::cout << "dummy-infer dummy output!!!" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/compiler/one-cmds/dummy-driver/src/dummy-inferV2.cpp b/compiler/one-cmds/dummy-driver/src/dummy-inferV2.cpp new file mode 100644 index 000000000..4b93c70a3 --- /dev/null +++ b/compiler/one-cmds/dummy-driver/src/dummy-inferV2.cpp @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/** + * dummy-infer only tests its interface rather than its functionality. + * + * ./dummy-infer ${INPUT_NAME} + * Do inference of ${INPUT_NAME} + */ + +#include <iostream> + +int main(int argc, char **argv) +{ + if (argc != 2) + return EXIT_FAILURE; + + std::cout << "Do inference of " + std::string(argv[1]) << std::endl; + + return EXIT_SUCCESS; +} diff --git a/compiler/one-cmds/dummy-driver/src/help-infer.cpp b/compiler/one-cmds/dummy-driver/src/help-infer.cpp new file mode 100644 index 000000000..821d368d4 --- /dev/null +++ b/compiler/one-cmds/dummy-driver/src/help-infer.cpp @@ -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. + */ + +/** + * help-infer prints dummy help message. + * + * $ ./help-infer -h + * HELP MESSAGE!! + */ + +#include <iostream> +#include <fstream> +#include <string> + +int main(int argc, char **argv) +{ + if (argc != 2) + return EXIT_FAILURE; + + std::string opt_h{"-h"}; + std::string argv_1{argv[1]}; + + if (opt_h != argv_1) + return EXIT_FAILURE; + + std::cout << "HELP MESSAGE!!" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/compiler/one-cmds/how-to-use-one-commands.txt b/compiler/one-cmds/how-to-use-one-commands.txt index ebc165167..2352bbd7a 100644 --- a/compiler/one-cmds/how-to-use-one-commands.txt +++ b/compiler/one-cmds/how-to-use-one-commands.txt @@ -153,6 +153,7 @@ Current transformation options are - expand_broadcast_const : This will expand broadcastable constant node inputs - fold_add_v2 : This removes AddV2 operation which can be folded - fold_cast : This removes Cast operation which can be folded +- fold_densify: This removes Densify operator which can be folded - fold_dequantize : This removes Dequantize operation which can be folded - fold_dwconv : This folds Depthwise Convolution operation which can be folded - fold_gather : This removes Gather operation which can be folded @@ -205,10 +206,6 @@ Current transformation options are - transform_min_max_to_relu6: This will transform Minimum-Maximum pattern to Relu6 operator. - transform_min_relu_to_relu6: This will transform Minimum(6)-Relu pattern to Relu6 operator. -There are options to enable multiple options at once for convenience. -- O1: fuse_bcq, fuse_instnorm, resolve_customop_add, resolve_customop_batchmatmul, - resolve_customop_matmul, remove_redundant_transpose, substitute_pack_to_reshape - one-quantize ------------ diff --git a/compiler/one-cmds/one-build b/compiler/one-cmds/one-build index 5c313b44b..4b1f98070 100644 --- a/compiler/one-cmds/one-build +++ b/compiler/one-cmds/one-build @@ -22,7 +22,6 @@ import argparse import configparser import os -import subprocess import sys import utils as _utils @@ -83,6 +82,7 @@ def _get_driver_name(driver_name): 'one-import-onnx': 'one-import-onnx', 'one-optimize': 'one-optimize', 'one-quantize': 'one-quantize', + 'one-partition': 'one-partition', 'one-pack': 'one-pack', 'one-codegen': 'one-codegen' }[driver_name] @@ -157,7 +157,8 @@ def main(): bin_dir = os.path.dirname(os.path.realpath(__file__)) import_drivers_dict = _utils._detect_one_import_drivers(bin_dir) transform_drivers = [ - 'one-optimize', 'one-quantize', 'one-pack', 'one-codegen', 'one-profile' + 'one-optimize', 'one-quantize', 'one-pack', 'one-codegen', 'one-profile', + 'one-partition' ] _verify_cfg(import_drivers_dict, config) diff --git a/compiler/one-cmds/one-build.template.cfg b/compiler/one-cmds/one-build.template.cfg index e147896ef..42960811e 100644 --- a/compiler/one-cmds/one-build.template.cfg +++ b/compiler/one-cmds/one-build.template.cfg @@ -5,6 +5,7 @@ one-import-bcq=False one-import-onnx=False one-optimize=True one-quantize=False +one-parition=False one-pack=True one-codegen=False diff --git a/compiler/one-cmds/one-codegen b/compiler/one-cmds/one-codegen index 726538d44..86e1632e6 100644 --- a/compiler/one-cmds/one-codegen +++ b/compiler/one-cmds/one-codegen @@ -25,9 +25,7 @@ import glob import itertools import ntpath import os -import subprocess import sys -import tempfile import shutil import utils as _utils diff --git a/compiler/one-cmds/one-import-bcq b/compiler/one-cmds/one-import-bcq index ef89a9297..c3ef0b275 100644 --- a/compiler/one-cmds/one-import-bcq +++ b/compiler/one-cmds/one-import-bcq @@ -21,7 +21,6 @@ import argparse import os -import subprocess import sys import tempfile @@ -160,9 +159,9 @@ def _convert(args): tmpdir, os.path.splitext( os.path.basename(generate_bcq_metadata_output_path))[0]) + '.tflite' - tf2tfliteV2_cmd = _make_cmd.make_tf2tfliteV2_cmd(args, tf2tfliteV2_path, - generate_bcq_metadata_output_path, - tf2tfliteV2_output_path) + tf2tfliteV2_cmd = _make_cmd.make_tf2tfliteV2_cmd( + args, tf2tfliteV2_path, generate_bcq_metadata_output_path, + tf2tfliteV2_output_path) try: output_arrays_idx = tf2tfliteV2_cmd.index('--output_arrays') tf2tfliteV2_cmd[output_arrays_idx + 1] = ','.join(bcq_output_arrays) @@ -177,8 +176,8 @@ def _convert(args): # make a command to convert from tflite to circle tflite2circle_path = os.path.join(dir_path, 'tflite2circle') tflite2circle_cmd = _make_cmd.make_tflite2circle_cmd(tflite2circle_path, - tf2tfliteV2_output_path, - getattr(args, 'output_path')) + tf2tfliteV2_output_path, + getattr(args, 'output_path')) f.write((' '.join(tflite2circle_cmd) + '\n').encode()) diff --git a/compiler/one-cmds/one-import-onnx b/compiler/one-cmds/one-import-onnx index eaa136197..ad19c2f59 100644 --- a/compiler/one-cmds/one-import-onnx +++ b/compiler/one-cmds/one-import-onnx @@ -21,7 +21,6 @@ import argparse import os -import subprocess import sys import tempfile import onnx @@ -80,6 +79,12 @@ def _get_parser(): parser.add_argument('--unroll_rnn', action='store_true', help='Unroll RNN operators') parser.add_argument( '--unroll_lstm', action='store_true', help='Unroll LSTM operators') + parser.add_argument( + '--keep_io_order', + action='store_true', + help= + 'Ensure generated circle model preserves the I/O order of the original onnx model.' + ) # save intermediate file(s) parser.add_argument( @@ -87,6 +92,12 @@ def _get_parser(): action='store_true', help='Save intermediate files to output folder') + # experimental options + parser.add_argument( + '--experimental_disable_batchmatmul_unfold', + action='store_true', + help='Experimental disable BatchMatMul unfold') + return parser @@ -124,6 +135,65 @@ def _apply_verbosity(verbosity): os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' +# The index of input/output is added in front of the name. For example, +# Original input names: 'a', 'c', 'b' +# Renamed: '0001_a', '0002_c', '0003_b' +# This will preserve I/O order after import. +def _remap_io_names(onnx_model): + # gather existing name of I/O and generate new name of I/O in sort order + input_nodes = [] + output_nodes = [] + remap_inputs = [] + remap_outputs = [] + initializers = [] + # some models may have initializers as inputs. ignore them. + for initializer in onnx_model.graph.initializer: + initializers.append(initializer.name) + for idx in range(0, len(onnx_model.graph.input)): + name = onnx_model.graph.input[idx].name + if not name in initializers: + input_nodes.append(name) + remap_inputs.append(format(idx + 1, '04d') + '_' + name) + for idx in range(0, len(onnx_model.graph.output)): + name = onnx_model.graph.output[idx].name + output_nodes.append(name) + remap_outputs.append(format(idx + 1, '04d') + '_' + name) + # change names for graph input + for i in range(len(onnx_model.graph.input)): + if onnx_model.graph.input[i].name in input_nodes: + to_rename = onnx_model.graph.input[i].name + idx = input_nodes.index(to_rename) + onnx_model.graph.input[i].name = remap_inputs[idx] + # change names of all nodes in the graph + for i in range(len(onnx_model.graph.node)): + # check node.input is to change to remap_inputs or remap_outputs + for j in range(len(onnx_model.graph.node[i].input)): + if onnx_model.graph.node[i].input[j] in input_nodes: + to_rename = onnx_model.graph.node[i].input[j] + idx = input_nodes.index(to_rename) + onnx_model.graph.node[i].input[j] = remap_inputs[idx] + if onnx_model.graph.node[i].input[j] in output_nodes: + to_rename = onnx_model.graph.node[i].input[j] + idx = output_nodes.index(to_rename) + onnx_model.graph.node[i].input[j] = remap_outputs[idx] + # check node.output is to change to remap_inputs or remap_outputs + for j in range(len(onnx_model.graph.node[i].output)): + if onnx_model.graph.node[i].output[j] in output_nodes: + to_rename = onnx_model.graph.node[i].output[j] + idx = output_nodes.index(to_rename) + onnx_model.graph.node[i].output[j] = remap_outputs[idx] + if onnx_model.graph.node[i].output[j] in input_nodes: + to_rename = onnx_model.graph.node[i].output[j] + idx = input_nodes.index(to_rename) + onnx_model.graph.node[i].output[j] = remap_inputs[idx] + # change names for graph output + for i in range(len(onnx_model.graph.output)): + if onnx_model.graph.output[i].name in output_nodes: + to_rename = onnx_model.graph.output[i].name + idx = output_nodes.index(to_rename) + onnx_model.graph.output[i].name = remap_outputs[idx] + + def _convert(args): _apply_verbosity(args.verbose) @@ -142,6 +212,13 @@ def _convert(args): options.unroll_rnn = _utils._is_valid_attr(args, 'unroll_rnn') options.unroll_lstm = _utils._is_valid_attr(args, 'unroll_lstm') onnx_legalizer.legalize(onnx_model, options) + if _utils._is_valid_attr(args, 'keep_io_order'): + _remap_io_names(onnx_model) + if _utils._is_valid_attr(args, 'save_intermediate'): + basename = os.path.basename(getattr(args, 'input_path')) + fixed_path = os.path.join(tmpdir, + os.path.splitext(basename)[0] + '~.onnx') + onnx.save(onnx_model, fixed_path) tf_savedmodel = onnx_tf.backend.prepare(onnx_model) savedmodel_name = os.path.splitext(os.path.basename( @@ -166,8 +243,8 @@ def _convert(args): # make a command to convert from tflite to circle tflite2circle_path = os.path.join(dir_path, 'tflite2circle') tflite2circle_cmd = _make_cmd.make_tflite2circle_cmd(tflite2circle_path, - tf2tfliteV2_output_path, - getattr(args, 'output_path')) + tf2tfliteV2_output_path, + getattr(args, 'output_path')) f.write((' '.join(tflite2circle_cmd) + '\n').encode()) diff --git a/compiler/one-cmds/one-import-pytorch b/compiler/one-cmds/one-import-pytorch index dbf1ba6d7..7f39e61bb 100644 --- a/compiler/one-cmds/one-import-pytorch +++ b/compiler/one-cmds/one-import-pytorch @@ -80,7 +80,8 @@ def _get_parser(): tf2tflite_group.add_argument('--converter_version', default='v2') parser.add_argument('--unroll_rnn', action='store_true', help='Unroll RNN operators') - parser.add_argument('--unroll_lstm', action='store_true', help='Unroll LSTM operators') + parser.add_argument( + '--unroll_lstm', action='store_true', help='Unroll LSTM operators') # save intermediate file(s) parser.add_argument( @@ -338,8 +339,8 @@ def _convert(args): # make a command to convert from tflite to circle tflite2circle_path = os.path.join(dir_path, 'tflite2circle') tflite2circle_cmd = _make_cmd.make_tflite2circle_cmd(tflite2circle_path, - tf2tfliteV2_output_path, - getattr(args, 'output_path')) + tf2tfliteV2_output_path, + getattr(args, 'output_path')) f.write((' '.join(tflite2circle_cmd) + '\n').encode()) diff --git a/compiler/one-cmds/one-import-tf b/compiler/one-cmds/one-import-tf index 999255a34..6623fa6a4 100644 --- a/compiler/one-cmds/one-import-tf +++ b/compiler/one-cmds/one-import-tf @@ -21,8 +21,6 @@ import argparse import os -import subprocess -import sys import tempfile import onelib.make_cmd as _make_cmd @@ -152,8 +150,8 @@ def _convert(args): tmpdir, os.path.splitext(os.path.basename(args.output_path))[0]) + '.tflite' tf2tfliteV2_cmd = _make_cmd.make_tf2tfliteV2_cmd(args, tf2tfliteV2_path, - getattr(args, 'input_path'), - tf2tfliteV2_output_path) + getattr(args, 'input_path'), + tf2tfliteV2_output_path) f.write((' '.join(tf2tfliteV2_cmd) + '\n').encode()) @@ -163,8 +161,8 @@ def _convert(args): # make a command to convert from tflite to circle tflite2circle_path = os.path.join(dir_path, 'tflite2circle') tflite2circle_cmd = _make_cmd.make_tflite2circle_cmd(tflite2circle_path, - tf2tfliteV2_output_path, - getattr(args, 'output_path')) + tf2tfliteV2_output_path, + getattr(args, 'output_path')) f.write((' '.join(tflite2circle_cmd) + '\n').encode()) diff --git a/compiler/one-cmds/one-import-tflite b/compiler/one-cmds/one-import-tflite index 2d756bff6..3d96b117f 100644 --- a/compiler/one-cmds/one-import-tflite +++ b/compiler/one-cmds/one-import-tflite @@ -21,7 +21,6 @@ import argparse import os -import subprocess import sys import onelib.make_cmd as _make_cmd @@ -83,8 +82,8 @@ def _convert(args): # make a command to convert from tflite to circle tflite2circle_path = os.path.join(dir_path, 'tflite2circle') tflite2circle_cmd = _make_cmd.make_tflite2circle_cmd(tflite2circle_path, - getattr(args, 'input_path'), - getattr(args, 'output_path')) + getattr(args, 'input_path'), + getattr(args, 'output_path')) f.write((' '.join(tflite2circle_cmd) + '\n').encode()) diff --git a/compiler/one-cmds/one-infer b/compiler/one-cmds/one-infer new file mode 100644 index 000000000..c7fcd8afd --- /dev/null +++ b/compiler/one-cmds/one-infer @@ -0,0 +1,224 @@ +#!/usr/bin/env bash +''''export SCRIPT_PATH="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" # ''' +''''export PY_PATH=${SCRIPT_PATH}/venv/bin/python # ''' +''''test -f ${PY_PATH} && exec ${PY_PATH} "$0" "$@" # ''' +''''echo "Error: Virtual environment not found. Please run 'one-prepare-venv' command." # ''' +''''exit 255 # ''' + +# 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. + +import argparse +import copy +import glob +import itertools +import ntpath +import os +import sys + +import utils as _utils + +# TODO Find better way to suppress trackback on error +sys.tracebacklimit = 0 + + +def _get_backends_list(): + """ + [one hierarchy] + one + ├── backends + ├── bin + ├── doc + ├── include + ├── lib + ├── optimization + └── test + + The list where `one-infer` finds its backends + - `bin` folder where `one-infer` exists + - `backends` folder + + NOTE If there are backends of the same name in different places, + the closer to the top in the list, the higher the priority. + """ + dir_path = os.path.dirname(os.path.realpath(__file__)) + backend_set = set() + + # bin folder + files = [f for f in glob.glob(dir_path + '/*-infer')] + # backends folder + files += [f for f in glob.glob(dir_path + '/../backends/**/*-infer', recursive=True)] + # TODO find backends in `$PATH` + + backends_list = [] + for cand in files: + base = ntpath.basename(cand) + if (not base in backend_set) and os.path.isfile(cand) and os.access( + cand, os.X_OK): + backend_set.add(base) + backends_list.append(cand) + + return backends_list + + +def _search_backend_driver(driver): + """ + [one hierarchy] + one + ├── backends + ├── bin + ├── doc + ├── include + ├── lib + ├── optimization + └── test + + The list where `one-infer` finds its backend driver + - `bin` folder where `one-infer` exists + - `backends/**/bin/` folder + + NOTE If there are drivers of the same name in different places, + the closer to the top in the list, the higher the priority. + """ + dir_path = os.path.dirname(os.path.realpath(__file__)) + + # CASE 1: one/bin/{driver} is found + driver_path = dir_path + '/' + driver + if os.path.isfile(driver_path) and os.access(driver_path, os.X_OK): + return driver_path + + # CASE 2: one/backends/**/bin/{driver} is found + for driver_path in glob.glob( + dir_path + '/../backends/**/bin/' + driver, recursive=True): + if os.path.isfile(driver_path) and os.access(driver_path, os.X_OK): + return driver_path + + # CASE 3: {driver} is found in nowhere + return None + + +def _get_parser(backends_list): + infer_usage = 'one-infer [-h] [-v] [-C CONFIG] [-d DRIVER | -b BACKEND] [--post-process POST_PROCESS] [--] [COMMANDS FOR BACKEND DRIVER]' + parser = argparse.ArgumentParser( + description='command line tool to infer model', usage=infer_usage) + + _utils._add_default_arg(parser) + + # TODO: add tflite/onnx-infer driver to helper message when it is implemented + driver_help_message = 'backend inference driver name to execute' + parser.add_argument('-d', '--driver', type=str, help=driver_help_message) + + # get backend list in the directory + backends_name = [ntpath.basename(f) for f in backends_list] + if not backends_name: + backends_name_message = '(There is no available backend drivers)' + else: + backends_name_message = '(available backend drivers: ' + ', '.join( + backends_name) + ')' + backend_help_message = 'backend name to use ' + backends_name_message + parser.add_argument('-b', '--backend', type=str, help=backend_help_message) + + post_process_help_message = 'post processing script to convert I/O data to standard format' + parser.add_argument('--post-process', type=str, help=post_process_help_message) + + return parser + + +def _verify_arg(parser, args): + """verify given arguments""" + # `-d/--driver` and `-b/--backend` are mutually exclusive arguments. + if _utils._is_valid_attr(args, 'driver') and _utils._is_valid_attr(args, 'backend'): + parser.error( + '-d and -b options are mutually exclusive. Please use only one of them') + + missing = [] + if not _utils._is_valid_attr(args, 'driver') and not _utils._is_valid_attr( + args, 'backend'): + missing.append('{-d/--driver | -b/--backend}') + if len(missing): + parser.error('the following arguments are required: ' + ' '.join(missing)) + + +def _parse_arg(parser): + infer_args = [] + backend_args = [] + argv = copy.deepcopy(sys.argv) + # delete file name + del argv[0] + # split by '--' + args = [list(y) for x, y in itertools.groupby(argv, lambda z: z == '--') if not x] + + # one-infer [-h] [-v] [-C CONFIG] [-d DRIVER] [-b BACKEND] [--post-process POST_PROCESS] -- [COMMANDS FOR BACKEND DRIVER] + if len(args): + infer_args = args[0] + infer_args = parser.parse_args(infer_args) + backend_args = backend_args if len(args) < 2 else args[1] + # print version + if len(args) and infer_args.version: + _utils._print_version_and_exit(__file__) + + return infer_args, backend_args + + +def _get_executable(args, backends_list): + driver = _utils._is_valid_attr(args, 'driver') + if driver: + executable = _search_backend_driver(driver) + if executable: + return executable + else: + raise FileNotFoundError(driver + ' not found') + + if _utils._is_valid_attr(args, 'backend'): + backend_base = getattr(args, 'backend') + '-infer' + for cand in backends_list: + if ntpath.basename(cand) == backend_base: + return cand + raise FileNotFoundError(backend_base + ' not found') + + +def main(): + # get backend list + backends_list = _get_backends_list() + + # parse arguments + parser = _get_parser(backends_list) + args, backend_args = _parse_arg(parser) + + # parse configuration file + _utils._parse_cfg(args, 'one-infer') + + # verify arguments + _verify_arg(parser, args) + + # make a command to run given backend driver + driver_path = _get_executable(args, backends_list) + infer_cmd = [driver_path] + backend_args + if _utils._is_valid_attr(args, 'command'): + infer_cmd += getattr(args, 'command').split() + + # run backend driver + _utils._run(infer_cmd, err_prefix=ntpath.basename(driver_path)) + + # run post process script if it's given + if _utils._is_valid_attr(args, 'post_process'): + # NOTE: the given python script will be executed by venv of ONE + python_path = sys.executable + post_process_command = [python_path] + getattr(args, + 'post_process').strip().split(' ') + _utils._run(post_process_command, err_prefix='one-infer') + + +if __name__ == '__main__': + _utils._safemain(main, __file__) diff --git a/compiler/one-cmds/one-init b/compiler/one-cmds/one-init new file mode 100644 index 000000000..04c4534cd --- /dev/null +++ b/compiler/one-cmds/one-init @@ -0,0 +1,280 @@ +#!/usr/bin/env bash +''''export SCRIPT_PATH="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" # ''' +''''export PY_PATH=${SCRIPT_PATH}/venv/bin/python # ''' +''''test -f ${PY_PATH} && exec ${PY_PATH} "$0" "$@" # ''' +''''echo "Error: Virtual environment not found. Please run 'one-prepare-venv' command." # ''' +''''exit 255 # ''' + +# 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. + +import argparse +import copy +import glob +import itertools +import ntpath +import os +import sys + +import configparser +import utils as _utils + +# TODO Find better way to suppress trackback on error +sys.tracebacklimit = 0 + + +class CommentableConfigParser(configparser.ConfigParser): + """ + ConfigParser where comment can be stored + In Python ConfigParser, comment in ini file ( starting with ';') is considered a key of which + value is None. + Ref: https://stackoverflow.com/questions/6620637/writing-comments-to-files-with-configparser + """ + + def __init__(self): + # allow_no_value=True to add comment + # ref: https://stackoverflow.com/a/19432072 + configparser.ConfigParser.__init__(self, allow_no_value=True) + self.optionxform = str + + def add_comment(self, section, comment): + comment_sign = ';' + self[section][f'{comment_sign} {comment}'] = None + + +def _get_backends_list(): + """ + [one hierarchy] + one + ├── backends + ├── bin + ├── doc + ├── include + ├── lib + ├── optimization + └── test + + The list where `one-init` finds its backends + - `bin` folder where `one-init` exists + - `backends` folder + + NOTE If there are backends of the same name in different places, + the closer to the top in the list, the higher the priority. + """ + dir_path = os.path.dirname(os.path.realpath(__file__)) + backend_set = set() + + # bin folder + files = [f for f in glob.glob(dir_path + '/*-init')] + # backends folder + files += [f for f in glob.glob(dir_path + '/../backends/**/*-init', recursive=True)] + # TODO find backends in `$PATH` + + backends_list = [] + for cand in files: + base = ntpath.basename(cand) + if (not base in backend_set) and os.path.isfile(cand) and os.access( + cand, os.X_OK): + backend_set.add(base) + backends_list.append(cand) + + return backends_list + + +# TODO Add support for TF graphdef and bcq +def _get_parser(backends_list): + init_usage = ( + 'one-init [-h] [-v] [-V] ' + '[-i INPUT_PATH] ' + '[-o OUTPUT_PATH] ' + '[-m MODEL_TYPE] ' + '[-b BACKEND] ' + # args for onnx model + '[--convert_nchw_to_nhwc] ' + '[--nchw_to_nhwc_input_shape] ' + '[--nchw_to_nhwc_output_shape] ' + # args for backend driver + '[--] [COMMANDS FOR BACKEND DRIVER]') + """ + NOTE + layout options for onnx model could be difficult to users. + In one-init, we could consider easier args for the the above three: + For example, we could have another option, e.g., --input_img_layout LAYOUT + - When LAYOUT is NHWC, apply 'nchw_to_nhwc_input_shape=True' into cfg + - When LAYOUT is NCHW, apply 'nchw_to_nhwc_input_shape=False' into cfg + """ + + parser = argparse.ArgumentParser( + description='Command line tool to generate initial cfg file. ' + 'Currently tflite and onnx models are supported', + usage=init_usage) + + _utils._add_default_arg_no_CS(parser) + + parser.add_argument( + '-i', '--input_path', type=str, help='full filepath of the input model file') + parser.add_argument( + '-o', '--output_path', type=str, help='full filepath of the output cfg file') + parser.add_argument( + '-m', + '--model_type', + type=str, + help=('type of input model: "onnx", "tflite". ' + 'If the file extension passed to --input_path is ' + '".tflite" or ".onnx", this arg can be omitted.')) + + onnx_group = parser.add_argument_group('arguments when model type is onnx') + onnx_group.add_argument( + '--convert_nchw_to_nhwc', + action='store_true', + help= + 'Convert NCHW operators to NHWC under the assumption that input model is NCHW.') + onnx_group.add_argument( + '--nchw_to_nhwc_input_shape', + action='store_true', + help='Convert the input shape of the model (argument for convert_nchw_to_nhwc)') + onnx_group.add_argument( + '--nchw_to_nhwc_output_shape', + action='store_true', + help='Convert the output shape of the model (argument for convert_nchw_to_nhwc)') + + # get backend list in the directory + backends_name = [ntpath.basename(f) for f in backends_list] + if not backends_name: + backends_name_message = '(There is no available backend drivers)' + else: + backends_name_message = '(available backend drivers: ' + ', '.join( + backends_name) + ')' + backend_help_message = 'backend name to use ' + backends_name_message + parser.add_argument('-b', '--backend', type=str, help=backend_help_message) + + return parser + + +def _verify_arg(parser, args): + # check if required arguments is given + missing = [] + if not _utils._is_valid_attr(args, 'input_path'): + missing.append('-i/--input_path') + if not _utils._is_valid_attr(args, 'output_path'): + missing.append('-o/--output_path') + if not _utils._is_valid_attr(args, 'backend'): + missing.append('-b/--backend') + + if _utils._is_valid_attr(args, 'model_type'): + # TODO Support model types other than onnx and tflite (e.g., TF) + if getattr(args, 'model_type') not in ['onnx', 'tflite']: + parser.error('Allowed value for --model_type: "onnx" or "tflite"') + + if _utils._is_valid_attr(args, 'nchw_to_nhwc_input_shape'): + if not _utils._is_valid_attr(args, 'convert_nchw_to_nhwc'): + missing.append('--convert_nchw_to_nhwc') + if _utils._is_valid_attr(args, 'nchw_to_nhwc_output_shape'): + if not _utils._is_valid_attr(args, 'convert_nchw_to_nhwc'): + missing.append('--convert_nchw_to_nhwc') + + if len(missing): + parser.error('the following arguments are required: ' + ' '.join(missing)) + + +def _parse_arg(parser): + init_args = [] + backend_args = [] + argv = copy.deepcopy(sys.argv) + # delete file name + del argv[0] + # split by '--' + args = [list(y) for x, y in itertools.groupby(argv, lambda z: z == '--') if not x] + + # one-init [-h] [-v] ... + if len(args): + init_args = args[0] + init_args = parser.parse_args(init_args) + backend_args = backend_args if len(args) < 2 else args[1] + # print version + if len(args) and init_args.version: + _utils._print_version_and_exit(__file__) + + return init_args, backend_args + + +def _get_executable(args, backends_list): + if _utils._is_valid_attr(args, 'backend'): + backend_base = getattr(args, 'backend') + '-init' + for cand in backends_list: + if ntpath.basename(cand) == backend_base: + return cand + raise FileNotFoundError(backend_base + ' not found') + + +# TODO Support workflow format (https://github.com/Samsung/ONE/pull/9354) +def _generate(): + # generate cfg file + config = CommentableConfigParser() + + def _add_onecc_sections(): + pass # NYI + + def _gen_import(): + pass # NYI + + def _gen_optimize(): + pass # NYI + + def _gen_quantize(): + pass # NYI + + def _gen_codegen(): + pass # NYI + + # + # NYI: one-profile, one-partition, one-pack, one-infer + # + + _add_onecc_sections() + + _gen_import() + _gen_optimize() + _gen_quantize() + _gen_codegen() + + with open(args.output_path, 'w') as f: + config.write(f) + + +def main(): + # get backend list + backends_list = _get_backends_list() + + # parse arguments + parser = _get_parser(backends_list) + args, backend_args = _parse_arg(parser) + + # verify arguments + _verify_arg(parser, args) + + # make a command to run given backend driver + driver_path = _get_executable(args, backends_list) + init_cmd = [driver_path] + backend_args + + # run backend driver + _utils._run(init_cmd, err_prefix=ntpath.basename(driver_path)) + + #TODO generate cfg file + + raise NotImplementedError("NYI") + + +if __name__ == '__main__': + _utils._safemain(main, __file__) diff --git a/compiler/one-cmds/one-optimize b/compiler/one-cmds/one-optimize index 8b1f3f7be..481fc8459 100644 --- a/compiler/one-cmds/one-optimize +++ b/compiler/one-cmds/one-optimize @@ -21,7 +21,6 @@ import argparse import os -import subprocess import sys import onelib.constant as _constant @@ -83,6 +82,14 @@ def _verify_arg(parser, args): if len(missing): parser.error('the following arguments are required: ' + ' '.join(missing)) + # default has pre-defined optimization options + default = _get_parser().parse_args() + + # check if unrecognized arguments are given + diff = set(dir(args)) - set(dir(default)) + if len(diff): + parser.error('the following arguments are unrecognized: ' + ' '.join(diff)) + def _parse_arg(parser): args = parser.parse_args() @@ -102,8 +109,8 @@ def _optimize(args): # make a command to optimize circle model circle2circle_path = os.path.join(dir_path, 'circle2circle') circle2circle_cmd = _make_cmd.make_circle2circle_cmd(args, circle2circle_path, - getattr(args, 'input_path'), - getattr(args, 'output_path')) + getattr(args, 'input_path'), + getattr(args, 'output_path')) # verbose if _utils._is_valid_attr(args, 'verbose'): diff --git a/compiler/one-cmds/one-pack b/compiler/one-cmds/one-pack index 133207de0..5cab7c737 100644 --- a/compiler/one-cmds/one-pack +++ b/compiler/one-cmds/one-pack @@ -21,9 +21,7 @@ import argparse import os -import subprocess import sys -import tempfile import utils as _utils diff --git a/compiler/one-cmds/one-partition b/compiler/one-cmds/one-partition new file mode 100644 index 000000000..c0d71e5d9 --- /dev/null +++ b/compiler/one-cmds/one-partition @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +''''export SCRIPT_PATH="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" # ''' +''''export PY_PATH=${SCRIPT_PATH}/venv/bin/python # ''' +''''test -f ${PY_PATH} && exec ${PY_PATH} "$0" "$@" # ''' +''''echo "Error: Virtual environment not found. Please run 'one-prepare-venv' command." # ''' +''''exit 255 # ''' + +# 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. + +import argparse +import configparser +import os +import sys + +import utils as _utils + +# TODO Find better way to suppress trackback on error +sys.tracebacklimit = 0 + + +def _get_parser(): + parser = argparse.ArgumentParser( + description='command line tool to partition circle model by multiple backends') + + _utils._add_default_arg(parser) + + parser.add_argument( + '--backends', type=str, help='backends in CSV to use for partitioning') + parser.add_argument('--default', type=str, help='default backend to assign') + + parser.add_argument( + '--part_file', type=str, help='partition file which provides backend to assign') + parser.add_argument('--input_file', type=str, help='input circle model filename') + parser.add_argument( + '--work_path', + type=str, + help='work path of partition, input files exist and output files are produced') + + return parser + + +def _parse_arg(parser): + args = parser.parse_args() + # print version + if args.version: + _utils._print_version_and_exit(__file__) + + return args + + +def _verify_arg(parser, args): + """verify given arguments""" + # check if required arguments is given + missing = [] + if not _utils._is_valid_attr(args, 'part_file'): + missing.append('part_file') + if not _utils._is_valid_attr(args, 'input_file'): + missing.append('input_file') + if len(missing): + parser.error('the following arguments are required: ' + ' '.join(missing)) + return + + +def _partition(args): + # get file path to log + bin_path = os.path.dirname(os.path.realpath(__file__)) + cur_path = os.getcwd() + partition_path = os.path.join(cur_path, args.part_file) + logfile_path = partition_path + '.log' + + with open(logfile_path, 'wb', buffering=0) as f: + # make a command to package circle model and metadata into nnpackage + circle_partitioner_path = os.path.join(bin_path, 'circle-partitioner') + + cmd = [os.path.expanduser(circle_partitioner_path)] + + if _utils._is_valid_attr(args, 'backends'): + cmd.append('--backends') + cmd.append(getattr(args, 'backends')) + if _utils._is_valid_attr(args, 'default'): + cmd.append('--default') + cmd.append(getattr(args, 'default')) + if _utils._is_valid_attr(args, 'work_path'): + cmd.append('--work_path') + cmd.append(getattr(args, 'work_path')) + + cmd.append('--part_file') + cmd.append(args.part_file) + cmd.append('--input_file') + cmd.append(args.input_file) + + f.write((' '.join(cmd) + '\n').encode()) + + # run circle-partitoner + _utils._run(cmd, err_prefix='circle-partitioner', logfile=f) + + +def main(): + # parse arguments + parser = _get_parser() + args = _parse_arg(parser) + + # parse configuration file + _utils._parse_cfg(args, 'one-partition') + + if _utils._is_valid_attr(args, 'config'): + config_path = getattr(args, 'config') + _utils._parse_cfg_and_overwrite(config_path, 'one-partition', args) + + # verify arguments + _verify_arg(parser, args) + + # do partition + _partition(args) + + +if __name__ == '__main__': + _utils._safemain(main, __file__) diff --git a/compiler/one-cmds/one-prepare-venv b/compiler/one-cmds/one-prepare-venv index 0f75166a7..b435671f4 100644 --- a/compiler/one-cmds/one-prepare-venv +++ b/compiler/one-cmds/one-prepare-venv @@ -41,6 +41,7 @@ VER_ONNX_TF=1.10.0 # Install tensorflow PIP_TRUSTED_HOST="--trusted-host pypi.org " +PIP_TRUSTED_HOST+="--trusted-host pypi.python.org " PIP_TRUSTED_HOST+="--trusted-host files.pythonhost.org " PIP_TRUSTED_HOST+="--trusted-host download.pytorch.org " @@ -62,7 +63,8 @@ else ${VENV_PYTHON} -m pip ${PIP_OPTIONS} install tensorflow-cpu==${VER_TENSORFLOW} fi ${VENV_PYTHON} -m pip ${PIP_OPTIONS} install Pillow -${VENV_PYTHON} -m pip ${PIP_OPTIONS} install tensorflow_probability +# TODO remove version fix, https://github.com/Samsung/ONE/issues/9240 +${VENV_PYTHON} -m pip ${PIP_OPTIONS} install tensorflow_probability==0.16.0 # Install PyTorch and ONNX related # NOTE set ONE_PREPVENV_TORCH_STABLE to override 'torch_stable.html' URL. @@ -72,6 +74,8 @@ TORCH_STABLE_URL="https://download.pytorch.org/whl/torch_stable.html" if [[ ! -z "$ONE_PREPVENV_TORCH_STABLE" ]]; then TORCH_STABLE_URL="${ONE_PREPVENV_TORCH_STABLE}" fi +# TODO remove torch message +echo "Torch from '${ONE_PREPVENV_TORCH_STABLE}' -> '${TORCH_STABLE_URL}'" ${VENV_PYTHON} -m pip ${PIP_OPTIONS} install torch==1.11.0+cpu -f ${TORCH_STABLE_URL} ${VENV_PYTHON} -m pip ${PIP_OPTIONS} install onnx==${VER_ONNX} @@ -84,3 +88,7 @@ if [ -n "${EXT_ONNX_TF_WHL}" ]; then else ${VENV_PYTHON} -m pip ${PIP_OPTIONS} install onnx-tf==${VER_ONNX_TF} fi + +# NOTE refer https://github.com/protocolbuffers/protobuf/issues/10051 +# TODO remove this when issue is resolved +${VENV_PYTHON} -m pip ${PIP_OPTIONS} install --upgrade protobuf==3.20.1 diff --git a/compiler/one-cmds/one-profile b/compiler/one-cmds/one-profile index ed6d8bd7a..b19c215ed 100644 --- a/compiler/one-cmds/one-profile +++ b/compiler/one-cmds/one-profile @@ -25,9 +25,7 @@ import glob import itertools import ntpath import os -import subprocess import sys -import tempfile import utils as _utils diff --git a/compiler/one-cmds/one-quantize b/compiler/one-cmds/one-quantize index f2eff24bd..9282007d8 100644 --- a/compiler/one-cmds/one-quantize +++ b/compiler/one-cmds/one-quantize @@ -21,11 +21,12 @@ import argparse import os -import subprocess import sys import tempfile +import json import utils as _utils +from utils import Command # TODO Find better way to suppress trackback on error sys.tracebacklimit = 0 @@ -67,6 +68,12 @@ def _get_parser(): action='store_true', help='generate profiling data') + # save intermediate file(s) + parser.add_argument( + '--save_intermediate', + action='store_true', + help='Save intermediate files to output folder') + ## arguments for quantization quantization_group = parser.add_argument_group('arguments for quantization') @@ -93,13 +100,13 @@ def _get_parser(): '--input_type', type=str, help= - 'data type of inputs of quantized model (supported: uint8, int16, default=quantized_dtype). QUANTIZE Op will be inserted at the beginning of the quantized model if input_type is different from quantized_dtype.' + 'data type of inputs of quantized model (supported: uint8, int16, float32, default=quantized_dtype). QUANTIZE Op will be inserted at the beginning of the quantized model if input_type is different from quantized_dtype.' ) quantization_group.add_argument( '--output_type', type=str, help= - 'data type of outputs of quantized model (supported: uint8, int16, default=quantized_dtype). QUANTIZE Op will be inserted at the end of the quantized model if output_type is different from quantized_dtype.' + 'data type of outputs of quantized model (supported: uint8, int16, float32, default=quantized_dtype). QUANTIZE Op will be inserted at the end of the quantized model if output_type is different from quantized_dtype.' ) quantization_group.add_argument( '--min_percentile', @@ -126,10 +133,50 @@ def _get_parser(): "Force MaxPool Op to have the same input/output quantparams. NOTE: This option can degrade accuracy of some models.)" ) quantization_group.add_argument( - '--quant_config', - type=str, + '--quant_config', type=str, help="Path to the quantization configuration file.") + quantization_group.add_argument( + '--evaluate_result', + action='store_true', + help= + "Evaluate accuracy of quantized model. Run inference for both fp32 model and the quantized model, and compare the inference results." + ) + quantization_group.add_argument( + '--test_data', type=str, help="Path to the test data used for evaluation.") + quantization_group.add_argument( + '--print_mae', + action='store_true', + help= + "Print MAE (Mean Absolute Error) of inference results between quantized model and fp32 model." + ) + quantization_group.add_argument( + '--print_mape', + action='store_true', + help= + "Print MAPE (Mean Absolute Percentage Error) of inference results between quantized model and fp32 model." + ) + quantization_group.add_argument( + '--print_mpeir', + action='store_true', + help= + "Print MPEIR (Mean Peak Error to Interval Ratio) of inference results between quantized model and fp32 model." + ) + quantization_group.add_argument( + '--print_top1_match', + action='store_true', + help= + "Print Top-1 match ratio of inference results between quantized model and fp32 model." + ) + quantization_group.add_argument( + '--print_top5_match', + action='store_true', + help= + "Print Top-5 match ratio of inference results between quantized model and fp32 model." + ) + quantization_group.add_argument( + '--print_mse', + action='store_true', help= - "Path to the quantization configuration file." + "Print MSE (Mean Squared Error) of inference results between quantized model and fp32 model." ) # arguments for force_quantparam option @@ -162,6 +209,14 @@ def _get_parser(): copy_quantparam_group.add_argument( '--dst_tensor_name', type=str, action='append', help='tensor name (string)') + # arguments for fake_quant option + fake_quant_group = parser.add_argument_group('arguments for fake_quantize option') + + fake_quant_group.add_argument( + '--fake_quantize', + action='store_true', + help='convert quantized model to fake-quantized fp32 model.') + return parser @@ -171,8 +226,29 @@ def _set_default_values(args): setattr(args, 'input_model_dtype', 'float32') if not _utils._is_valid_attr(args, 'quantized_dtype'): setattr(args, 'quantized_dtype', 'uint8') + if _utils._is_valid_attr(args, 'quant_config'): + # Get quantized_dtype from qconfig file + try: + with open(getattr(args, 'quant_config')) as f: + qconf = json.load(f) + if 'default_quantization_dtype' in qconf: + setattr(args, 'quantized_dtype', + qconf['default_quantization_dtype']) + except json.decoder.JSONDecodeError: + print('Failed to decode ' + getattr(args, 'quant_config') + + '. Please check it is a json file.') if not _utils._is_valid_attr(args, 'granularity'): setattr(args, 'granularity', 'layer') + if _utils._is_valid_attr(args, 'quant_config'): + # Get granularity from qconfig file + try: + with open(getattr(args, 'quant_config')) as f: + qconf = json.load(f) + if 'default_granularity' in qconf: + setattr(args, 'granularity', qconf['default_granularity']) + except json.decoder.JSONDecodeError: + print('Failed to decode ' + getattr(args, 'quant_config') + + '. Please check it is a json file.') if not _utils._is_valid_attr(args, 'mode'): setattr(args, 'mode', 'percentile') if not _utils._is_valid_attr(args, 'min_percentile'): @@ -238,11 +314,18 @@ def _quantize(args): _copy_qparam(args) return + if _utils._is_valid_attr(args, 'fake_quantize'): + # fake-quantize model + _fake_quantize(args) + return + # get file path to log dir_path = os.path.dirname(os.path.realpath(__file__)) logfile_path = os.path.realpath(args.output_path) + '.log' with open(logfile_path, 'wb') as f, tempfile.TemporaryDirectory() as tmpdir: + if _utils._is_valid_attr(args, 'save_intermediate'): + tmpdir = os.path.dirname(logfile_path) # get driver path circle_quantizer_path = os.path.join(dir_path, 'circle-quantizer') record_minmax_path = os.path.join(dir_path, 'record-minmax') @@ -263,13 +346,19 @@ def _quantize(args): circle_quantizer_cmd.append(getattr(args, 'quantized_dtype')) if _utils._is_valid_attr(args, 'granularity'): circle_quantizer_cmd.append(getattr(args, 'granularity')) + if _utils._is_valid_attr(args, 'quant_config'): + # NOTE --config conflicts with --config option in onecc, so + # we use quant_config for one-quantize + circle_quantizer_cmd.append('--config') + circle_quantizer_cmd.append(getattr(args, 'quant_config')) # input and output path if _utils._is_valid_attr(args, 'input_path'): circle_quantizer_cmd.append(getattr(args, 'input_path')) - tmp_output_path_1 = os.path.join( + tmp_weights_fake_quant_path = os.path.join( tmpdir, - os.path.splitext(os.path.basename(args.input_path))[0]) + '1.circle' - circle_quantizer_cmd.append(tmp_output_path_1) + os.path.splitext(os.path.basename( + args.input_path))[0]) + '.weights_fake_quant.circle' + circle_quantizer_cmd.append(tmp_weights_fake_quant_path) # profiling if _utils._is_valid_attr(args, 'generate_profile_data'): circle_quantizer_cmd.append('--generate_profile_data') @@ -279,45 +368,23 @@ def _quantize(args): # run circle-quantizer _utils._run(circle_quantizer_cmd, err_prefix="circle_quantizer", logfile=f) - ## make a command to record min-max value of each tensor while running the representative dataset - circle_record_minmax_cmd = [record_minmax_path] - # verbose - if _utils._is_valid_attr(args, 'verbose'): - circle_record_minmax_cmd.append('--verbose') - # input and output path - circle_record_minmax_cmd.append('--input_model') - circle_record_minmax_cmd.append(tmp_output_path_1) - tmp_output_path_2 = os.path.join( + tmp_minmax_recorded_path = os.path.join( tmpdir, - os.path.splitext(os.path.basename(args.input_path))[0]) + '2.circle' - circle_record_minmax_cmd.append('--output_model') - circle_record_minmax_cmd.append(tmp_output_path_2) - # input data - if _utils._is_valid_attr(args, 'input_data'): - circle_record_minmax_cmd.append('--input_data') - circle_record_minmax_cmd.append(getattr(args, 'input_data')) - if _utils._is_valid_attr(args, 'input_data_format'): - circle_record_minmax_cmd.append('--input_data_format') - circle_record_minmax_cmd.append(getattr(args, 'input_data_format')) - # min and max percentile - if _utils._is_valid_attr(args, 'min_percentile'): - circle_record_minmax_cmd.append('--min_percentile') - circle_record_minmax_cmd.append(getattr(args, 'min_percentile')) - if _utils._is_valid_attr(args, 'max_percentile'): - circle_record_minmax_cmd.append('--max_percentile') - circle_record_minmax_cmd.append(getattr(args, 'max_percentile')) - # mode - if _utils._is_valid_attr(args, 'mode'): - circle_record_minmax_cmd.append('--mode') - circle_record_minmax_cmd.append(getattr(args, 'mode')) - # profiling - if _utils._is_valid_attr(args, 'generate_profile_data'): - circle_record_minmax_cmd.append('--generate_profile_data') - - f.write((' '.join(circle_record_minmax_cmd) + '\n').encode()) + os.path.splitext(os.path.basename( + args.input_path))[0]) + '.minmax_recorded.circle' - # run record-minmax - _utils._run(circle_record_minmax_cmd, err_prefix="record_minmax", logfile=f) + ## make a command to record min-max value of each tensor while running the representative dataset + record_minmax_cmd = Command(record_minmax_path, args, f) + record_minmax_cmd.add_noarg_option_if_valid_arg('--verbose', 'verbose') \ + .add_option_with_values('--input_model', [tmp_weights_fake_quant_path]) \ + .add_option_with_values('--output_model', [tmp_minmax_recorded_path]) \ + .add_option_with_valid_args('--input_data', ['input_data']) \ + .add_option_with_valid_args('--input_data_format', ['input_data_format']) \ + .add_option_with_valid_args('--min_percentile', ['min_percentile']) \ + .add_option_with_valid_args('--max_percentile', ['max_percentile']) \ + .add_option_with_valid_args('--mode', ['mode']) \ + .add_noarg_option_if_valid_arg('--generate_profile_data', 'generate_profile_data') \ + .run() ## make a second command to quantize the model using the embedded information circle_quantizer_cmd = [circle_quantizer_path] @@ -349,7 +416,7 @@ def _quantize(args): circle_quantizer_cmd.append('--config') circle_quantizer_cmd.append(getattr(args, 'quant_config')) # input and output path - circle_quantizer_cmd.append(tmp_output_path_2) + circle_quantizer_cmd.append(tmp_minmax_recorded_path) if _utils._is_valid_attr(args, 'output_path'): circle_quantizer_cmd.append(getattr(args, 'output_path')) # profiling @@ -361,6 +428,38 @@ def _quantize(args): # run circle-quantizer _utils._run(circle_quantizer_cmd, err_prefix="circle_quantizer", logfile=f) + # evaluate + if _utils._is_valid_attr(args, 'evaluate_result'): + circle_eval_diff_path = os.path.join(dir_path, 'circle-eval-diff') + quant_model = "" + if _utils._is_valid_attr(args, 'output_path'): + quant_model = getattr(args, 'output_path') + tmp_fake_quant_model = os.path.join( + tmpdir, + os.path.splitext(os.path.basename( + args.input_path))[0]) + '.fake_quant.circle' + + # do fake quantization + fake_quantize_cmd = Command(circle_quantizer_path, args, f) + fake_quantize_cmd.add_noarg_option_if_valid_arg('--verbose', 'verbose') \ + .add_option_with_values('--fake_quantize', [quant_model, tmp_fake_quant_model]) \ + .run() + + # compare fake-quant model and fp32 model + circle_eval_diff_cmd = Command(circle_eval_diff_path, args, f) + circle_eval_diff_cmd.add_option_with_valid_args('--first_model', ['input_path']) \ + .add_option_with_values('--second_model', [tmp_fake_quant_model]) \ + .add_option_with_valid_args('--first_input_data', ['test_data']) \ + .add_option_with_valid_args('--second_input_data', ['test_data']) \ + .add_option_with_valid_args('--input_data_format', ['input_data_format']) \ + .add_noarg_option_if_valid_arg('--print_mae', 'print_mae') \ + .add_noarg_option_if_valid_arg('--print_mape', 'print_mape') \ + .add_noarg_option_if_valid_arg('--print_mpeir', 'print_mpeir') \ + .add_noarg_option_if_valid_arg('--print_top1_match', 'print_top1_match') \ + .add_noarg_option_if_valid_arg('--print_top5_match', 'print_top5_match') \ + .add_noarg_option_if_valid_arg('--print_mse', 'print_mse') \ + .run() + def _write_qparam(args): # get file path to log @@ -433,6 +532,24 @@ def _copy_qparam(args): _utils._run(circle_quantizer_cmd, err_prefix="circle_quantizer", logfile=f) +def _fake_quantize(args): + # get file path to log + dir_path = os.path.dirname(os.path.realpath(__file__)) + logfile_path = os.path.realpath(args.output_path) + '.log' + + with open(logfile_path, 'wb') as f: + # get driver path + circle_quantizer_path = os.path.join(dir_path, 'circle-quantizer') + q_model = getattr(args, 'input_path') + fq_model = getattr(args, 'output_path') + + # do fake quantization + fake_quantize_cmd = Command(circle_quantizer_path, args, f) + fake_quantize_cmd.add_noarg_option_if_valid_arg('--verbose', 'verbose') \ + .add_option_with_values('--fake_quantize', [q_model, fq_model]) \ + .run() + + def main(): # parse arguments parser = _get_parser() diff --git a/compiler/one-cmds/onecc b/compiler/one-cmds/onecc index 25682ff4b..a5ba636a2 100644 --- a/compiler/one-cmds/onecc +++ b/compiler/one-cmds/onecc @@ -25,6 +25,8 @@ import os import subprocess import sys +from onelib.CfgRunner import CfgRunner +from onelib.WorkflowRunner import WorkflowRunner import utils as _utils # TODO Find better way to suppress trackback on error @@ -42,6 +44,7 @@ subtool_list = { 'backend': { 'codegen': 'Code generation tool', 'profile': 'Profile backend model file', + 'infer': 'Infer backend model file' }, } @@ -64,12 +67,25 @@ def _check_subtool_exists(): def _get_parser(): - onecc_usage = 'onecc [-h] [-v] [-C CONFIG] [COMMAND <args>]' + onecc_usage = 'onecc [-h] [-v] [-C CONFIG] [-W WORKFLOW] [-O OPTIMIZATION] [COMMAND <args>]' onecc_desc = 'Run ONE driver via several commands or configuration file' parser = argparse.ArgumentParser(description=onecc_desc, usage=onecc_usage) _utils._add_default_arg(parser) + opt_name_list = _utils._get_optimization_list(get_name=True) + opt_name_list = ['-' + s for s in opt_name_list] + if not opt_name_list: + opt_help_message = '(No available optimization options)' + else: + opt_help_message = '(Available optimization options: ' + ', '.join( + opt_name_list) + ')' + opt_help_message = 'optimization name to use ' + opt_help_message + parser.add_argument('-O', type=str, metavar='OPTIMIZATION', help=opt_help_message) + + parser.add_argument( + '-W', '--workflow', type=str, metavar='WORKFLOW', help='run with workflow file') + # just for help message compile_group = parser.add_argument_group('compile to circle model') for tool, desc in subtool_list['compile'].items(): @@ -98,45 +114,17 @@ def _parse_arg(parser): def _verify_arg(parser, args): """verify given arguments""" # check if required arguments is given - if not _utils._is_valid_attr(args, 'config'): - parser.error('-C/--config argument is required') - - -def _get_driver_name(driver_name): - return { - 'one-optimize': 'one-optimize', - 'one-quantize': 'one-quantize', - 'one-pack': 'one-pack', - 'one-codegen': 'one-codegen', - 'one-profile': 'one-profile' - }[driver_name] - - -def _parse_cfg(args): - config = configparser.ConfigParser() - config.optionxform = str - parsed = config.read(os.path.expanduser(getattr(args, 'config'))) - if not parsed: - raise FileNotFoundError('Not found given configuration file') - return config - - -def _is_available_driver(config, driver_name): - return config.has_option('onecc', driver_name) and config.getboolean( - 'onecc', driver_name) - - -def _verify_cfg(import_driver_list, config): - if not config.has_section('onecc'): - raise ImportError('[onecc] section is required in configuration file') - - import_driver_cnt = 0 - for d in import_driver_list: - if _is_available_driver(config, d): - import_driver_cnt += 1 - - if import_driver_cnt > 1: - raise AssertionError('Only one import-* driver can be executed') + if not _utils._is_valid_attr(args, 'config') and not _utils._is_valid_attr( + args, 'workflow'): + parser.error('-C/--config or -W/--workflow argument is required') + # check if given optimization option exists + opt_name_list = _utils._get_optimization_list(get_name=True) + opt_name_list = [_utils._remove_prefix(s, 'O') for s in opt_name_list] + if _utils._is_valid_attr(args, 'O'): + if ' ' in getattr(args, 'O'): + parser.error('Not allowed to have space in the optimization name') + if not getattr(args, 'O') in opt_name_list: + parser.error('Invalid optimization option') def main(): @@ -158,35 +146,16 @@ def main(): # verify arguments _verify_arg(parser, args) - # parse configuration file - config = _parse_cfg(args) - - # verify configuration file bin_dir = os.path.dirname(os.path.realpath(__file__)) - import_drivers_dict = _utils._detect_one_import_drivers(bin_dir) - transform_drivers = [ - 'one-optimize', 'one-quantize', 'one-pack', 'one-codegen', 'one-profile' - ] - _verify_cfg(import_drivers_dict, config) - - # get sections to run - section_to_run = [] - for d in list(import_drivers_dict) + transform_drivers: - if _is_available_driver(config, d): - section_to_run.append(d) - - # run - dir_path = os.path.dirname(os.path.realpath(__file__)) - for section in section_to_run: - if section in import_drivers_dict: - # we already has driver name in dict - driver_name = import_drivers_dict[section] - else: - driver_name = _get_driver_name(section) - options = ['--config', getattr(args, 'config'), '--section', section] - if _utils._is_valid_attr(args, 'verbose'): - options.append('--verbose') - _call_driver(driver_name, options) + if _utils._is_valid_attr(args, 'config'): + runner = CfgRunner(args.config) + runner.detect_import_drivers(bin_dir) + if _utils._is_valid_attr(args, 'O'): + runner.add_opt(getattr(args, 'O')) + runner.run(bin_dir) + elif _utils._is_valid_attr(args, 'workflow'): + runner = WorkflowRunner(args.workflow) + runner.run(bin_dir) if __name__ == '__main__': diff --git a/compiler/one-cmds/onecc.template.cfg b/compiler/one-cmds/onecc.template.cfg index a23d1cea9..6f6a4e266 100644 --- a/compiler/one-cmds/onecc.template.cfg +++ b/compiler/one-cmds/onecc.template.cfg @@ -1,28 +1,144 @@ +; To activate a step (or task), +; set True for the step in [onecc] section and fill options in the corresponding section [onecc] -one-import-tf=True +; neural network model to circle +one-import-tf=False one-import-tflite=False one-import-bcq=False one-import-onnx=False -one-optimize=True +; circle to circle with optimization +one-optimize=False +; circle to circle with quantization one-quantize=False -one-pack=True +; partition circle +one-partition=False +; package circle and metadata into nnpackage +one-pack=False +; generate code for backend one-codegen=False +; profile one-profile=False +; infer +one-infer=False [one-import-tf] -input_path=/path/to/inception_v3.pb -output_path=inception_v3.circle -input_arrays=input -input_shapes=1,299,299,3 -output_arrays=InceptionV3/Predictions/Reshape_1 -converter_version=v1 +# mandatory +; pb file +input_path= +; circle file +output_path= +# optional +; v1 or v2 +converter_version=v2 +; graph_def(default), saved_model or keras_model model_format=graph_def +# optional but mandatory for model_format=graph_def +; input tensor names of the input arrays, comma-separated +input_arrays= +; output tensor names of the input arrays, comma-separated +output_arrays= +; input shapes corresponding to --input_arrays, colon-separated.(ex:1,4,4,3:1,20,20,3) +input_shapes= + +[one-import-tflite] +# mandatory +; tflite file +input_path= +; circle file +output_path= + +[one-import-bcq] +# mandatory +; bcq file +input_path= +; circle file +output_path= +# optional +; v1 or v2 +converter_version=v2 +; graph_def(default), saved_model or keras_model +model_format=graph_def +# optional but mandatory for model_format=graph_def +; input tensor names of the input arrays, comma-separated +input_arrays= +; output tensor names of the input arrays, comma-separated +output_arrays= +; input shapes corresponding to --input_arrays, colon-separated.(ex:1,4,4,3:1,20,20,3) +input_shapes= + +[one-import-onnx] +# mandatory +; onnx file +input_path= +; circle file +output_path= +# optional +; True or False +unroll_rnn= +; True or False +unroll_lstm= [one-optimize] -input_path=inception_v3.circle -output_path=inception_v3.opt.circle -generate_profile_data=False +# mandatory +; circle file +input_path= +; circle file +output_path= +# //TODO: Add available options + +[one-quantize] +# mandatory +; circle file +input_path= +; circle file +output_path= +# optional arguments for quantization +; input data file (if not given, random data will be used for calibration) +input_data= +; h5/hdf5(default), list/filelist, or dir/directory +input_data_format= +; dtype of quantized model (uint8(default), int16) +quantized_dtype= +; granularity of quantization (layer(default), channel) +granularity= +; dtype of model's input (uint8, int16, float32). Same with quantized_dtype by default. +input_type= +; dtype of model's output (uint8, int16, float32). Same with quantized_dtype by default. +output_type= + +[one-partition] +# mandatory +; partition file which provides backend to assign +part_file= +; circle file +input_file= +# //TODO: Add available options [one-pack] -input_path=inception_v3.opt.circle -output_path=inception_v3_pack +# mandatory +; input path +input_path= +; output path +output_path= +# //TODO: Add available options + +[one-codegen] +# mandatory +; backend name +backend= +; commands for each backend +command= + +[one-profile] +# mandatory +; backend name +backend= +# //TODO: Add available options + +[one-infer] +# mandatory (mutually exclusive) +; backend name +backend= +; driver name +driver= +# //TODO: Add available options diff --git a/compiler/one-cmds/onelib/CfgRunner.py b/compiler/one-cmds/onelib/CfgRunner.py new file mode 100644 index 000000000..c66e5b4ba --- /dev/null +++ b/compiler/one-cmds/onelib/CfgRunner.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +# 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. + +import configparser +import os +import warnings + +import utils as oneutils + + +def _simple_warning(message, category, filename, lineno, file=None, line=None): + return f'{category.__name__}: {message}\n' + + +class CfgRunner: + driver_sequence = [ + 'one-optimize', 'one-quantize', 'one-pack', 'one-codegen', 'one-profile', + 'one-partition', 'one-infer' + ] + + def __init__(self, path): + self.path = path + self.optparser = None + self.cfgparser = configparser.ConfigParser() + # make option names case sensitive + self.cfgparser.optionxform = str + parsed = self.cfgparser.read(os.path.expanduser(path)) + if not parsed: + raise FileNotFoundError('Not found given configuration file') + + self._verify_cfg(self.cfgparser) + # default import drivers + self.import_drivers = [ + 'one-import-bcq', 'one-import-onnx', 'one-import-tf', 'one-import-tflite' + ] + + def _verify_cfg(self, cfgparser): + if not cfgparser.has_section('onecc'): + if cfgparser.has_section('one-build'): + warnings.formatwarning = _simple_warning + warnings.warn( + "[one-build] section will be deprecated. Please use [onecc] section.") + else: + raise ImportError('[onecc] section is required in configuration file') + + def _is_available(self, driver): + # if there's no `onecc` section, it will find `one-build` section because of backward compatibility + return (self.cfgparser.has_option('onecc', driver) and self.cfgparser.getboolean( + 'onecc', driver)) or (self.cfgparser.has_option('one-build', driver) + and self.cfgparser.getboolean('one-build', driver)) + + def add_opt(self, opt): + self.optparser = configparser.ConfigParser() + # make option names case sensitive + self.optparser.optionxform = str + opt_book = dict( + zip(oneutils._get_optimization_list(get_name=True), + oneutils._get_optimization_list())) + parsed = self.optparser.read(opt_book['O' + opt]) + if not parsed: + raise FileNotFoundError('Not found given optimization configuration file') + if len(self.optparser.sections()) != 1 or self.optparser.sections( + )[0] != 'one-optimize': + raise AssertionError( + 'Optimization configuration file only allowed to have a \'one-optimize\' section' + ) + self.opt = opt + + def detect_import_drivers(self, dir): + self.import_drivers = list(oneutils._detect_one_import_drivers(dir).keys()) + + def run(self, working_dir, verbose=False): + section_to_run = [] + for d in self.import_drivers + self.driver_sequence: + if self._is_available(d): + section_to_run.append(d) + + for section in section_to_run: + options = ['--config', self.path, '--section', section] + if section == 'one-optimize' and self.optparser: + options += ['-O', self.opt] + if verbose: + options.append('--verbose') + driver_path = os.path.join(working_dir, section) + cmd = [driver_path] + options + oneutils._run(cmd) diff --git a/compiler/one-cmds/onelib/OptionBuilder.py b/compiler/one-cmds/onelib/OptionBuilder.py new file mode 100644 index 000000000..6a75783ad --- /dev/null +++ b/compiler/one-cmds/onelib/OptionBuilder.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +# 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. + +from onelib.constant import CONSTANT + + +class OptionBuilder: + def __init__(self, one_cmd_type): + self.type = one_cmd_type + + def _build_default(self, commands): + options = [] + for k, v in commands.items(): + options.extend(['--' + k, v]) + return options + + def _build_with_unknown_command(self, commands): + COMMAND_K = 'command' + options = [] + for k, v in commands.items(): + if k == COMMAND_K: + continue + options.extend(['--' + k, v]) + options.extend(['--']) + options.extend(commands[COMMAND_K].split()) + return options + + def _build_import(self, commands): + options = [] + arg_0 = ['save_intermediate'] + for k, v in commands.items(): + if k in arg_0 and v == "True": + options.extend(['--' + k]) + continue + options.extend(['--' + k, v]) + return options + + def _build_optimize(self, commands): + options = [] + arg_0 = ['generate_profile_data'] + arg_1 = ['input_path', 'output_path', 'change_outputs'] + for k, v in commands.items(): + if k in arg_1: + options.extend(['--' + k, v]) + continue + if k in arg_0 and v == 'True': + options.extend(['--' + k]) + continue + for opt in CONSTANT.OPTIMIZATION_OPTS: + if k == opt[0] and v == "True": + options.extend(['--' + k]) + break + return options + + def _build_quantize(self, commands): + options = [] + arg_0 = [ + 'generate_profile_data', 'save_intermediate', 'TF-style_maxpool', + 'evaluate_result', 'print_mae', 'print_mape', 'print_mpeir', + 'print_top1_match', 'print_top5_match', 'force_quantparam', 'copy_quantparam' + ] + for k, v in commands.items(): + if k in arg_0 and v == "True": + options.extend(['--' + k]) + continue + options.extend(['--' + k, v]) + return options + + def build(self, commands): + cmd_book = dict.fromkeys( + ['one-import-bcq', 'one-import-tflite', 'one-pack', 'one-partition'], + self._build_default) + cmd_book['one-codegen'] = self._build_with_unknown_command + cmd_book['one-import-onnx'] = self._build_import + cmd_book['one-import-pytorch'] = self._build_import + cmd_book['one-import-tf'] = self._build_import + cmd_book['one-infer'] = self._build_with_unknown_command + cmd_book['one-optimize'] = self._build_optimize + cmd_book['one-profile'] = self._build_with_unknown_command + cmd_book['one-quantize'] = self._build_quantize + + return cmd_book[self.type](commands) diff --git a/compiler/one-cmds/onelib/TopologicalSortHelper.py b/compiler/one-cmds/onelib/TopologicalSortHelper.py new file mode 100644 index 000000000..d05adea8d --- /dev/null +++ b/compiler/one-cmds/onelib/TopologicalSortHelper.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +# 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. + +from collections import defaultdict + + +class TopologicalSortHelper: + def __init__(self, vertices): + self.graph = defaultdict(list) + self.vertices = vertices + + def add_edge(self, u, v): + self.graph[u].append(v) + + def sort_util(self, v, visited, stack): + visited[v] = True + + for i in self.graph[v]: + if visited[i] == False: + self.sort_util(i, visited, stack) + + stack.insert(0, v) + + def sort(self): + visited = dict.fromkeys(self.vertices, False) + stack = [] + + for v in self.vertices: + if visited[v] == False: + self.sort_util(v, visited, stack) + + return stack diff --git a/compiler/one-cmds/onelib/WorkflowRunner.py b/compiler/one-cmds/onelib/WorkflowRunner.py new file mode 100644 index 000000000..0482dd9da --- /dev/null +++ b/compiler/one-cmds/onelib/WorkflowRunner.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python + +# 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. + +import json +import os + +from onelib.OptionBuilder import OptionBuilder +from onelib.TopologicalSortHelper import TopologicalSortHelper +from onelib.CfgRunner import CfgRunner +import utils as oneutils + + +class WorkflowRunner: + WORKFLOWS_K = 'workflows' + DEPENDENCIES_K = 'run-after' + CFG_REFERENCE_K = 'cfg-reference' + WORKFLOW_STEPS_K = 'steps' + ONE_CMD_TOOL_K = 'one-cmd' + COMMANDS_K = 'commands' + + def __init__(self, path): + try: + with open(path) as f: + self.json_contents = json.load(f) + except FileNotFoundError: + raise FileNotFoundError("Not found given workflow file") + except json.decoder.JSONDecodeError: + raise ImportError("Invalid workflow file") + + self._verify_workflow(self.json_contents) + + workflows = self.json_contents[self.WORKFLOWS_K] + self.adj = dict.fromkeys(workflows, []) + # decide the order according to the dependencies of each workflow. + helper = TopologicalSortHelper(workflows) + for workflow_k in workflows: + workflow = self.json_contents[workflow_k] + if self.DEPENDENCIES_K in workflow: + for previous_workflow in workflow[self.DEPENDENCIES_K]: + helper.add_edge(previous_workflow, workflow_k) + self.adj[previous_workflow].append(workflow_k) + self.workflow_sequence = helper.sort() + + self._check_cycle() + + def _check_cycle(self): + pos = dict() + index = 0 + workflow_num = len(self.workflow_sequence) + # number the order + for seq_idx in range(workflow_num): + pos[self.workflow_sequence[seq_idx]] = index + index += 1 + + for seq_idx in range(workflow_num): + first_wf = self.workflow_sequence[seq_idx] + for adj_wf in self.adj[first_wf]: + first_pos = 0 if first_wf not in pos else pos[first_wf] + second_pos = 0 if adj_wf not in pos else pos[adj_wf] + if (first_pos > second_pos): + raise RuntimeError("Workflows should not have a cycle") + + def _verify_workflow(self, json_contents): + # workflow file should have WORKFLOWS_K + if not self.WORKFLOWS_K in json_contents: + raise ValueError("Not found \"" + self.WORKFLOWS_K + + "\" key in workflow file") + + workflows = json_contents[self.WORKFLOWS_K] + # workflow file should have keys listed in WORKFLOWS_K + for workflow_k in workflows: + if not workflow_k in json_contents: + raise ValueError("Not found " + workflow_k + " key listed in \"" + + self.WORKFLOWS_K + "\"") + + # each workflow should have either WORKFLOW_STEPS_K or CFG_REFERENCE_K + for workflow_k in workflows: + if not self.WORKFLOW_STEPS_K in json_contents[workflow_k] and not self.CFG_REFERENCE_K in json_contents[workflow_k]: + raise ValueError("Each workflow should have either \"" + + self.WORKFLOW_STEPS_K + "\" or \"" + + self.CFG_REFERENCE_K + "\"") + for workflow_k in workflows: + if self.WORKFLOW_STEPS_K in json_contents[workflow_k] and self.CFG_REFERENCE_K in json_contents[workflow_k]: + raise ValueError("\"" + self.WORKFLOW_STEPS_K + "\" and \"" + + self.CFG_REFERENCE_K + "\" are exclusive key") + + # each step should have ONE_CMD_TOOL_K and COMMANDS_K + for workflow_k in workflows: + workflow = json_contents[workflow_k] + if self.WORKFLOW_STEPS_K in workflow: + step_keys = workflow[self.WORKFLOW_STEPS_K] + for step_k in step_keys: + step = workflow[step_k] + if not self.ONE_CMD_TOOL_K in step or not self.COMMANDS_K in step: + raise ValueError("Each step should have \"" + + self.ONE_CMD_TOOL_K + "\"" + " and \"" + + self.COMMANDS_K + "\"") + + def run(self, working_dir, verbose=False): + # run workflows in sequence + for workflow_k in self.workflow_sequence: + workflow = self.json_contents[workflow_k] + if self.WORKFLOW_STEPS_K in workflow: + steps = workflow[self.WORKFLOW_STEPS_K] + for step_k in steps: + step = workflow[step_k] + commands = step[self.COMMANDS_K] + driver_name = step[self.ONE_CMD_TOOL_K] + option_builder = OptionBuilder(driver_name) + options = option_builder.build(commands) + # get the absolute path of the caller + driver_path = os.path.join(working_dir, driver_name) + cmd = [driver_path] + options + oneutils._run(cmd) + elif self.CFG_REFERENCE_K in workflow: + cfg_path = workflow[self.CFG_REFERENCE_K]['path'] + runner = CfgRunner(cfg_path) + runner.run(working_dir, verbose) diff --git a/compiler/one-cmds/onelib/constant.py b/compiler/one-cmds/onelib/constant.py index 7ddd7382d..7dd79b65d 100644 --- a/compiler/one-cmds/onelib/constant.py +++ b/compiler/one-cmds/onelib/constant.py @@ -14,11 +14,11 @@ # See the License for the specific language governing permissions and # limitations under the License. + class CONSTANT: __slots__ = () # This prevents access via __dict__. OPTIMIZATION_OPTS = ( # (OPTION_NAME, HELP_MESSAGE) - ('O1', 'enable O1 optimization pass'), ('convert_nchw_to_nhwc', 'Experimental: This will convert NCHW operators to NHWC under the assumption that input model is NCHW.' ), @@ -29,6 +29,7 @@ class CONSTANT: 'convert the output shape of the model (argument for convert_nchw_to_nhwc)'), ('fold_add_v2', 'fold AddV2 op with constant inputs'), ('fold_cast', 'fold Cast op with constant input'), + ('fold_densify', 'fold Densify op with sparse constant input'), ('fold_dequantize', 'fold Dequantize op'), ('fold_dwconv', 'fold Depthwise Convolution op with constant inputs'), ('fold_gather', 'fold Gather op'), @@ -62,12 +63,16 @@ class CONSTANT: ('remove_unnecessary_slice', 'remove unnecessary slice ops'), ('remove_unnecessary_strided_slice', 'remove unnecessary strided slice ops'), ('remove_unnecessary_split', 'remove unnecessary split ops'), + ('replace_non_const_fc_with_batch_matmul', + 'replace FullyConnected op with non-const weights to BatchMatMul op'), + ('replace_sub_with_add', 'replace Sub op with Add op'), ('resolve_customop_add', 'convert Custom(Add) op to Add op'), ('resolve_customop_batchmatmul', 'convert Custom(BatchMatmul) op to BatchMatmul op'), ('resolve_customop_matmul', 'convert Custom(Matmul) op to Matmul op'), ('resolve_customop_max_pool_with_argmax', 'convert Custom(MaxPoolWithArgmax) to net of builtin operators'), + ('resolve_customop_splitv', 'convert Custom(SplitV) op to SplitV op'), ('shuffle_weight_to_16x1float32', 'convert weight format of FullyConnected op to SHUFFLED16x1FLOAT32.' ' Note that it only converts weights whose row is a multiple of 16'), diff --git a/compiler/one-cmds/onelib/make_cmd.py b/compiler/one-cmds/onelib/make_cmd.py index d8380f28d..0015e8319 100644 --- a/compiler/one-cmds/onelib/make_cmd.py +++ b/compiler/one-cmds/onelib/make_cmd.py @@ -19,6 +19,7 @@ import sys import onelib.constant as _constant + def _is_valid_attr(args, attr): return hasattr(args, attr) and getattr(args, attr) @@ -64,6 +65,10 @@ def make_tf2tfliteV2_cmd(args, driver_path, input_path, output_path): cmd.append('--output_arrays') cmd.append(getattr(args, 'output_arrays')) + # experimental options + if _is_valid_attr(args, 'experimental_disable_batchmatmul_unfold'): + cmd.append('--experimental_disable_batchmatmul_unfold') + return cmd diff --git a/compiler/one-cmds/onnx_legalizer.py b/compiler/one-cmds/onnx_legalizer.py index 26c2b75b9..0141514b6 100755 --- a/compiler/one-cmds/onnx_legalizer.py +++ b/compiler/one-cmds/onnx_legalizer.py @@ -341,7 +341,8 @@ def _dtype_to_np(dtype): raise NotImplementedError('unsupported data type') -def _generate_one_direction_RNN(transformer, X, W, R, B, initial_h, clip, activation_name): +def _generate_one_direction_RNN(transformer, X, W, R, B, initial_h, clip, + activation_name): """Generate subgraph of one direction of unrolled RNN layer Args: @@ -395,7 +396,7 @@ def _generate_one_direction_RNN(transformer, X, W, R, B, initial_h, clip, activa def _transform_unidirectional_RNN(transformer, original_node, x, tensor_infos, activation, - clip, direction, hidden_size, layout): + clip, direction, hidden_size, layout): """Generate Simple (forward or reverse) unrolled RNN Args: @@ -432,7 +433,7 @@ def _transform_unidirectional_RNN(transformer, original_node, x, tensor_infos, a else: initial_h = None state_tensors = _generate_one_direction_RNN(transformer, x, w, r, b, initial_h, clip, - activation) + activation) y_direction_dim = layout + 1 y_h_direction_dim = layout state_layout_tensors = [] @@ -447,12 +448,11 @@ def _transform_unidirectional_RNN(transformer, original_node, x, tensor_infos, a transformer.make_node( 'Unsqueeze', [state_tensors[-1]], [Y_h], axes=[y_h_direction_dim]) Y = outputs[0] - transformer.make_node( - 'Concat', state_layout_tensors, [Y], axis=seq_length_dim) + transformer.make_node('Concat', state_layout_tensors, [Y], axis=seq_length_dim) def _transform_bidirectional_RNN(transformer, original_node, x, tensor_infos, activations, - clip, hidden_size, layout): + clip, hidden_size, layout): """Generate Bidirectional unrolled RNN Args: @@ -503,10 +503,10 @@ def _transform_bidirectional_RNN(transformer, original_node, x, tensor_infos, ac initial_h[d] = transformer.make_squeeze(initial_h[d], axes=[direction_dim]) state_f_tensors = _generate_one_direction_RNN(transformer, x, w[0], r[0], b[0], - initial_h[0], clip, activations[0]) + initial_h[0], clip, activations[0]) x.reverse() state_b_tensors = _generate_one_direction_RNN(transformer, x, w[1], r[1], b[1], - initial_h[1], clip, activations[1]) + initial_h[1], clip, activations[1]) state_b_tensors.reverse() y_direction_dim = layout + 1 @@ -538,8 +538,7 @@ def _transform_bidirectional_RNN(transformer, original_node, x, tensor_infos, ac axis=y_h_direction_dim) Y = outputs[0] - transformer.make_node( - 'Concat', state_layout_tensors, [Y], axis=seq_length_dim) + transformer.make_node('Concat', state_layout_tensors, [Y], axis=seq_length_dim) def _legalize_RNN(transformer, tensor_infos, node): @@ -600,10 +599,10 @@ def _legalize_RNN(transformer, tensor_infos, node): if direction in ['forward', 'reverse']: _transform_unidirectional_RNN(transformer, node, x, tensor_infos, activations[0], - clip, direction, hidden_size, layout) + clip, direction, hidden_size, layout) elif direction == 'bidirectional': - _transform_bidirectional_RNN(transformer, node, x, tensor_infos, activations, clip, - hidden_size, layout) + _transform_bidirectional_RNN(transformer, node, x, tensor_infos, activations, + clip, hidden_size, layout) else: raise RuntimeError('Unknown RNN type') @@ -611,7 +610,7 @@ def _legalize_RNN(transformer, tensor_infos, node): def _generate_one_direction_LSTM(transformer, X, W, R, B, initial_h, initial_c, P, clip, - act, dtype, hidden_size, batch_size): + act, dtype, hidden_size, batch_size): """Generate subgraph for one direction of unrolled LSTM layer Args: @@ -754,7 +753,7 @@ def _generate_one_direction_LSTM(transformer, X, W, R, B, initial_h, initial_c, def _transform_unidirectional_LSTM(transformer, original_node, x, tensor_infos, - activations, clip, direction, hidden_size, layout): + activations, clip, direction, hidden_size, layout): """Generate Simple (forward or reverse) unrolled LSTM Args: @@ -818,17 +817,15 @@ def _transform_unidirectional_LSTM(transformer, original_node, x, tensor_infos, transformer.make_node( 'Unsqueeze', [state_h_tensors[-1]], [Y_h], axes=[y_h_direction_dim]) Y_c = outputs[2] - transformer.make_node( - 'Unsqueeze', [state_c_tensor], [Y_c], axes=[y_h_direction_dim]) + transformer.make_node('Unsqueeze', [state_c_tensor], [Y_c], axes=[y_h_direction_dim]) if direction == 'reverse': state_layout_tensors.reverse() Y = outputs[0] - transformer.make_node( - 'Concat', state_layout_tensors, [Y], axis=seq_length_dim) + transformer.make_node('Concat', state_layout_tensors, [Y], axis=seq_length_dim) -def _transform_bidirectional_LSTM(transformer, original_node, x, tensor_infos, activations, - clip, hidden_size, layout): +def _transform_bidirectional_LSTM(transformer, original_node, x, tensor_infos, + activations, clip, hidden_size, layout): """Generate Bidirectional unrolled LSTM Args: @@ -929,12 +926,10 @@ def _transform_bidirectional_LSTM(transformer, original_node, x, tensor_infos, a Y_f_c = transformer.make_unsqueeze(state_f_c_tensor, axes=[y_c_direction_dim]) Y_b_c = transformer.make_unsqueeze(state_b_c_tensor, axes=[y_c_direction_dim]) Y_c = outputs[2] - transformer.make_node( - 'Concat', [Y_f_c, Y_b_c], [Y_c], axis=y_c_direction_dim) + transformer.make_node('Concat', [Y_f_c, Y_b_c], [Y_c], axis=y_c_direction_dim) Y = outputs[0] - transformer.make_node( - 'Concat', state_layout_tensors, [Y], axis=seq_length_dim) + transformer.make_node('Concat', state_layout_tensors, [Y], axis=seq_length_dim) def _legalize_LSTM(transformer, tensor_infos, node): @@ -1001,10 +996,10 @@ def _legalize_LSTM(transformer, tensor_infos, node): if direction in ['forward', 'reverse']: _transform_unidirectional_LSTM(transformer, node, x, tensor_infos, activations, - clip, direction, hidden_size, layout) + clip, direction, hidden_size, layout) elif direction == 'bidirectional': _transform_bidirectional_LSTM(transformer, node, x, tensor_infos, activations, - clip, hidden_size, layout) + clip, hidden_size, layout) else: raise RuntimeError('Unknown LSTM type') @@ -1052,10 +1047,12 @@ def legalize(model, options): if __name__ == '__main__': if len(sys.argv) < 3: - print('usage: ./legalize_onnx.py <path to input model> <path to output model>\n' - '\n' - ' In stand-alone utility mode this tool provides basic funtionality\n' - ' If you want to have more control over applied transformations, use this legalizer as a library') + print( + 'usage: ./legalize_onnx.py <path to input model> <path to output model>\n' + '\n' + ' In stand-alone utility mode this tool provides basic funtionality\n' + ' If you want to have more control over applied transformations, use this legalizer as a library' + ) exit(1) options = LegalizeOptions() options.unroll_lstm = True diff --git a/compiler/one-cmds/requires.cmake b/compiler/one-cmds/requires.cmake index b1aabdb97..c27920980 100644 --- a/compiler/one-cmds/requires.cmake +++ b/compiler/one-cmds/requires.cmake @@ -1,6 +1,7 @@ require("tf2tfliteV2") require("tflite2circle") require("circle2circle") +require("circle-eval-diff") require("circle-quantizer") require("record-minmax") require("vconone") diff --git a/compiler/one-cmds/tests/CMakeLists.txt b/compiler/one-cmds/tests/CMakeLists.txt index caea756c2..17f55ec96 100644 --- a/compiler/one-cmds/tests/CMakeLists.txt +++ b/compiler/one-cmds/tests/CMakeLists.txt @@ -4,6 +4,8 @@ file(GLOB TESTITEMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "./*.test") file(GLOB CONFIGITEMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "./*.cfg") file(GLOB QCONFIGITEMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "./*.qconf.json") +file(GLOB PYSCRIPTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "./*.py") +file(GLOB WORKFLOWITEMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "./*.workflow.json") # Create a script to run the tests at installation folder set(DRIVER_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/runtestall.sh") @@ -45,6 +47,16 @@ foreach(QCONFIGITEM IN ITEMS ${QCONFIGITEMS}) install(FILES ${QCONFIGITEM} DESTINATION test) endforeach(QCONFIGITEM) +foreach(PYSCRIPT IN ITEMS ${PYSCRIPTS}) + get_filename_component(ITEM_PREFIX ${PYSCRIPT} NAME_WE) + install(FILES ${PYSCRIPT} DESTINATION test) +endforeach(PYSCRIPT) + +foreach(WORKFLOWITEM IN ITEMS ${WORKFLOWITEMS}) + get_filename_component(ITEM_PREFIX ${WORKFLOWITEM} NAME_WE) + install(FILES ${WORKFLOWITEM} DESTINATION test) +endforeach(WORKFLOWITEM) + file(APPEND "${DRIVER_SCRIPT}" "popd > /dev/null\n\n") file(APPEND "${DRIVER_SCRIPT}" diff --git a/compiler/one-cmds/tests/OONECC_024.cfg b/compiler/one-cmds/tests/OONECC_024.cfg new file mode 100644 index 000000000..a39aae071 --- /dev/null +++ b/compiler/one-cmds/tests/OONECC_024.cfg @@ -0,0 +1,2 @@ +[one-optimize] +make_batchnorm_gamma_positive=True diff --git a/compiler/one-cmds/tests/one-build_008.cfg b/compiler/one-cmds/tests/one-build_008.cfg index 615047c86..8c777f64f 100644 --- a/compiler/one-cmds/tests/one-build_008.cfg +++ b/compiler/one-cmds/tests/one-build_008.cfg @@ -15,7 +15,6 @@ output_path=test_onnx_model.circle [one-optimize] input_path=test_onnx_model.circle output_path=test_onnx_model.opt.circle -all=True remove_redundant_transpose=True [one-codegen] diff --git a/compiler/one-cmds/tests/one-build_009.cfg b/compiler/one-cmds/tests/one-build_009.cfg index 66bca250d..b5a35dd97 100644 --- a/compiler/one-cmds/tests/one-build_009.cfg +++ b/compiler/one-cmds/tests/one-build_009.cfg @@ -15,7 +15,6 @@ output_path=onnx_conv2d_conv2d.circle [one-optimize] input_path=onnx_conv2d_conv2d.circle output_path=onnx_conv2d_conv2d.opt.circle -all=True remove_redundant_transpose=True convert_nchw_to_nhwc=True diff --git a/compiler/one-cmds/tests/one-import-onnx_002.test b/compiler/one-cmds/tests/one-import-onnx_002.test new file mode 100644 index 000000000..a6a38eee5 --- /dev/null +++ b/compiler/one-cmds/tests/one-import-onnx_002.test @@ -0,0 +1,71 @@ +#!/bin/bash + +# 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 for experimental_disable_batchmatmul_unfold option + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="./reshape_matmul.onnx" +outputfile="./reshape_matmul.circle" + +rm -rf ${outputfile} +rm -rf ${outputfile}.log + +# run test without option that should drop FULLY_CONNECTED +one-import-onnx \ +--input_path ${inputfile} \ +--output_path ${outputfile} > /dev/null 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +circle-operator --code reshape_matmul.circle > ${outputfile}.log 2>&1 + +if ! grep -q "FULLY_CONNECTED" "${outputfile}.log"; then + trap_err_onexit +fi + +rm -rf ${outputfile} +rm -rf ${outputfile}.log + +# run test with option that should drop BATCH_MATMUL +one-import-onnx \ +--experimental_disable_batchmatmul_unfold \ +--input_path ${inputfile} \ +--output_path ${outputfile} > /dev/null 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +circle-operator --code reshape_matmul.circle > ${outputfile}.log 2>&1 + +if ! grep -q "BATCH_MATMUL" "${outputfile}.log"; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" +exit 0 diff --git a/compiler/one-cmds/tests/one-infer-test-post-process.py b/compiler/one-cmds/tests/one-infer-test-post-process.py new file mode 100644 index 000000000..0f0e0d701 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer-test-post-process.py @@ -0,0 +1,16 @@ +# This script gets one argument and print it + +import sys +from pathlib import Path + + +def main(): + if len(sys.argv) < 2: + filepath = Path(sys.argv[0]) + sys.exit("Usage: " + filepath.name + " [Word to print]") + word = sys.argv[1] + print(word) + + +if __name__ == '__main__': + main() diff --git a/compiler/one-cmds/tests/one-infer_001.test b/compiler/one-cmds/tests/one-infer_001.test new file mode 100644 index 000000000..e7b569522 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_001.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/help-infer + exit 255 +} + +trap trap_err_onexit ERR + +# copy help-infer to bin folder +cp help-infer ../bin/help-infer + +# run test +one-infer -b help -- -h > ${filename}.log + +rm -rf ../bin/help-infer + +if grep -q "HELP MESSAGE!!" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/one-infer_002.test b/compiler/one-cmds/tests/one-infer_002.test new file mode 100644 index 000000000..22070de19 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_002.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-infer + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="sample.tvn" + +if [[ ! -s "${inputfile}" ]]; then + touch ${inputfile} +fi + +# copy dummy-infer to bin folder +cp dummy-infer ../bin/dummy-infer + +# run test +one-infer -d dummy-infer -- ${inputfile} > ${filename}.log + +rm -rf ../bin/dummy-infer + +if grep -q "dummy-infer dummy output!!!" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/one-infer_003.test b/compiler/one-cmds/tests/one-infer_003.test new file mode 100644 index 000000000..e2aa459a1 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_003.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-infer + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="sample.tvn" + +if [[ ! -s "${inputfile}" ]]; then + touch ${inputfile} +fi + +# copy dummy-infer to bin folder +cp dummy-infer ../bin/dummy-infer + +# run test +one-infer -b dummy -- ${inputfile} > ${filename}.log + +rm -rf ../bin/dummy-infer + +if grep -q "dummy-infer dummy output!!!" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/one-infer_004.test b/compiler/one-cmds/tests/one-infer_004.test new file mode 100644 index 000000000..a4cb76c55 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_004.test @@ -0,0 +1,38 @@ +#!/bin/bash + +# 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. + +# print one-infer's help message + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +# run test +one-infer -h > ${filename}.log + +if grep -q "command line tool to infer model" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/one-infer_005.cfg b/compiler/one-cmds/tests/one-infer_005.cfg new file mode 100644 index 000000000..aca687801 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_005.cfg @@ -0,0 +1,3 @@ +[one-infer] +backend=dummy +command=sample.tvn diff --git a/compiler/one-cmds/tests/one-infer_005.test b/compiler/one-cmds/tests/one-infer_005.test new file mode 100644 index 000000000..a44dd0e25 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_005.test @@ -0,0 +1,51 @@ +#!/bin/bash + +# 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. + +# one-infer with configuration input + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-infer + exit 255 +} + +trap trap_err_onexit ERR + +configfile="one-infer_005.cfg" +inputfile="sample.tvn" + +if [[ ! -s "${inputfile}" ]]; then + touch ${inputfile} +fi + +# copy dummy-infer to bin folder +cp dummy-infer ../bin/dummy-infer + +# run test +one-infer -C ${configfile} > ${filename}.log + +rm -rf ../bin/dummy-infer + +if grep -q "dummy-infer dummy output!!!" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/one-infer_006.test b/compiler/one-cmds/tests/one-infer_006.test new file mode 100644 index 000000000..2612133a3 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_006.test @@ -0,0 +1,53 @@ +#!/bin/bash + +# 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. + +# one-infer with post process script + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-infer + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="sample.tvn" + +if [[ ! -s "${inputfile}" ]]; then + touch ${inputfile} +fi + +# copy dummy-infer to bin folder +cp dummy-infer ../bin/dummy-infer + +# run test +one-infer -b dummy --post-process "./one-infer-test-post-process.py TOKEN" -- ${inputfile} > ${filename}.log 2>&1 +return_code=$? + +rm -rf ../bin/dummy-infer + +if grep -q "dummy-infer dummy output!!!" "${filename}.log"; then + if [ "$return_code" -eq "0" ]; then + echo "${filename_ext} SUCCESS" + exit 0 + fi +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/one-infer_neg_001.test b/compiler/one-cmds/tests/one-infer_neg_001.test new file mode 100644 index 000000000..62e721128 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_neg_001.test @@ -0,0 +1,39 @@ +#!/bin/bash + +# 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. + +# negative usage with no input + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "error: the following arguments are required: {-d/--driver | -b/--backend}" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +# run test +one-infer > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/one-infer_neg_002.test b/compiler/one-cmds/tests/one-infer_neg_002.test new file mode 100644 index 000000000..fa88876e8 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_neg_002.test @@ -0,0 +1,40 @@ +#!/bin/bash + +# 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. + +# passed driver is not found + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" +driver_name="neg-infer" + +trap_err_onexit() +{ + if grep -q "FileNotFoundError: ${driver_name} not found" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +# run test +one-infer -d ${driver_name} -- -h> ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/one-infer_neg_003.test b/compiler/one-cmds/tests/one-infer_neg_003.test new file mode 100644 index 000000000..a0005520f --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_neg_003.test @@ -0,0 +1,40 @@ +#!/bin/bash + +# 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. + +# passed backend is not found + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" +backend_name="neg" + +trap_err_onexit() +{ + if grep -q "FileNotFoundError: ${backend_name}-infer not found" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +# run test +one-infer -b ${backend_name} -- -h> ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/one-infer_neg_004.test b/compiler/one-cmds/tests/one-infer_neg_004.test new file mode 100644 index 000000000..b9130d051 --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_neg_004.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# both -b and -d option drivers are given as argument + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" +backend_name="neg" +driver_name="neg2" + +trap_err_onexit() +{ + if grep -q "\-d and -b options are mutually exclusive. Please use only one of them" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +# run test +one-infer -d ${driver_name} -b ${backend_name} -- -h> ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/one-infer_neg_005.test b/compiler/one-cmds/tests/one-infer_neg_005.test new file mode 100644 index 000000000..9074debcf --- /dev/null +++ b/compiler/one-cmds/tests/one-infer_neg_005.test @@ -0,0 +1,54 @@ +#!/bin/bash + +# 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. + +# one-infer with invalid post process script + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + return_code=$? + if grep -q "dummy-infer dummy output!!!" "${filename}.log"; then + # Case of succeed of inference driver but error after it + if [ "$return_code" -ne "0" ]; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + fi + + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-infer + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="sample.tvn" + +if [[ ! -s "${inputfile}" ]]; then + touch ${inputfile} +fi + +# copy dummy-infer to bin folder +cp dummy-infer ../bin/dummy-infer + +# run test +one-infer -b dummy --post-process "./one-infer-test-post-process.py" -- ${inputfile} > ${filename}.log 2>&1 + +rm -rf ../bin/dummy-infer +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/one-optimize_001.test b/compiler/one-cmds/tests/one-optimize_001.test index 8eb58f4eb..4152fa3dd 100644 --- a/compiler/one-cmds/tests/one-optimize_001.test +++ b/compiler/one-cmds/tests/one-optimize_001.test @@ -40,7 +40,7 @@ if [[ ! -s ${inputfile} ]]; then fi # run test -one-optimize --O1 \ +one-optimize --resolve_customop_add \ --input_path ${inputfile} \ --output_path ${outputfile} > /dev/null 2>&1 diff --git a/compiler/one-cmds/tests/one-optimize_002.test b/compiler/one-cmds/tests/one-optimize_002.test index bd64494be..58f792bf8 100644 --- a/compiler/one-cmds/tests/one-optimize_002.test +++ b/compiler/one-cmds/tests/one-optimize_002.test @@ -40,7 +40,7 @@ if [[ ! -s ${inputfile} ]]; then fi # run test -one-optimize --O1 \ +one-optimize --resolve_customop_add \ --change_outputs InceptionV3/Logits/SpatialSqueeze1 \ --input_path ${inputfile} \ --output_path ${outputfile} > /dev/null 2>&1 diff --git a/compiler/one-cmds/tests/one-optimize_neg_001.test b/compiler/one-cmds/tests/one-optimize_neg_001.test index f0b5563c7..c67e3d489 100644 --- a/compiler/one-cmds/tests/one-optimize_neg_001.test +++ b/compiler/one-cmds/tests/one-optimize_neg_001.test @@ -39,7 +39,7 @@ rm -rf ${outputfile} rm -rf ${outputfile}.log # run test -one-optimize --O1 \ +one-optimize --resolve_customop_add \ --input_path ${inputfile} \ --output_path ${outputfile} > ${filename}.log 2>&1 diff --git a/compiler/one-cmds/tests/one-optimize_neg_002.test b/compiler/one-cmds/tests/one-optimize_neg_002.test index 72f306e20..a1ef70216 100644 --- a/compiler/one-cmds/tests/one-optimize_neg_002.test +++ b/compiler/one-cmds/tests/one-optimize_neg_002.test @@ -39,7 +39,7 @@ rm -rf ${outputfile} rm -rf ${outputfile}.log # run test -one-optimize --O1 \ +one-optimize --resolve_customop_add \ --input_path ${inputfile} \ --output_path ${outputfile} > ${filename}.log 2>&1 diff --git a/compiler/one-cmds/tests/one-optimize_neg_003.test b/compiler/one-cmds/tests/one-optimize_neg_003.test index 3fe7d330e..668a6c29d 100644 --- a/compiler/one-cmds/tests/one-optimize_neg_003.test +++ b/compiler/one-cmds/tests/one-optimize_neg_003.test @@ -44,7 +44,7 @@ if [[ ! -s ${inputfile} ]]; then fi # run test -one-optimize --O1 \ +one-optimize --resolve_customop_add \ --input_path "${inputfile}" > "${filename}.log" 2>&1 echo "${filename_ext} FAILED" diff --git a/compiler/one-cmds/tests/one-optimize_neg_004.test b/compiler/one-cmds/tests/one-optimize_neg_004.test index e73911b54..5abd4c553 100644 --- a/compiler/one-cmds/tests/one-optimize_neg_004.test +++ b/compiler/one-cmds/tests/one-optimize_neg_004.test @@ -39,7 +39,7 @@ rm -rf ${outputfile} rm -rf ${filename}.log # run test -one-optimize --O1 \ +one-optimize --resolve_customop_add \ --change_outputs non_existing_node_name \ --input_path ${inputfile} \ --output_path ${outputfile} > ${filename}.log 2>&1 diff --git a/compiler/one-cmds/tests/one-partition_001.test b/compiler/one-cmds/tests/one-partition_001.test new file mode 100644 index 000000000..a6fba07d7 --- /dev/null +++ b/compiler/one-cmds/tests/one-partition_001.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" +testmodel="Net_InstanceNorm_003" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="${testmodel}.circle" +partfile="${testmodel}.part" +outputfile="${testmodel}.conn.json" + +rm -rf ${testmodel}.000* +rm -rf ${testmodel}.conn.* +rm -rf ${testmodel}.*.log + +# run test +one-partition \ +--input_file ${inputfile} \ +--part_file ${partfile} > /dev/null 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-partition_neg_001.test b/compiler/one-cmds/tests/one-partition_neg_001.test new file mode 100644 index 000000000..d54a94fa2 --- /dev/null +++ b/compiler/one-cmds/tests/one-partition_neg_001.test @@ -0,0 +1,51 @@ +#!/bin/bash + +# 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. + +# negative usage with invalid .part file (wrong comply value) + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" +testmodel="Net_InstanceNorm_003" + +trap_err_onexit() +{ + if grep -q "ERROR" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="${testmodel}.circle" +partfile="${testmodel}.neg.part" +outputfile="${testmodel}.conn.json" + +rm -rf ${testmodel}.000* +rm -rf ${testmodel}.conn.* +rm -rf ${testmodel}.*.log +rm -rf ${filename}.log + +# run test +one-partition \ +--input_file ${inputfile} \ +--part_file ${partfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/one-partition_neg_002.test b/compiler/one-cmds/tests/one-partition_neg_002.test new file mode 100644 index 000000000..23fe84c05 --- /dev/null +++ b/compiler/one-cmds/tests/one-partition_neg_002.test @@ -0,0 +1,47 @@ +#!/bin/bash + +# 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. + +# negative usage with invalid .cfg file (no one-partition section) + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" +testmodel="Net_InstanceNorm_003" + +trap_err_onexit() +{ + if grep -q "'one-partition' section" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +cfgfile="${testmodel}.neg.cfg" + +rm -rf ${testmodel}.000* +rm -rf ${testmodel}.conn.* +rm -rf ${testmodel}.*.log +rm -rf ${filename}.log + +# run test +one-partition -C ${cfgfile}> ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/one-quantize_010.test b/compiler/one-cmds/tests/one-quantize_010.test new file mode 100644 index 000000000..1095ba0a0 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_010.test @@ -0,0 +1,65 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +check_message() +{ + if grep -q "MPEIR for InceptionV3/Predictions/Reshape_1 is" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + trap_err_onexit +} + +trap trap_err_onexit ERR + +inputfile="./inception_v3.circle" +outputfile="./inception_v3.one-quantize_010.q.circle" +datafile="./inception_v3_test_data.h5" + +rm -rf ${outputfile} + +# to create inception_v3.circle +if [[ ! -s ${inputfile} ]]; then + /bin/bash one-import_001.test > /dev/null 2>&1 + return_code=$? + if [[ ${return_code} != 0 ]]; then + trap_err_onexit + fi +fi + +# run test +one-quantize \ +--input_dtype float32 \ +--quantized_dtype uint8 \ +--granularity channel \ +--input_path ${inputfile} \ +--input_data ${datafile} \ +--output_path ${outputfile} \ +--evaluate_result \ +--test_data ${datafile} \ +--print_mpeir > ${filename}.log 2>&1 + +check_message diff --git a/compiler/one-cmds/tests/one-quantize_011.test b/compiler/one-cmds/tests/one-quantize_011.test new file mode 100644 index 000000000..34d7f57b5 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_011.test @@ -0,0 +1,56 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +check_message() +{ + if grep -q "Mean Top-5 match ratio for InceptionV3/Predictions/Reshape_1 is" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + trap_err_onexit +} + +trap trap_err_onexit ERR + +inputfile="./inception_v3.circle" +outputfile="./inception_v3.one-quantize_011.q.circle" +datafile="./inception_v3_test_data.h5" + +rm -rf ${outputfile} + +# run test +one-quantize \ +--input_dtype float32 \ +--quantized_dtype uint8 \ +--granularity channel \ +--input_path ${inputfile} \ +--input_data ${datafile} \ +--output_path ${outputfile} \ +--evaluate_result \ +--test_data ${datafile} \ +--print_top5_match > ${filename}.log 2>&1 + +check_message diff --git a/compiler/one-cmds/tests/one-quantize_012.qconf.json b/compiler/one-cmds/tests/one-quantize_012.qconf.json new file mode 100644 index 000000000..4a15b04f5 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_012.qconf.json @@ -0,0 +1,16 @@ +{ + "default_quantization_dtype" : "uint8", + "default_granularity" : "channel", + "layers" : [ + { + "names" : ["InceptionV3/InceptionV3/Conv2d_2b_3x3/Relu;InceptionV3/InceptionV3/Conv2d_2b_3x3/BatchNorm/FusedBatchNorm;InceptionV3/InceptionV3/Mixed_6a/Branch_1/Conv2d_0a_1x1/Conv2D;InceptionV3/InceptionV3/Conv2d_2b_3x3/Conv2D", + "InceptionV3/InceptionV3/MaxPool_5a_3x3/MaxPool", + "InceptionV3/InceptionV3/Mixed_5b/concat", + "InceptionV3/InceptionV3/Mixed_5b/Branch_3/AvgPool_0a_3x3/AvgPool", + "InceptionV3/InceptionV3/Mixed_7c/concat", + "InceptionV3/Predictions/Reshape_1"], + "dtype" : "int16", + "granularity" : "channel" + } + ] +} diff --git a/compiler/one-cmds/tests/one-quantize_012.test b/compiler/one-cmds/tests/one-quantize_012.test new file mode 100644 index 000000000..fba18acc5 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_012.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="./inception_v3.circle" +outputfile="./inception_v3.one-quantize_012.q.circle" + +rm -rf ${outputfile} + +# run test without input data +one-quantize \ +--input_dtype float32 \ +--quantized_dtype uint8 \ +--granularity channel \ +--quant_config one-quantize_012.qconf.json \ +--input_path ${inputfile} \ +--output_path ${outputfile} > /dev/null 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-quantize_013.qconf.json b/compiler/one-cmds/tests/one-quantize_013.qconf.json new file mode 100644 index 000000000..4a15b04f5 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_013.qconf.json @@ -0,0 +1,16 @@ +{ + "default_quantization_dtype" : "uint8", + "default_granularity" : "channel", + "layers" : [ + { + "names" : ["InceptionV3/InceptionV3/Conv2d_2b_3x3/Relu;InceptionV3/InceptionV3/Conv2d_2b_3x3/BatchNorm/FusedBatchNorm;InceptionV3/InceptionV3/Mixed_6a/Branch_1/Conv2d_0a_1x1/Conv2D;InceptionV3/InceptionV3/Conv2d_2b_3x3/Conv2D", + "InceptionV3/InceptionV3/MaxPool_5a_3x3/MaxPool", + "InceptionV3/InceptionV3/Mixed_5b/concat", + "InceptionV3/InceptionV3/Mixed_5b/Branch_3/AvgPool_0a_3x3/AvgPool", + "InceptionV3/InceptionV3/Mixed_7c/concat", + "InceptionV3/Predictions/Reshape_1"], + "dtype" : "int16", + "granularity" : "channel" + } + ] +} diff --git a/compiler/one-cmds/tests/one-quantize_013.test b/compiler/one-cmds/tests/one-quantize_013.test new file mode 100644 index 000000000..fd443d627 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_013.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +# quantized_dtype and granularity are given by qconfig file +# (not by command line interface) + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="./inception_v3.circle" +outputfile="./inception_v3.one-quantize_013.q.circle" + +rm -rf ${outputfile} + +# run test without input data +# quantized_dtype and granularity are not given here +one-quantize \ +--input_dtype float32 \ +--quant_config one-quantize_013.qconf.json \ +--input_path ${inputfile} \ +--output_path ${outputfile} > /dev/null 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-quantize_014.test b/compiler/one-cmds/tests/one-quantize_014.test new file mode 100644 index 000000000..518c32841 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_014.test @@ -0,0 +1,59 @@ +#!/bin/bash + +# 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 if `circle-eval-diff` supports directory input. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +check_message() +{ + if grep -q "Mean Top-5 match ratio for InceptionV3/Predictions/Reshape_1 is" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + trap_err_onexit +} + +trap trap_err_onexit ERR + +inputfile="./inception_v3.circle" +outputfile="./inception_v3.one-quantize_014.q.circle" +datadir="./raw_files/" + +rm -rf ${outputfile} + +# run test +one-quantize \ +--input_dtype float32 \ +--quantized_dtype uint8 \ +--granularity channel \ +--input_path ${inputfile} \ +--input_data ${datadir} \ +--input_data_format dir \ +--output_path ${outputfile} \ +--evaluate_result \ +--test_data ${datadir} \ +--print_top5_match > ${filename}.log 2>&1 + +check_message diff --git a/compiler/one-cmds/tests/one-quantize_015.test b/compiler/one-cmds/tests/one-quantize_015.test new file mode 100644 index 000000000..bb45b5722 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_015.test @@ -0,0 +1,45 @@ +#!/bin/bash + +# 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 if --fake_quantize option works well + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="./inception_v3.mat.q8.circle" +outputfile="./inception_v3.one-quantize_015.fq.circle" + +rm -rf ${outputfile} + +# run test +one-quantize \ +--fake_quantize \ +--input_path ${inputfile} \ +--output_path ${outputfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-quantize_neg_019.test b/compiler/one-cmds/tests/one-quantize_neg_019.test index ac920a4fe..e182edf78 100644 --- a/compiler/one-cmds/tests/one-quantize_neg_019.test +++ b/compiler/one-cmds/tests/one-quantize_neg_019.test @@ -42,7 +42,7 @@ one-quantize \ --input_dtype float32 \ --quantized_dtype int16 \ --granularity channel \ ---input_type float32 \ +--input_type float64 \ --input_path ${inputfile} \ --output_path ${outputfile} > ${filename}.log 2>&1 diff --git a/compiler/one-cmds/tests/one-quantize_neg_020.test b/compiler/one-cmds/tests/one-quantize_neg_020.test new file mode 100644 index 000000000..27b11c3e6 --- /dev/null +++ b/compiler/one-cmds/tests/one-quantize_neg_020.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +# check error message is printed when qconfig file is not json + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Failed to decode" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +inputfile="./inception_v3.circle" +outputfile="./inception_v3.quantized.neg_020.circle" + +rm -rf ${outputfile}.log + +# run test +one-quantize \ +--input_dtype float32 \ +--quant_config one-quantize_neg_020.test \ +--input_path ${inputfile} \ +--output_path ${outputfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_008.cfg b/compiler/one-cmds/tests/onecc_008.cfg index 0be026e6e..020e274e1 100644 --- a/compiler/one-cmds/tests/onecc_008.cfg +++ b/compiler/one-cmds/tests/onecc_008.cfg @@ -15,7 +15,6 @@ output_path=test_onnx_model.circle [one-optimize] input_path=test_onnx_model.circle output_path=test_onnx_model.opt.circle -all=True remove_redundant_transpose=True [one-codegen] diff --git a/compiler/one-cmds/tests/onecc_009.cfg b/compiler/one-cmds/tests/onecc_009.cfg index a17ae59cb..86121c557 100644 --- a/compiler/one-cmds/tests/onecc_009.cfg +++ b/compiler/one-cmds/tests/onecc_009.cfg @@ -15,7 +15,6 @@ output_path=onnx_conv2d_conv2d.circle [one-optimize] input_path=onnx_conv2d_conv2d.circle output_path=onnx_conv2d_conv2d.opt.circle -all=True remove_redundant_transpose=True convert_nchw_to_nhwc=True diff --git a/compiler/one-cmds/tests/onecc_024.cfg b/compiler/one-cmds/tests/onecc_024.cfg new file mode 100644 index 000000000..7b4b1a80a --- /dev/null +++ b/compiler/one-cmds/tests/onecc_024.cfg @@ -0,0 +1,22 @@ +[onecc] +one-import-tf=True +one-import-tflite=False +one-import-bcq=False +one-import-onnx=False +one-optimize=True +one-quantize=False +one-pack=False +one-codegen=False + +[one-import-tf] +input_path=inception_v3.pb +output_path=inception_v3.circle +input_arrays=input +input_shapes=1,299,299,3 +output_arrays=InceptionV3/Predictions/Reshape_1 +converter_version=v1 + +[one-optimize] +input_path=inception_v3.circle +output_path=inception_v3.opt.circle +make_batchnorm_gamma_positive=False diff --git a/compiler/one-cmds/tests/onecc_024.test b/compiler/one-cmds/tests/onecc_024.test new file mode 100644 index 000000000..1f5daa13e --- /dev/null +++ b/compiler/one-cmds/tests/onecc_024.test @@ -0,0 +1,77 @@ +#!/bin/bash + +# 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. + +# Use `OONECC_024` optimization option + +: ' +This test assumes below directories. + +[one hierarchy] + one + ├── backends + ├── bin + ├── doc + ├── include + ├── lib + ├── optimization + └── test # pwd +' + +OPT_ALREADY_EXIST=true + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +clean_envir() +{ + rm -rf ../optimization/OONECC_024.cfg + if [ "$OPT_ALREADY_EXIST" = false ]; then + rm -rf ../optimization + fi +} + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + clean_envir + exit 255 +} + +trap trap_err_onexit ERR + +configfile="onecc_024.cfg" +outputfile="inception_v3.opt.circle" + +rm -rf ${outputfile} + +if [ ! -d "../optimization" ]; then + mkdir -p ../optimization + OPT_ALREADY_EXIST=false +fi + +cp OONECC_024.cfg ../optimization + +# run test +LUCI_LOG=5 onecc -C ${configfile} -OONECC_024 > ${filename}.log 2>&1 + +clean_envir + +if grep -q "MakeBatchNormGammaPositivePass" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/onecc_025.cfg b/compiler/one-cmds/tests/onecc_025.cfg new file mode 100644 index 000000000..4776ea80e --- /dev/null +++ b/compiler/one-cmds/tests/onecc_025.cfg @@ -0,0 +1,20 @@ +[onecc] +one-import-tf=True +one-import-tflite=False +one-import-bcq=False +one-optimize=True +one-quantize=False +one-pack=False +one-codegen=False + +[one-import-tf] +input_path=inception_v3.pb +output_path=inception_v3.circle +input_arrays=input +input_shapes=1,299,299,3 +output_arrays=InceptionV3/Predictions/Reshape_1 +converter_version=v2 + +[one-optimize] +input_path=inception_v3.circle +output_path=inception_v3.opt.circle diff --git a/compiler/one-cmds/tests/onecc_025.test b/compiler/one-cmds/tests/onecc_025.test new file mode 100644 index 000000000..396f40cea --- /dev/null +++ b/compiler/one-cmds/tests/onecc_025.test @@ -0,0 +1,40 @@ +#!/bin/bash + +# Copyright (c) 2021 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. + +# one-import-tf -> one-optimize with the configuration file that includes `onecc` section + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +configfile="onecc_001.cfg" +outputfile="inception_v3.opt.circle" + +# run test +onecc -C ${configfile} > /dev/null 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_026.cfg b/compiler/one-cmds/tests/onecc_026.cfg new file mode 100644 index 000000000..c27a13654 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_026.cfg @@ -0,0 +1,16 @@ +[onecc] +one-import-tf=False +one-import-tflite=False +one-import-bcq=False +one-optimize=False +one-quantize=True +one-pack=False +one-codegen=False + +[one-quantize] +input_path=inception_v3.circle +output_path=inception_v3.onecc_026.q.circle +input_data=inception_v3_test_data.h5 +evaluate_result=True +test_data=inception_v3_test_data.h5 +print_mpeir=True diff --git a/compiler/one-cmds/tests/onecc_026.test b/compiler/one-cmds/tests/onecc_026.test new file mode 100644 index 000000000..84cfa4146 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_026.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# 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. + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +check_message() +{ + if grep -q "MPEIR for InceptionV3/Predictions/Reshape_1 is" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + trap_err_onexit +} + +trap trap_err_onexit ERR + +configfile="onecc_026.cfg" +outputfile="inception_v3.onecc_026.q.circle" + +rm -rf ${outputfile} + +# run test +onecc -C ${configfile} > ${filename}.log 2>&1 + +check_message diff --git a/compiler/one-cmds/tests/onecc_027.cfg b/compiler/one-cmds/tests/onecc_027.cfg new file mode 100644 index 000000000..d3f6b5e82 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_027.cfg @@ -0,0 +1,15 @@ +[onecc] +one-import-tf=False +one-import-tflite=False +one-import-bcq=False +one-import-onnx=False +one-optimize=False +one-quantize=False +one-pack=False +one-codegen=False +one-profile=False +one-infer=True + +[one-infer] +backend=dummy +command=test_onnx_model.bin diff --git a/compiler/one-cmds/tests/onecc_027.test b/compiler/one-cmds/tests/onecc_027.test new file mode 100644 index 000000000..e727359ef --- /dev/null +++ b/compiler/one-cmds/tests/onecc_027.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright (c) 2021 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. + +# one-infer + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-profile + exit 255 +} + +trap trap_err_onexit ERR + +configfile="onecc_027.cfg" + +# copy dummy-infer to bin folder +cp dummy-infer ../bin/dummy-infer + +# run test +onecc -C ${configfile} > ${filename}.log + +rm -rf ../bin/dummy-infer + +if grep -q "dummy-infer dummy output!!!" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 +fi + +trap_err_onexit diff --git a/compiler/one-cmds/tests/onecc_028.test b/compiler/one-cmds/tests/onecc_028.test new file mode 100644 index 000000000..10ce1583b --- /dev/null +++ b/compiler/one-cmds/tests/onecc_028.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf -> one-optimize -> one-pack + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_028.workflow.json" +outputfile="inception_v3_pkg" + +rm -rf ${outputfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_028.workflow.json b/compiler/one-cmds/tests/onecc_028.workflow.json new file mode 100644 index 000000000..84bfd01fa --- /dev/null +++ b/compiler/one-cmds/tests/onecc_028.workflow.json @@ -0,0 +1,37 @@ +{ + "workflows": [ + "MY_WORKFLOW" + ], + "MY_WORKFLOW": { + "steps": [ + "IMPORT_TF", + "OPTIMIZE", + "PACK" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "OPTIMIZE": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle" + } + }, + "PACK": { + "one-cmd": "one-pack", + "commands": { + "input_path": "inception_v3.opt.circle", + "output_path": "inception_v3_pkg" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_029.test b/compiler/one-cmds/tests/onecc_029.test new file mode 100644 index 000000000..9bab1a1ee --- /dev/null +++ b/compiler/one-cmds/tests/onecc_029.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf -> one-quantize + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_029.workflow.json" +outputfile="inception_v3.quantized.circle" + +rm -rf ${outputfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_029.workflow.json b/compiler/one-cmds/tests/onecc_029.workflow.json new file mode 100644 index 000000000..65c9ea662 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_029.workflow.json @@ -0,0 +1,30 @@ +{ + "workflows": [ + "QUANTIZE_WORKFLOW" + ], + "QUANTIZE_WORKFLOW": { + "steps": [ + "IMPORT_TF", + "QUANTIZE" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "QUANTIZE": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.quantized.circle", + "input_data": "inception_v3_test_data.h5" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_030.test b/compiler/one-cmds/tests/onecc_030.test new file mode 100644 index 000000000..c0aa56a51 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_030.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf -> one-codegen + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-compile + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_030.workflow.json" +outputfile="sample.tvn" + +rm -rf ${outputfile} + +# copy dummy-compile to bin folder +cp dummy-compile ../bin/dummy-compile + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +rm -rf ../bin/dummy-compile + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_030.workflow.json b/compiler/one-cmds/tests/onecc_030.workflow.json new file mode 100644 index 000000000..111a1b034 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_030.workflow.json @@ -0,0 +1,29 @@ +{ + "workflows": [ + "codegen_wf" + ], + "codegen_wf": { + "steps": [ + "import_tf", + "codegen" + ], + "import_tf": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "codegen": { + "one-cmd": "one-codegen", + "commands": { + "backend": "dummy", + "command": "-o sample.tvn inception_v3.circle" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_031.test b/compiler/one-cmds/tests/onecc_031.test new file mode 100644 index 000000000..7a1c670c8 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_031.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tflite -> one-optimize -> one-codgen + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-compile + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_031.workflow.json" +outputfile="sample.tvn" + +rm -rf ${outputfile} + +# copy dummy-compile to bin folder +cp dummy-compile ../bin/dummy-compile + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +rm -rf ../bin/dummy-compile + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_031.workflow.json b/compiler/one-cmds/tests/onecc_031.workflow.json new file mode 100644 index 000000000..83d52b942 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_031.workflow.json @@ -0,0 +1,33 @@ +{ + "workflows": [ + "wf" + ], + "wf": { + "steps": [ + "import", + "optimize", + "codegen" + ], + "import": { + "one-cmd": "one-import-tflite", + "commands": { + "input_path": "inception_v3.tflite", + "output_path": "inception_v3.circle" + } + }, + "optimize": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle" + } + }, + "codegen": { + "one-cmd": "one-codegen", + "commands": { + "backend": "dummy", + "command": "-o sample.tvn inception_v3.opt.circle" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_032.test b/compiler/one-cmds/tests/onecc_032.test new file mode 100644 index 000000000..89b6c41a5 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_032.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf -> one-optimize -> one-quantize -> one-codegen + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-compile + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_032.workflow.json" +outputfile="sample.tvn" + +rm -rf ${outputfile} + +# copy dummy-compile to bin folder +cp dummy-compile ../bin/dummy-compile + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +rm -rf ../bin/dummy-compile + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_032.workflow.json b/compiler/one-cmds/tests/onecc_032.workflow.json new file mode 100644 index 000000000..08d3f0f5c --- /dev/null +++ b/compiler/one-cmds/tests/onecc_032.workflow.json @@ -0,0 +1,42 @@ +{ + "workflows": [ + "wf" + ], + "wf": { + "steps": [ + "import", + "optimize", + "quantize", + "codegen" + ], + "import": { + "one-cmd": "one-import-tflite", + "commands": { + "input_path": "inception_v3.tflite", + "output_path": "inception_v3.circle" + } + }, + "optimize": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle" + } + }, + "quantize": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.quantized.circle", + "input_data": "inception_v3_test_data.h5" + } + }, + "codegen": { + "one-cmd": "one-codegen", + "commands": { + "backend": "dummy", + "command": "-o sample.tvn inception_v3.quantized.circle" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_033.test b/compiler/one-cmds/tests/onecc_033.test new file mode 100644 index 000000000..635582f61 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_033.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf -> one-optimize -> one-quantize -> one-pack + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_033.workflow.json" +outputfile="inception_v3_pkg" + +rm -rf ${outputfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_033.workflow.json b/compiler/one-cmds/tests/onecc_033.workflow.json new file mode 100644 index 000000000..01233ffd9 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_033.workflow.json @@ -0,0 +1,42 @@ +{ + "workflows": [ + "wf" + ], + "wf": { + "steps": [ + "import", + "optimize", + "quantize", + "pack" + ], + "import": { + "one-cmd": "one-import-tflite", + "commands": { + "input_path": "inception_v3.tflite", + "output_path": "inception_v3.circle" + } + }, + "optimize": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle" + } + }, + "quantize": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.quantized.circle", + "input_data": "inception_v3_test_data.h5" + } + }, + "pack": { + "one-cmd": "one-pack", + "commands": { + "input_path": "inception_v3.quantized.circle", + "output_path": "inception_v3_pkg" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_034.test b/compiler/one-cmds/tests/onecc_034.test new file mode 100644 index 000000000..e76654809 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_034.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-onnx -> one-optimize -> one-codegen + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + rm -rf ../bin/dummy-compile + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_034.workflow.json" +outputfile="onnx_conv2d_conv2d.bin" + +rm -rf ${outputfile} + +# copy dummy-compile to bin folder +cp dummy-compile ../bin/dummy-compile + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +rm -rf ../bin/dummy-compile + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_034.workflow.json b/compiler/one-cmds/tests/onecc_034.workflow.json new file mode 100644 index 000000000..bc3cbbf58 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_034.workflow.json @@ -0,0 +1,35 @@ +{ + "workflows": [ + "wf" + ], + "wf": { + "steps": [ + "import", + "optimize", + "codegen" + ], + "import": { + "one-cmd": "one-import-onnx", + "commands": { + "input_path": "onnx_conv2d_conv2d.onnx", + "output_path": "onnx_conv2d_conv2d.circle" + } + }, + "optimize": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "onnx_conv2d_conv2d.circle", + "output_path": "onnx_conv2d_conv2d.opt.circle", + "remove_redundant_transpose": "True", + "convert_nchw_to_nhwc": "True" + } + }, + "codegen": { + "one-cmd": "one-codegen", + "commands": { + "backend": "dummy", + "command": "-o onnx_conv2d_conv2d.bin onnx_conv2d_conv2d.opt.circle" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_035.test b/compiler/one-cmds/tests/onecc_035.test new file mode 100644 index 000000000..762cdd31a --- /dev/null +++ b/compiler/one-cmds/tests/onecc_035.test @@ -0,0 +1,47 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf generates intermediate files + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_035.workflow.json" +outputfile="inception_v3.alt.circle" +intermfile="inception_v3.alt.tflite" + +rm -rf ${outputfile} +rm -rf ${intermfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi +if [[ ! -s "${intermfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_035.workflow.json b/compiler/one-cmds/tests/onecc_035.workflow.json new file mode 100644 index 000000000..6abf1f32b --- /dev/null +++ b/compiler/one-cmds/tests/onecc_035.workflow.json @@ -0,0 +1,22 @@ +{ + "workflows": [ + "wf" + ], + "wf": { + "steps": [ + "import" + ], + "import": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.alt.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v1", + "save_intermediate": "True" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_036.test b/compiler/one-cmds/tests/onecc_036.test new file mode 100644 index 000000000..865255e9f --- /dev/null +++ b/compiler/one-cmds/tests/onecc_036.test @@ -0,0 +1,47 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-onnx generates intermediate files + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_036.workflow.json" +outputfile="test_onnx_model.circle" +intermfile="test_onnx_model.tflite" + +rm -rf ${outputfile} +rm -rf ${intermfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi +if [[ ! -s "${intermfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_036.workflow.json b/compiler/one-cmds/tests/onecc_036.workflow.json new file mode 100644 index 000000000..5fa29edb5 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_036.workflow.json @@ -0,0 +1,18 @@ +{ + "workflows": [ + "wf" + ], + "wf": { + "steps": [ + "import" + ], + "import": { + "one-cmd": "one-import-onnx", + "commands": { + "input_path": "test_onnx_model.onnx", + "output_path": "test_onnx_model.circle", + "save_intermediate": "True" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_037.test b/compiler/one-cmds/tests/onecc_037.test new file mode 100644 index 000000000..52ea9e4c7 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_037.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf -> one-optimize + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_037.workflow.json" +outputfile="inception_v3.opt.circle" + +rm -rf ${outputfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_037.workflow.json b/compiler/one-cmds/tests/onecc_037.workflow.json new file mode 100644 index 000000000..3317fb27a --- /dev/null +++ b/compiler/one-cmds/tests/onecc_037.workflow.json @@ -0,0 +1,29 @@ +{ + "workflows": [ + "SIMPLE_WORKFLOW" + ], + "SIMPLE_WORKFLOW": { + "steps": [ + "IMPORT", + "OPTIMIZE" + ], + "IMPORT": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "OPTIMIZE": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_038.test b/compiler/one-cmds/tests/onecc_038.test new file mode 100644 index 000000000..6b8f7cf64 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_038.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-import-tf -> one-quantize + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_038.workflow.json" +outputfile="inception_v3.list.quantized.circle" + +rm -rf ${outputfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_038.workflow.json b/compiler/one-cmds/tests/onecc_038.workflow.json new file mode 100644 index 000000000..5ac515d00 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_038.workflow.json @@ -0,0 +1,31 @@ +{ + "workflows": [ + "SIMPLE_WORKFLOW" + ], + "SIMPLE_WORKFLOW": { + "steps": [ + "IMPORT", + "QUANTIZE" + ], + "IMPORT": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "QUANTIZE": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.list.quantized.circle", + "input_data": "datalist.txt", + "input_data_format": "list" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_039.test b/compiler/one-cmds/tests/onecc_039.test new file mode 100644 index 000000000..7db9d901c --- /dev/null +++ b/compiler/one-cmds/tests/onecc_039.test @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +# run a workflow where one-quantize quantizes the model and evaluates the result + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +check_message() +{ + if grep -q "MPEIR for InceptionV3/Predictions/Reshape_1 is" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + trap_err_onexit +} + +trap trap_err_onexit ERR + +workflowfile="onecc_039.workflow.json" +outputfile="inception_v3.onecc_039.q.circle" + +rm -rf ${outputfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +check_message diff --git a/compiler/one-cmds/tests/onecc_039.workflow.json b/compiler/one-cmds/tests/onecc_039.workflow.json new file mode 100644 index 000000000..55ef56988 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_039.workflow.json @@ -0,0 +1,21 @@ +{ + "workflows": [ + "SIMPLE_WORKFLOW" + ], + "SIMPLE_WORKFLOW": { + "steps": [ + "QUANTIZE" + ], + "QUANTIZE": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.onecc_026.q.circle", + "input_data": "inception_v3_test_data.h5", + "evaluate_result": "True", + "test_data": "inception_v3_test_data.h5", + "print_mpeir": "True" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_040.cfg b/compiler/one-cmds/tests/onecc_040.cfg new file mode 100644 index 000000000..4776ea80e --- /dev/null +++ b/compiler/one-cmds/tests/onecc_040.cfg @@ -0,0 +1,20 @@ +[onecc] +one-import-tf=True +one-import-tflite=False +one-import-bcq=False +one-optimize=True +one-quantize=False +one-pack=False +one-codegen=False + +[one-import-tf] +input_path=inception_v3.pb +output_path=inception_v3.circle +input_arrays=input +input_shapes=1,299,299,3 +output_arrays=InceptionV3/Predictions/Reshape_1 +converter_version=v2 + +[one-optimize] +input_path=inception_v3.circle +output_path=inception_v3.opt.circle diff --git a/compiler/one-cmds/tests/onecc_040.test b/compiler/one-cmds/tests/onecc_040.test new file mode 100644 index 000000000..2f7567730 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_040.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# run a workflow with cfg reference + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_040.workflow.json" +outputfile="inception_v3.opt.circle" + +rm -rf ${outputfile} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +if [[ ! -s "${outputfile}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_040.workflow.json b/compiler/one-cmds/tests/onecc_040.workflow.json new file mode 100644 index 000000000..2d4119b21 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_040.workflow.json @@ -0,0 +1,10 @@ +{ + "workflows": [ + "MY_WORKFLOW" + ], + "MY_WORKFLOW": { + "cfg-reference": { + "path": "onecc_040.cfg" + } + } +} diff --git a/compiler/one-cmds/tests/onecc_041.cfg b/compiler/one-cmds/tests/onecc_041.cfg new file mode 100644 index 000000000..16135f074 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_041.cfg @@ -0,0 +1,16 @@ +[onecc] +one-import-tf=True +one-import-tflite=False +one-import-bcq=False +one-optimize=False +one-quantize=False +one-pack=False +one-codegen=False + +[one-import-tf] +input_path=inception_v3.pb +output_path=inception_v3_without_opt.circle +input_arrays=input +input_shapes=1,299,299,3 +output_arrays=InceptionV3/Predictions/Reshape_1 +converter_version=v2 diff --git a/compiler/one-cmds/tests/onecc_041.test b/compiler/one-cmds/tests/onecc_041.test new file mode 100644 index 000000000..791dd12ca --- /dev/null +++ b/compiler/one-cmds/tests/onecc_041.test @@ -0,0 +1,58 @@ +#!/bin/bash + +# 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. + +# run a workflows + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +check_message() +{ + if grep -q "Do inference of inception_v3_without_opt\.circle" "${filename}.log" && + grep -q "Do inference of inception_v3\.opt\.circle" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + trap_err_onexit +} + +trap trap_err_onexit ERR + +workflowfile="onecc_041.workflow.json" +outputfile1="inception_v3_without_opt.circle" +outputfile2="inception_v3.opt.circle" + +cp dummy-inferV2 ../bin/dummy-inferV2 + +rm -rf ${outputfile1} {outputfile2} + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +rm -rf ../bin/dummy-inferV2 + +if [[ ! -s "${outputfile1}" ]] && [[ ! -s "${outputfile2}" ]]; then + trap_err_onexit +fi + +check_message diff --git a/compiler/one-cmds/tests/onecc_041.workflow.json b/compiler/one-cmds/tests/onecc_041.workflow.json new file mode 100644 index 000000000..7dfc1c664 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_041.workflow.json @@ -0,0 +1,61 @@ +{ + "workflows": [ + "WITHOUT_OPT", + "WITH_OPT", + "INFER" + ], + "INFER": { + "run-after": [ + "WITHOUT_OPT", + "WITH_OPT" + ], + "steps": [ + "INFER1", + "INFER2" + ], + "INFER1": { + "one-cmd": "one-infer", + "commands" : { + "driver": "dummy-inferV2", + "command": "inception_v3_without_opt.circle" + } + }, + "INFER2": { + "one-cmd": "one-infer", + "commands": { + "driver": "dummy-inferV2", + "command": "inception_v3.opt.circle" + } + } + }, + "WITHOUT_OPT": { + "cfg-reference": { + "path": "onecc_041.cfg" + } + }, + "WITH_OPT": { + "steps": [ + "IMPORT_TF", + "OPTIMIZE" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "OPTIMIZE": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle" + } + } + } + +} diff --git a/compiler/one-cmds/tests/onecc_neg_009.test b/compiler/one-cmds/tests/onecc_neg_009.test new file mode 100644 index 000000000..54dd129e4 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_009.test @@ -0,0 +1,69 @@ +#!/bin/bash + +# 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. + +# Valid optimization option but invalid configuration file path + +: ' +This test assumes below directories. + +[one hierarchy] + one + ├── backends + ├── bin + ├── doc + ├── include + ├── lib + ├── optimization + └── test # pwd +' + +OPT_ALREADY_EXIST=true + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + rm -rf ../optimization/OONECC_NEG_009.cfg + if [ "$OPT_ALREADY_EXIST" = false ]; then + rm -rf ../optimization + fi + if grep -q "Not found given configuration file" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +if [ ! -d "../optimization" ]; then + mkdir -p ../optimization + OPT_ALREADY_EXIST=false +fi + + +touch ../optimization/OONECC_NEG_009.cfg + +configfile=".." + +# run test +onecc -C ${configfile} -OONECC_NEG_009 > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_010.test b/compiler/one-cmds/tests/onecc_neg_010.test new file mode 100644 index 000000000..ddad5e6de --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_010.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# Invalid optimization option + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Invalid optimization option" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +configfile=".." + +# run test +onecc -C ${configfile} -OONECC_NEG_010 > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_011.cfg b/compiler/one-cmds/tests/onecc_neg_011.cfg new file mode 100644 index 000000000..b5873245b --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_011.cfg @@ -0,0 +1,13 @@ +[onecc] +one-import-tf=False +one-import-tflite=False +one-import-bcq=False +one-optimize=True +one-quantize=False +one-pack=False +one-codegen=False + +[one-optimize] +input_path=inception_v3.circle +output_path=inception_v3.opt.circle +wrong_opt=True diff --git a/compiler/one-cmds/tests/onecc_neg_011.test b/compiler/one-cmds/tests/onecc_neg_011.test new file mode 100644 index 000000000..3f043a77e --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_011.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# generate error for unrecognized opitmization option + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "following arguments are unrecognized" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +configfile="onecc_neg_011.cfg" + +# run test +onecc -C ${configfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_012.cfg b/compiler/one-cmds/tests/onecc_neg_012.cfg new file mode 100644 index 000000000..fdc73ef43 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_012.cfg @@ -0,0 +1,15 @@ +[onecc] +one-import-tf=False +one-import-tflite=False +one-import-bcq=False +one-optimize=False +one-quantize=False +one-pack=False +one-codegen=False +one-profile=False +one-infer=True + +[one-infer] +driver=dummy-infer +backend=dummy +command="dummy arguments" diff --git a/compiler/one-cmds/tests/onecc_neg_012.test b/compiler/one-cmds/tests/onecc_neg_012.test new file mode 100644 index 000000000..9feca5f54 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_012.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# Check driver and backend option is mutually exclusive + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "\-d and -b options are mutually exclusive" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +configfile="onecc_neg_012.cfg" + +# run test +onecc -C ${configfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_013.test b/compiler/one-cmds/tests/onecc_neg_013.test new file mode 100644 index 000000000..0dd8a0fdd --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_013.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# negative usage with missing workflow file + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Not found given workflow file" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_013.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_014.test b/compiler/one-cmds/tests/onecc_neg_014.test new file mode 100644 index 000000000..2ed5dcbf5 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_014.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# invalid workflow file + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Invalid workflow file" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_014.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_014.workflow.json b/compiler/one-cmds/tests/onecc_neg_014.workflow.json new file mode 100644 index 000000000..8d4fd431e --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_014.workflow.json @@ -0,0 +1,3 @@ +{ + INVALID JSON FILE +} diff --git a/compiler/one-cmds/tests/onecc_neg_015.test b/compiler/one-cmds/tests/onecc_neg_015.test new file mode 100644 index 000000000..079ba677a --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_015.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# workflow file has invalid key + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Not found" "${filename}.log" && + grep -q "key in workflow file" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_015.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_015.workflow.json b/compiler/one-cmds/tests/onecc_neg_015.workflow.json new file mode 100644 index 000000000..4cb752e4e --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_015.workflow.json @@ -0,0 +1,21 @@ +{ + "workflowsssssss": [ + "SIMPLE_WORKFLOW" + ], + "SIMPLE_WORKFLOW": { + "steps": [ + "QUANTIZE" + ], + "QUANTIZE": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.onecc_026.q.circle", + "input_data": "inception_v3_test_data.h5", + "evaluate_result": "True", + "test_data": "inception_v3_test_data.h5", + "print_mpeir": "True" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_016.test b/compiler/one-cmds/tests/onecc_neg_016.test new file mode 100644 index 000000000..c52763f47 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_016.test @@ -0,0 +1,42 @@ +#!/bin/bash + +# 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. + +# workflow file has invalid key + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Not found" "${filename}.log" && + grep -q "key listed in" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_016.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_016.workflow.json b/compiler/one-cmds/tests/onecc_neg_016.workflow.json new file mode 100644 index 000000000..c929cf38c --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_016.workflow.json @@ -0,0 +1,21 @@ +{ + "workflows": [ + "SIMPLE_WORKFLOW" + ], + "SIMPLE_WORKFLOWWWWW": { + "steps": [ + "QUANTIZE" + ], + "QUANTIZE": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.onecc_026.q.circle", + "input_data": "inception_v3_test_data.h5", + "evaluate_result": "True", + "test_data": "inception_v3_test_data.h5", + "print_mpeir": "True" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_017.test b/compiler/one-cmds/tests/onecc_neg_017.test new file mode 100644 index 000000000..2f173d2f6 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_017.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# workflow file has invalid key + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Each workflow should have either" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_017.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_017.workflow.json b/compiler/one-cmds/tests/onecc_neg_017.workflow.json new file mode 100644 index 000000000..22f1415e9 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_017.workflow.json @@ -0,0 +1,18 @@ +{ + "workflows": [ + "SIMPLE_WORKFLOW" + ], + "SIMPLE_WORKFLOW": { + "QUANTIZE": { + "one-cmd": "one-quantize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.onecc_026.q.circle", + "input_data": "inception_v3_test_data.h5", + "evaluate_result": "True", + "test_data": "inception_v3_test_data.h5", + "print_mpeir": "True" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_018.test b/compiler/one-cmds/tests/onecc_neg_018.test new file mode 100644 index 000000000..bc2297ed0 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_018.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# workflow file has invalid key + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "are exclusive key" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_018.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_018.workflow.json b/compiler/one-cmds/tests/onecc_neg_018.workflow.json new file mode 100644 index 000000000..58cb88e17 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_018.workflow.json @@ -0,0 +1,24 @@ +{ + "workflows": [ + "MY_WORKFLOW" + ], + "MY_WORKFLOW": { + "steps": [ + "IMPORT_TF" + ], + "cfg-reference": { + "path": "/path/to/ini/format/file" + }, + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_019.test b/compiler/one-cmds/tests/onecc_neg_019.test new file mode 100644 index 000000000..11ef3a9ee --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_019.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# workflow file has invalid key + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Each step should have" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_019.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_019.workflow.json b/compiler/one-cmds/tests/onecc_neg_019.workflow.json new file mode 100644 index 000000000..aedeeecca --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_019.workflow.json @@ -0,0 +1,21 @@ +{ + "workflows": [ + "MY_WORKFLOW" + ], + "MY_WORKFLOW": { + "steps": [ + "IMPORT_TF" + ], + "IMPORT_TF": { + "one-cmddddddddd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_020.test b/compiler/one-cmds/tests/onecc_neg_020.test new file mode 100644 index 000000000..7f5073d82 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_020.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# workflow file has invalid key + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Each step should have" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_020.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_020.workflow.json b/compiler/one-cmds/tests/onecc_neg_020.workflow.json new file mode 100644 index 000000000..d3446d38f --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_020.workflow.json @@ -0,0 +1,21 @@ +{ + "workflows": [ + "MY_WORKFLOW" + ], + "MY_WORKFLOW": { + "steps": [ + "IMPORT_TF" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commandssssssssss": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_021.test b/compiler/one-cmds/tests/onecc_neg_021.test new file mode 100644 index 000000000..e9d4baaee --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_021.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# workflows have a cycle + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Workflows should not have a cycle" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_021.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_021.workflow.json b/compiler/one-cmds/tests/onecc_neg_021.workflow.json new file mode 100644 index 000000000..6d21111af --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_021.workflow.json @@ -0,0 +1,44 @@ +{ + "workflows": [ + "CYCLE_WF1", + "CYCLE_WF2" + ], + "CYCLE_WF1": { + "run-after": [ + "CYCLE_WF2" + ], + "steps": [ + "IMPORT_TF" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + } + }, + "CYCLE_WF2": { + "run-after": [ + "CYCLE_WF1" + ], + "steps": [ + "IMPORT_TF" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_022.cfg b/compiler/one-cmds/tests/onecc_neg_022.cfg new file mode 100644 index 000000000..16135f074 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_022.cfg @@ -0,0 +1,16 @@ +[onecc] +one-import-tf=True +one-import-tflite=False +one-import-bcq=False +one-optimize=False +one-quantize=False +one-pack=False +one-codegen=False + +[one-import-tf] +input_path=inception_v3.pb +output_path=inception_v3_without_opt.circle +input_arrays=input +input_shapes=1,299,299,3 +output_arrays=InceptionV3/Predictions/Reshape_1 +converter_version=v2 diff --git a/compiler/one-cmds/tests/onecc_neg_022.test b/compiler/one-cmds/tests/onecc_neg_022.test new file mode 100644 index 000000000..540071729 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_022.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# workflows have a cycle + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Workflows should not have a cycle" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_022.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_022.workflow.json b/compiler/one-cmds/tests/onecc_neg_022.workflow.json new file mode 100644 index 000000000..2e056acf1 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_022.workflow.json @@ -0,0 +1,63 @@ +{ + "workflows": [ + "WITHOUT_OPT", + "WITH_OPT", + "INFER" + ], + "INFER": { + "run-after": [ + "WITHOUT_OPT", + "WITH_OPT" + ], + "steps": [ + "INFER1", + "INFER2" + ], + "INFER1": { + "one-cmd": "one-infer", + "commands" : { + "driver": "dummy-inferV2", + "command": "inception_v3_without_opt.circle" + } + }, + "INFER2": { + "one-cmd": "one-infer", + "commands": { + "driver": "dummy-inferV2", + "command": "inception_v3.opt.circle" + } + } + }, + "WITHOUT_OPT": { + "cfg-reference": { + "path": "onecc_041.cfg" + } + }, + "WITH_OPT": { + "run-after": [ + "WITHOUT_OPT" + ], + "steps": [ + "IMPORT_TF", + "OPTIMIZE" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "OPTIMIZE": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle" + } + } + } +} diff --git a/compiler/one-cmds/tests/onecc_neg_023.test b/compiler/one-cmds/tests/onecc_neg_023.test new file mode 100644 index 000000000..09717e8ad --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_023.test @@ -0,0 +1,41 @@ +#!/bin/bash + +# 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. + +# workflows have wrong optimize option + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + if grep -q "Change outputs failed" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +workflowfile="onecc_neg_023.workflow.json" + +# run test +onecc -W ${workflowfile} > ${filename}.log 2>&1 + +echo "${filename_ext} FAILED" +exit 255 diff --git a/compiler/one-cmds/tests/onecc_neg_023.workflow.json b/compiler/one-cmds/tests/onecc_neg_023.workflow.json new file mode 100644 index 000000000..056e704fd --- /dev/null +++ b/compiler/one-cmds/tests/onecc_neg_023.workflow.json @@ -0,0 +1,30 @@ +{ + "workflows": [ + "WITH_OPT" + ], + "WITH_OPT": { + "steps": [ + "IMPORT_TF", + "OPTIMIZE" + ], + "IMPORT_TF": { + "one-cmd": "one-import-tf", + "commands": { + "input_path": "inception_v3.pb", + "output_path": "inception_v3.circle", + "input_arrays": "input", + "input_shapes": "1,299,299,3", + "output_arrays": "InceptionV3/Predictions/Reshape_1", + "converter_version": "v2" + } + }, + "OPTIMIZE": { + "one-cmd": "one-optimize", + "commands": { + "input_path": "inception_v3.circle", + "output_path": "inception_v3.opt.circle", + "change_outputs": "non_existing_node_name" + } + } + } +} diff --git a/compiler/one-cmds/tests/prepare_test_materials.sh b/compiler/one-cmds/tests/prepare_test_materials.sh index c80c59834..c171cfe01 100644 --- a/compiler/one-cmds/tests/prepare_test_materials.sh +++ b/compiler/one-cmds/tests/prepare_test_materials.sh @@ -91,6 +91,20 @@ if [[ ! -s "onnx_conv2d_conv2d.onnx" ]]; then # https://github.com/Samsung/ONE/issues/5577#issuecomment-755078444 fi +if [[ ! -s "reshape_matmul.onnx" ]]; then + rm -rf reshape_matmul.zip + wget https://github.com/Samsung/ONE/files/9082878/reshape_matmul.zip + unzip reshape_matmul.zip + # https://github.com/Samsung/ONE/issues/9405#issuecomment-1180198137 +fi + +if [[ ! -s "Net_InstanceNorm_003.part" ]]; then + rm -rf Net_InstanceNorm_003.zip + wget https://github.com/Samsung/ONE/files/8608844/Net_InstanceNorm_003.zip + unzip Net_InstanceNorm_003.zip + # https://github.com/Samsung/ONE/issues/8570#issuecomment-1115804257 +fi + function files_missing() { condition="test " diff --git a/compiler/one-cmds/utils.py b/compiler/one-cmds/utils.py index be0322aca..d204447fd 100644 --- a/compiler/one-cmds/utils.py +++ b/compiler/one-cmds/utils.py @@ -47,6 +47,25 @@ def _add_default_arg(parser): parser.add_argument('-S', '--section', type=str, help=argparse.SUPPRESS) +def _add_default_arg_no_CS(parser): + """ + This adds -v -V args only (no -C nor -S) + """ + # version + parser.add_argument( + '-v', + '--version', + action='store_true', + help='show program\'s version number and exit') + + # verbose + parser.add_argument( + '-V', + '--verbose', + action='store_true', + help='output additional information to stdout or stderr') + + def is_accumulated_arg(arg, driver): if driver == "one-quantize": accumulables = [ @@ -62,6 +81,43 @@ def _is_valid_attr(args, attr): return hasattr(args, attr) and getattr(args, attr) +class Command: + def __init__(self, driver, args, log_file): + self.cmd = [driver] + self.driver = driver + self.args = args + self.log_file = log_file + + # Add option if attrs are valid + # Option values are collected from self.args + def add_option_with_valid_args(self, option, attrs): + for attr in attrs: + if not _is_valid_attr(self.args, attr): + return self + self.cmd.append(option) + for attr in attrs: + self.cmd.append(getattr(self.args, attr)) + return self + + # Add option and values without any condition + def add_option_with_values(self, option, values): + self.cmd.append(option) + for value in values: + self.cmd.append(value) + return self + + # Add option with no argument (ex: --verbose) if attr is valid + def add_noarg_option_if_valid_arg(self, option, attr): + if _is_valid_attr(self.args, attr): + self.cmd.append(option) + return self + + # Run cmd and save logs + def run(self): + self.log_file.write((' '.join(self.cmd) + '\n').encode()) + _run(self.cmd, err_prefix=self.driver, logfile=self.log_file) + + def _parse_cfg_and_overwrite(config_path, section, args): """ parse given section of configuration file and set the values of args. @@ -153,8 +209,7 @@ def _run(cmd, err_prefix=None, logfile=None): err_prefix: prefix to be put before every stderr lines logfile: file stream to which both of stdout and stderr lines will be written """ - with subprocess.Popen( - cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1) as p: + with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p: import select inputs = set([p.stdout, p.stderr]) while inputs: |