diff --git a/compiler/circle-resizer-dredd-recipe-test/CMakeLists.txt b/compiler/circle-resizer-dredd-recipe-test/CMakeLists.txt new file mode 100644 index 00000000000..cd80070cc13 --- /dev/null +++ b/compiler/circle-resizer-dredd-recipe-test/CMakeLists.txt @@ -0,0 +1,117 @@ +if(NOT ENABLE_TEST) + return() +endif(NOT ENABLE_TEST) + +nnas_include(TargetRequire) + +unset(REQUIRED_TARGETS) +list(APPEND REQUIRED_TARGETS circle-inspect) +list(APPEND REQUIRED_TARGETS circle-verify) +list(APPEND REQUIRED_TARGETS circle_resizer) +list(APPEND REQUIRED_TARGETS dredd_rule_lib) +TargetRequire_Return(${REQUIRED_TARGETS}) + +unset(TEST_DEPS) +unset(TEST_NAMES) + +get_target_property(ARTIFACTS_BIN_PATH testDataGenerator BINARY_DIR) + +set(oneValueArgs NEW_INPUTS_SIZES) +set(multiValueArgs "") + +macro(Add RECIPE) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(NEW_INPUTS_SIZES "") + if(ARG_NEW_INPUTS_SIZES) + set(NEW_INPUTS_SIZES "--input_shapes" "${ARG_NEW_INPUTS_SIZES}") + endif() + + set(CIRCLE_PATH "${ARTIFACTS_BIN_PATH}/${RECIPE}.circle") + set(RESIZED_CIRCLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${RECIPE}.resized.circle") + + # Generate resized .circle + add_custom_command(OUTPUT ${RESIZED_CIRCLE_PATH} + COMMAND $ --input_path ${CIRCLE_PATH} --output_path ${RESIZED_CIRCLE_PATH} ${NEW_INPUTS_SIZES} + DEPENDS + circle_resizer + ${CIRCLE_PATH} + COMMENT "Generate ${RECIPE}.resized.circle" + ) + + list(APPEND TEST_DEPS ${RESIZED_CIRCLE_PATH}) + list(APPEND TEST_NAMES ${RECIPE}) +endmacro(Add) + + +# Read "test.lst" +include("test.lst") + +## +## Copy testall +## +set(TEST_RUNNER "${CMAKE_CURRENT_BINARY_DIR}/testall.sh") +set(TEST_RUNNER_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/testall.sh") + +add_custom_command( + OUTPUT ${TEST_RUNNER} + COMMAND ${CMAKE_COMMAND} -E copy "${TEST_RUNNER_SOURCE}" "${TEST_RUNNER}" + DEPENDS ${TEST_RUNNER_SOURCE} + COMMENT "Generate test runner" +) + +list(APPEND TEST_DEPS "${TEST_RUNNER}") + +### +### Generate test.config +### +set(TEST_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/test.config") + +add_custom_command( + OUTPUT ${TEST_CONFIG} + COMMAND ${CMAKE_COMMAND} -E remove -f ${TEST_CONFIG} + COMMAND ${CMAKE_COMMAND} -E echo 'CIRCLE_INSPECT_PATH=\"$\"' >> ${TEST_CONFIG} + COMMAND ${CMAKE_COMMAND} -E echo 'CIRCLE_VERIFY_PATH=\"$\"' >> ${TEST_CONFIG} + COMMAND ${CMAKE_COMMAND} -E echo 'CIRCLE_RESIZER_PATH=\"$\"' >> ${TEST_CONFIG} + DEPENDS + circle-inspect + circle-verify + circle_resizer + COMMENT "Generate test configuration" +) + +list(APPEND TEST_DEPS "${TEST_CONFIG}") + +# +# copy rule-lib.sh (a library of shell script functions) +# + +# getting path for rule-lib.sh in dredd-rule-lib +get_target_property(DREDD_RULE_LIB_DIR dredd_rule_lib BINARY_DIR) + +set(RULE_LIB_SOURCE_PATH "${DREDD_RULE_LIB_DIR}/rule-lib.sh") +set(RULE_LIB_BINARY_PATH "${CMAKE_CURRENT_BINARY_DIR}/rule-lib.sh") + +add_custom_command( + OUTPUT ${RULE_LIB_BINARY_PATH} + COMMAND ${CMAKE_COMMAND} -E copy "${RULE_LIB_SOURCE_PATH}" "${RULE_LIB_BINARY_PATH}" + DEPENDS ${RULE_LIB_SOURCE_PATH} + COMMENT "Generate rule lib" +) + +list(APPEND TEST_DEPS "${RULE_LIB_BINARY_PATH}") + +# Generate dependencies +add_custom_target(circle-resizer_dredd_recipe_test ALL DEPENDS ${TEST_DEPS}) +add_dependencies(circle-resizer_dredd_recipe_test common_artifacts_deps) + +get_target_property(ARTIFACTS_BIN_PATH testDataGenerator BINARY_DIR) + +# Run tests +add_test( + NAME resizer_dredd_recipe_test + COMMAND "${TEST_RUNNER}" + "${TEST_CONFIG}" + "${ARTIFACTS_BIN_PATH}" + ${TEST_NAMES} +) diff --git a/compiler/circle-resizer-dredd-recipe-test/README.md b/compiler/circle-resizer-dredd-recipe-test/README.md new file mode 100644 index 00000000000..ea65d7319ee --- /dev/null +++ b/compiler/circle-resizer-dredd-recipe-test/README.md @@ -0,0 +1,31 @@ +# circle-resizer-dredd-recipe-test + +It tests non-functional conditions of a circle model resized by circle-resizer. + +## How to add a test? + +1. Create a directory under `res/TensorFlowLiteRecipes/` or `res/CircleRecipes/`. + +2. Make a recipe (`test.recipe`) for a model under the directory. + +3. Make a rule (`test.rule`) you want to test under the directory. Note, that you can find more information about dredd-test-rules in _dredd-rule-lib_ module. + +4. Add a test to `test.lst` in this module using `Add` macro. + ``` + Add(RECIPE_DIR NEW_INPUTS_SIZES) + ``` + - `NEW_INPUTS_SIZES`: New shapes of Circle model inputs in comma-separated format like `[1,2,3],[4,5]` for a model with 2 inputs. + +## Example + +``` +# TensorFlowLiteRecipes +res/TensorFlowLiteRecipes/PRelu_000 +├── test.recipe # What you want to test +└── test.rule # Non-functional conditions to be satisfied + +# test.lst +... +Add(PRelu_000 NEW_INPUTS_SIZES [1,4,4,5],[1,1,5]) +... +``` diff --git a/compiler/circle-resizer-dredd-recipe-test/requires.cmake b/compiler/circle-resizer-dredd-recipe-test/requires.cmake new file mode 100644 index 00000000000..d5e55f70dc6 --- /dev/null +++ b/compiler/circle-resizer-dredd-recipe-test/requires.cmake @@ -0,0 +1,5 @@ +require("circle-inspect") +require("circle-resizer") +require("circle-verify") +require("common-artifacts") +require("dredd-rule-lib") diff --git a/compiler/circle-resizer-dredd-recipe-test/test.lst b/compiler/circle-resizer-dredd-recipe-test/test.lst new file mode 100644 index 00000000000..3326ce0993c --- /dev/null +++ b/compiler/circle-resizer-dredd-recipe-test/test.lst @@ -0,0 +1,19 @@ +## EXAMPLE +# +# Add(RECIPE_DIR NEW_INPUTS_SIZES [1,2,3]) +# + +## TFLITE RECIPE + +# two inputs, one output +Add(PRelu_002 NEW_INPUTS_SIZES [1,4,4,5],[1,1,5]) +# scalar output +Add(ReduceAny_dynamic_004 NEW_INPUTS_SIZES [4,5,6]) +# change rank +Add(GreaterEqual_001 NEW_INPUTS_SIZES [1,2,3],[1,2,3]) +# one inputs, two outputs +Add(Split_001 NEW_INPUTS_SIZES [8,1,2]) +# bigger graph +Add(Net_FullyConnected_Gelu_001 NEW_INPUTS_SIZES [2,16]) +# from dynamic to static +Add(Inf_StridedSlice_002 NEW_INPUTS_SIZES [1,10,10,5]) diff --git a/compiler/circle-resizer-dredd-recipe-test/testall.sh b/compiler/circle-resizer-dredd-recipe-test/testall.sh new file mode 100755 index 00000000000..18f47137c13 --- /dev/null +++ b/compiler/circle-resizer-dredd-recipe-test/testall.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +# Need at least 2 arguments +if [[ $# -lt 2 ]]; then + echo "USAGE: $0 ..." + echo + echo "ARGUMENTS:" + echo " [test.config path]" + echo " [WORKDIR]" + echo " [Prefix1]" + echo " [Prefix2]" + echo " ..." + exit 255 +fi + +WORKDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +CONFIG_PATH="$1"; shift +RESOURCE_DIR="$1"; shift + +source "${CONFIG_PATH}" + +echo "-- Found circle-resizer: ${CIRCLE_RESIZER_PATH}" +echo "-- Found circle-inspect: ${CIRCLE_INSPECT_PATH}" +echo "-- Found circle-verify: ${CIRCLE_VERIFY_PATH}" +echo "-- Found common-artifacts: ${RESOURCE_DIR}" + +TESTED=() +PASSED=() +FAILED=() + +pushd ${WORKDIR} +while [[ $# -ne 0 ]]; do + PREFIX="$1"; shift + + TESTED+=("${PREFIX}") + + PASSED_TAG="${PREFIX}.passed" + + rm -f "${PASSED_TAG}" + + cat > "${PREFIX}.log" <( + exec 2>&1 + + echo "-- Found circle: ${PREFIX}.resized.circle" + + # Exit immediately if any command fails + set -e + # Show commands + set -x + + # + # Check if rule is satisfied + # + + # Note: turn off 'command printing'. Otherwise printing will be so messy + set +x + + # (COMPILED_FILE, INSPECT_PROG_PATH, VERIFY_PROG_PATH, ERROR_LOG) must be set for rule-lib.sh + COMPILED_FILE="${PREFIX}.resized.circle" + INSPECT_PROG_PATH=${CIRCLE_INSPECT_PATH} + VERIFY_PROG_PATH=${CIRCLE_VERIFY_PATH} + ERROR_LOG="${PREFIX}.error" + + rm -f "${ERROR_LOG}" + + # in case error while running rule-lib.sh, prints error msg + trap 'echo "** ERROR **" ; cat "${ERROR_LOG}"' ERR + + source rule-lib.sh + source "${RESOURCE_DIR}/${PREFIX}.rule" + + # unset + trap - ERR + set -x + + # At this point, the exit code of all commands is 0 + # If not 0, execution of this script ends because of "set -e" + touch "${PASSED_TAG}" + ) + + if [[ -f "${PASSED_TAG}" ]]; then + PASSED+=("$PREFIX") + else + FAILED+=("$PREFIX") + fi +done +popd + +if [[ ${#TESTED[@]} -ne ${#PASSED[@]} ]]; then + echo "FAILED" + for TEST in "${FAILED[@]}" + do + echo "- ${TEST}" + done + exit 255 +fi + +echo "PASSED" +exit 0 diff --git a/compiler/circle-resizer/CMakeLists.txt b/compiler/circle-resizer/CMakeLists.txt index df1a6e31ce2..4e6b23a2c6d 100644 --- a/compiler/circle-resizer/CMakeLists.txt +++ b/compiler/circle-resizer/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(src) add_subdirectory(app) +add_subdirectory(python) add_subdirectory(tests) diff --git a/compiler/circle-resizer/python/CMakeLists.txt b/compiler/circle-resizer/python/CMakeLists.txt new file mode 100644 index 00000000000..171a304781d --- /dev/null +++ b/compiler/circle-resizer/python/CMakeLists.txt @@ -0,0 +1,61 @@ +# NOTE find_package will try to use at least python3.8 as follows depending on platform version +# Ubuntu18.04; explictly installed python3.8 (default is python3.6) +# Ubuntu20.04; default python3.8 +# Ubuntu22.04; default python3.10 +# Ubuntu24.04; explictly installed python3.8 (default is python3.12) +# refer https://github.com/Samsung/ONE/issues/9962 +if(CMAKE_VERSION VERSION_LESS 3.12) + find_package(PythonInterp 3.8 QUIET) + find_package(PythonLibs 3.8 QUIET) + + if(NOT ${PYTHONINTERP_FOUND}) + message(STATUS "Build circle-resizer: FAILED (Python3 is missing)") + return() + endif() + + if(${PYTHON_VERSION_MINOR} LESS 8) + message(STATUS "Build circle-resizer: FAILED (Install Python version higher than or equal to 3.8)") + return() + endif() +else() + find_package(Python 3.8 EXACT COMPONENTS Development QUIET) + if(NOT Python_FOUND) + find_package(Python 3.8 COMPONENTS Development QUIET) + endif() + + # Require same python version of common-artifacts + if(Python_VERSION VERSION_GREATER_EQUAL 3.12) + message(STATUS "Build dalgona: FALSE (Python version 3.12 or higher is not supported yet)") + return() + endif() + if(Python_VERSION VERSION_LESS 3.8) + message(STATUS "Build dalgona: FAILED (Install Python version 3.8 or 3.10)") + return() + endif() + + if(NOT Python_Development_FOUND) + message(STATUS "Build dalgona: FAILED (Python3 development package is missing)") + return() + endif() + + set(PYTHON_INCLUDE_DIRS ${Python_INCLUDE_DIRS}) + set(PYTHON_LIBRARIES ${Python_LIBRARIES}) +endif() + +nnas_find_package(Pybind11) +if(NOT Pybind11_FOUND) + message(STATUS "circle-resizer: FAILED (Pybind11 is missing)") + return() +endif() + +add_library(circle_resizer_python_api SHARED src/CircleResizerBindings.cpp) +target_link_libraries(circle_resizer_python_api PRIVATE circle_resizer_core) + +set_target_properties(circle_resizer_python_api PROPERTIES CXX_VISIBILITY_PRESET "hidden" + CUDA_VISIBILITY_PRESET "hidden") +set_target_properties(circle_resizer_python_api PROPERTIES PREFIX "") + +target_include_directories(circle_resizer_python_api PRIVATE ${PYTHON_INCLUDE_DIRS}) +target_include_directories(circle_resizer_python_api PRIVATE ${Pybind11_INCLUDE_DIRS}) + +install(TARGETS circle_resizer_python_api DESTINATION lib) diff --git a/compiler/circle-resizer/python/circle_resizer/__init__.py b/compiler/circle-resizer/python/circle_resizer/__init__.py new file mode 100644 index 00000000000..1ca0e4ab5ff --- /dev/null +++ b/compiler/circle-resizer/python/circle_resizer/__init__.py @@ -0,0 +1,4 @@ +from circle_resizer.circle_resizer_python_api import Dim +from circle_resizer.circle_resizer_python_api import Shape +from circle_resizer.circle_resizer_python_api import CircleModel +from circle_resizer.circle_resizer_python_api import ModelEditor diff --git a/compiler/circle-resizer/python/setup.py b/compiler/circle-resizer/python/setup.py new file mode 100644 index 00000000000..8235c128c17 --- /dev/null +++ b/compiler/circle-resizer/python/setup.py @@ -0,0 +1,45 @@ +from setuptools import setup, find_packages +import os +import pathlib +import shutil + +install_dir = os.environ.get("CMAKE_INSTALL_PREFIX") +if install_dir is None: + print( + 'You have to set CMAKE_INSTALL_PREFIX env variable with value passed to nncc cmake as install dir' + ) + exit(-1) + +lib_dir = pathlib.Path(f'{install_dir}/lib') +resizer_dependent_so_libs = [ + 'libluci_export.so', + 'libluci_import.so', + 'libluci_pass.so', + 'libluci_lang.so', + 'libloco.so', + 'libcircle_resizer_core.so', + 'circle_resizer_python_api.so', +] + +package_name = 'circle_resizer' +package_data_path = (pathlib.Path(__file__).parent / package_name).resolve() +package_data_path.mkdir(parents=True, exist_ok=True) + +for idx, lib_path in enumerate(resizer_dependent_so_libs): + shutil.copy((lib_dir / lib_path).resolve(), package_data_path) + # update path to relative to package_data_path (expected by the setup function) + resizer_dependent_so_libs[idx] = os.path.join(package_data_path, lib_path) + +setup( + name="circle-resizer", + version='0.0.0', + description='circle_resizer API binding', + long_description='It provides circle-resizer Python API', + url='https://github.com/Samsung/ONE', + license='Apache-2.0, MIT, BSD-2-Clause, BSD-3-Clause, Mozilla Public License 2.0', + has_ext_modules=lambda: True, + include_package_data=True, + packages=find_packages(), + package_data={package_name: resizer_dependent_so_libs}, + zip_safe=False, +) diff --git a/compiler/circle-resizer/python/src/CircleResizerBindings.cpp b/compiler/circle-resizer/python/src/CircleResizerBindings.cpp new file mode 100644 index 00000000000..119b5c79b30 --- /dev/null +++ b/compiler/circle-resizer/python/src/CircleResizerBindings.cpp @@ -0,0 +1,92 @@ + +/* + * Copyright (c) 2025 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. + */ + +#include "Shape.h" +#include "CircleModel.h" +#include "ModelEditor.h" + +#include +#include +#include +#include + +#include +#include +#include + +namespace py = pybind11; +using namespace circle_resizer; + +using Shapes = std::vector; + +PYBIND11_MAKE_OPAQUE(Dim); +PYBIND11_MAKE_OPAQUE(Shape); +PYBIND11_MAKE_OPAQUE(Shapes); + +PYBIND11_MODULE(circle_resizer_python_api, m) +{ + m.doc() = "circle-resizer module"; + + py::class_ dim(m, "Dim"); + dim.doc() = "circle_resizer::Dim"; + dim.def(py::init()); + dim.def("is_dynamic", &Dim::is_dynamic); + dim.def("value", &Dim::value); + dim.def("__eq__", [](const Dim &rhs, const Dim &lhs) { return rhs.value() == lhs.value(); }); + dim.def("__str__", [](const Dim &self) { return std::to_string(self.value()); }); + + py::class_ shape(m, "Shape"); + shape.doc() = "circle_resizer::Shape"; + shape.def("__eq__", [](const Shape &rhs, const Shape &lhs) { return rhs == lhs; }); + shape.def("__str__", [](const Shape &shape) -> std::string { + std::stringstream ss; + ss << shape; + return ss.str(); + }); + + auto shapes = py::bind_vector(m, "Shapes"); + shapes.doc() = "circle_resizer::Shapes"; + shapes.def("__str__", [](const Shapes &shapes) -> std::string { + if (shapes.empty()) + { + return ""; + } + std::stringstream ss; + for (int i = 0; i < shapes.size() - 1; ++i) + { + ss << shapes[i] << ", "; + } + ss << shapes.back(); + return ss.str(); + }); + + py::class_> circle_model(m, "CircleModel"); + circle_model.doc() = "circle_resizer::CircleModel"; + circle_model.def(py::init &>(), py::arg("buffer")); + circle_model.def(py::init(), py::arg("model_path")); + circle_model.def("input_shapes", &CircleModel::input_shapes); + circle_model.def("output_shapes", &CircleModel::output_shapes); + circle_model.def("save", py::overload_cast(&CircleModel::save), + py::arg("stream")); + circle_model.def("save", py::overload_cast(&CircleModel::save), + py::arg("output_path")); + + py::class_ model_editor(m, "ModelEditor"); + model_editor.doc() = "circle_resizer::ModelEditor"; + model_editor.def(py::init>(), py::arg("circle_model")); + model_editor.def("resize_inputs", &ModelEditor::resize_inputs, py::arg("shapes")); +} diff --git a/compiler/circle-resizer/requires.cmake b/compiler/circle-resizer/requires.cmake index 7c0ade30d58..2bc3d41bf28 100644 --- a/compiler/circle-resizer/requires.cmake +++ b/compiler/circle-resizer/requires.cmake @@ -2,4 +2,9 @@ require("arser") require("common-artifacts") require("mio-circle08") require("safemain") +require("mio-circle08") +require("logo-core") +require("luci") +require("logo") +require("common-artifacts") require("vconone") diff --git a/compiler/circle-resizer/src/CMakeLists.txt b/compiler/circle-resizer/src/CMakeLists.txt index d099a4991a2..a9c0c068410 100644 --- a/compiler/circle-resizer/src/CMakeLists.txt +++ b/compiler/circle-resizer/src/CMakeLists.txt @@ -8,11 +8,13 @@ add_library(circle_resizer_core SHARED "${CIRCLE_RESIZER_SOURCES}") target_include_directories(circle_resizer_core PUBLIC ../include) +target_link_libraries(circle_resizer_core PRIVATE mio_circle08) +target_link_libraries(circle_resizer_core PRIVATE logo_core) +target_link_libraries(circle_resizer_core PRIVATE luci_pass) +target_link_libraries(circle_resizer_core PRIVATE luci_lang) target_link_libraries(circle_resizer_core PRIVATE luci_export) target_link_libraries(circle_resizer_core PRIVATE luci_import) -target_link_libraries(circle_resizer_core PRIVATE luci_lang) -target_link_libraries(circle_resizer_core PRIVATE luci_pass) target_link_libraries(circle_resizer_core PRIVATE logo) -target_link_libraries(circle_resizer_core PRIVATE mio_circle08) +target_link_libraries(circle_resizer_core PRIVATE luci_log) install(TARGETS circle_resizer_core DESTINATION lib) diff --git a/compiler/circle-resizer/src/ShapeParser.cpp b/compiler/circle-resizer/src/ShapeParser.cpp index baa189f4160..574dc2e674c 100644 --- a/compiler/circle-resizer/src/ShapeParser.cpp +++ b/compiler/circle-resizer/src/ShapeParser.cpp @@ -25,7 +25,6 @@ using namespace circle_resizer; namespace { - bool is_blank(const std::string &s) { return !s.empty() && std::find_if(s.begin(), s.end(), diff --git a/compiler/common-artifacts/exclude.lst b/compiler/common-artifacts/exclude.lst index 4f1611bd01a..845e0b09422 100644 --- a/compiler/common-artifacts/exclude.lst +++ b/compiler/common-artifacts/exclude.lst @@ -110,6 +110,7 @@ tcgenerate(ReduceAny_dynamic_000) # TestDataGenerator does not support unknown d tcgenerate(ReduceAny_dynamic_001) # TestDataGenerator does not support unknown dimension tcgenerate(ReduceAny_dynamic_002) # TestDataGenerator does not support unknown dimension tcgenerate(ReduceAny_dynamic_003) # TestDataGenerator does not support unknown dimension +tcgenerate(ReduceAny_dynamic_004) # TestDataGenerator does not support unknown dimension tcgenerate(ReduceMax_000) tcgenerate(ReduceMax_dynamic_000) # TestDataGenerator does not support unknown dimension tcgenerate(ReduceMin_000) diff --git a/compiler/one-cmds/CMakeLists.txt b/compiler/one-cmds/CMakeLists.txt index 2e43fce4faa..99df414cd44 100644 --- a/compiler/one-cmds/CMakeLists.txt +++ b/compiler/one-cmds/CMakeLists.txt @@ -51,6 +51,7 @@ set(ONE_COMMAND_FILES one-import-tf one-import-tflite one-import-onnx + one-resize one-optimize one-quantize one-pack diff --git a/compiler/one-cmds/one-build b/compiler/one-cmds/one-build index 556a8f85eb9..984545a5b8d 100644 --- a/compiler/one-cmds/one-build +++ b/compiler/one-cmds/one-build @@ -79,6 +79,7 @@ def _get_driver_name(driver_name): 'one-import-tf': 'one-import-tf', 'one-import-tflite': 'one-import-tflite', 'one-import-onnx': 'one-import-onnx', + 'one-resize': 'one-resize', 'one-optimize': 'one-optimize', 'one-quantize': 'one-quantize', 'one-partition': 'one-partition', @@ -154,8 +155,8 @@ def main(): bin_dir = os.path.dirname(os.path.realpath(__file__)) import_drivers_dict = oneutils.detect_one_import_drivers(bin_dir) transform_drivers = [ - 'one-optimize', 'one-quantize', 'one-pack', 'one-codegen', 'one-profile', - 'one-partition' + 'one-resize', '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 42960811ef3..583c84e180f 100644 --- a/compiler/one-cmds/one-build.template.cfg +++ b/compiler/one-cmds/one-build.template.cfg @@ -3,6 +3,7 @@ one-import-tf=True one-import-tflite=False one-import-bcq=False one-import-onnx=False +one-resize=False one-optimize=True one-quantize=False one-parition=False diff --git a/compiler/one-cmds/one-resize b/compiler/one-cmds/one-resize new file mode 100644 index 00000000000..f86c69692db --- /dev/null +++ b/compiler/one-cmds/one-resize @@ -0,0 +1,131 @@ +#!/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) 2025 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 onelib.utils as oneutils + +# TODO Find better way to suppress trackback on error +sys.tracebacklimit = 0 + + +def _get_parser(): + parser = argparse.ArgumentParser( + description='command line tool to change shape of model inputs') + + oneutils.add_default_arg(parser) + + ## model2nnpkg arguments + model2nnpkg_group = parser.add_argument_group('arguments for packaging') + + model2nnpkg_group.add_argument('-i', + '--input_path', + type=str, + help='The path to the input model (.circle)') + + model2nnpkg_group.add_argument('-o', + '--output_path', + type=str, + help='The path to the resized model (.circle)') + + model2nnpkg_group.add_argument( + '-s', + '--input_shapes', + type=str, + help= + 'New inputs shapes in in comma separated format. An example for 2 inputs: [1,2],[3,4].' + ) + + return parser + + +def _parse_arg(parser): + args = parser.parse_args() + # print version + if args.version: + oneutils.print_version_and_exit(__file__) + + return args + + +def _verify_arg(parser, args): + """verify given arguments""" + # check if required arguments is given + missing = [] + if not oneutils.is_valid_attr(args, 'input_path'): + missing.append('input_path') + if not oneutils.is_valid_attr(args, 'output_path'): + missing.append('output_path') + if not oneutils.is_valid_attr(args, 'input_shapes'): + missing.append('input_shapes') + if len(missing): + parser.error('the following arguments are required: ' + ' '.join(missing)) + return + + +def _resize(args): + # get file path to log + bin_path = os.path.dirname(os.path.realpath(__file__)) + cur_path = os.getcwd() + input_path = os.path.join(cur_path, args.input_path) + output_path = os.path.join(cur_path, args.output_path) + + log_file_path = os.path.join(cur_path, output_path) + '.log' + + with open(log_file_path, 'wb', buffering=0) as f: + # make a command to package circle model and metadata into nnpackage + circle_resizer_path = os.path.join(bin_path, 'circle-resizer') + + cmd = [os.path.expanduser(circle_resizer_path)] + + cmd.append('--input_path') + cmd.append(input_path) + cmd.append('--output_path') + cmd.append(output_path) + cmd.append('--input_shapes') + cmd.append(args.input_shapes) + + f.write((' '.join(cmd) + '\n').encode()) + + # run circle-resizer + oneutils.run(cmd, err_prefix='one-resize', logfile=f) + + +def main(): + # parse arguments + parser = _get_parser() + args = _parse_arg(parser) + + # parse configuration file + oneutils.parse_cfg(args.config, 'one-resize', args) + + # verify arguments + _verify_arg(parser, args) + + # resize the model + _resize(args) + + +if __name__ == '__main__': + oneutils.safemain(main, __file__) diff --git a/compiler/one-cmds/onecc.template.cfg b/compiler/one-cmds/onecc.template.cfg index 8bc1e2a4ccb..a54110df2ac 100644 --- a/compiler/one-cmds/onecc.template.cfg +++ b/compiler/one-cmds/onecc.template.cfg @@ -14,6 +14,7 @@ one-import-tf=False one-import-tflite=False one-import-bcq=False one-import-onnx=False +one-resize=False ; circle to circle with optimization one-optimize=False ; circle to circle with quantization @@ -90,6 +91,15 @@ unroll_rnn= ; True or False unroll_lstm= +[one-resize] +# mandatory +; path to the input model +input_path= +; path to the resized model +output_path= +; the new shapes of inputs +input_shapes= + [one-optimize] # mandatory ; circle file diff --git a/compiler/one-cmds/onelib/CfgRunner.py b/compiler/one-cmds/onelib/CfgRunner.py index 13272525445..27a5f3240e5 100644 --- a/compiler/one-cmds/onelib/CfgRunner.py +++ b/compiler/one-cmds/onelib/CfgRunner.py @@ -27,8 +27,8 @@ def _simple_warning(message, category, filename, lineno, file=None, line=None): class CfgRunner: driver_sequence = [ - 'one-optimize', 'one-quantize', 'one-pack', 'one-codegen', 'one-profile', - 'one-partition', 'one-infer' + 'one-optimize', 'one-resize', 'one-quantize', 'one-pack', 'one-codegen', + 'one-profile', 'one-partition', 'one-infer' ] def __init__(self, path): diff --git a/compiler/one-cmds/onelib/OptionBuilder.py b/compiler/one-cmds/onelib/OptionBuilder.py index 6a75783ada4..750b196467b 100644 --- a/compiler/one-cmds/onelib/OptionBuilder.py +++ b/compiler/one-cmds/onelib/OptionBuilder.py @@ -80,9 +80,10 @@ def _build_quantize(self, commands): 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 = dict.fromkeys([ + 'one-import-bcq', 'one-import-tflite', 'one-resize', '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 diff --git a/compiler/one-cmds/tests/one-build_001.test b/compiler/one-cmds/tests/one-build_001.test new file mode 100644 index 00000000000..317e90a4a39 --- /dev/null +++ b/compiler/one-cmds/tests/one-build_001.test @@ -0,0 +1,43 @@ +#!/bin/bash + +# Copyright (c) 2025 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. + +# positive usage with overriding option + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +config_file="one-resize_001.cfg" +output_file_cfg="inception_v3.resized.circle" + +rm -f ${filename}.log +rm -f ${output_file_cfg} + +# run test +one-build -C ${config_file} > ${filename}.log 2>&1 + +if [[ ! -s "${output_file_cfg}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-import_002.cfg b/compiler/one-cmds/tests/one-import_002.cfg index e7ede7bc2f4..079886cb565 100644 --- a/compiler/one-cmds/tests/one-import_002.cfg +++ b/compiler/one-cmds/tests/one-import_002.cfg @@ -2,6 +2,7 @@ one-import-tf=True one-import-tflite=False one-import-bcq=False +one-resize=True one-optimize=False one-quantize=False one-pack=False diff --git a/compiler/one-cmds/tests/one-import_003.cfg b/compiler/one-cmds/tests/one-import_003.cfg index b679ebdb3b6..e993d734cb9 100644 --- a/compiler/one-cmds/tests/one-import_003.cfg +++ b/compiler/one-cmds/tests/one-import_003.cfg @@ -2,6 +2,7 @@ one-import-tf=True one-import-tflite=False one-import-bcq=False +one-resize=False one-optimize=False one-quantize=False one-pack=False diff --git a/compiler/one-cmds/tests/one-import_004.cfg b/compiler/one-cmds/tests/one-import_004.cfg index d28c8dff642..2c9eae5a65a 100644 --- a/compiler/one-cmds/tests/one-import_004.cfg +++ b/compiler/one-cmds/tests/one-import_004.cfg @@ -2,6 +2,7 @@ one-import-tf=True one-import-tflite=False one-import-bcq=False +one-resize=False one-optimize=False one-quantize=False one-pack=False diff --git a/compiler/one-cmds/tests/one-import_005.cfg b/compiler/one-cmds/tests/one-import_005.cfg index abe4c7d7745..775a6980b2c 100644 --- a/compiler/one-cmds/tests/one-import_005.cfg +++ b/compiler/one-cmds/tests/one-import_005.cfg @@ -3,6 +3,7 @@ one-import-tf=False one-import-tflite=False one-import-bcq=False one-import-onnx=True +one-resize=False one-optimize=False one-quantize=False one-pack=False diff --git a/compiler/one-cmds/tests/one-resize_001.cfg b/compiler/one-cmds/tests/one-resize_001.cfg new file mode 100644 index 00000000000..6964ad0eeb5 --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_001.cfg @@ -0,0 +1,14 @@ +[one-build] +one-import-tf=False +one-import-tflite=False +one-import-bcq=False +one-resize=True +one-optimize=False +one-quantize=False +one-pack=False +one-codegen=False + +[one-resize] +input_path=inception_v3.circle +output_path=inception_v3.resized.circle +input_shapes=[2,299,299,3] diff --git a/compiler/one-cmds/tests/one-resize_001.test b/compiler/one-cmds/tests/one-resize_001.test new file mode 100644 index 00000000000..68abb015579 --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_001.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright (c) 2025 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%.*}" +test_model_name="Add_000" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +input_path="${test_model_name}.circle" +input_shapes="[1,3,3,1],[1,3,3,1]" +output_path="${test_model_name}.resize.circle" + +rm -f ${filename}.log +rm -f ${output_path} + +# run test +one-resize \ +--input_path ${input_path} \ +--input_shapes ${input_shapes} \ +--output_path ${output_path} > ${filename}.log 2>&1 + +if [[ ! -s "${output_path}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-resize_002.test b/compiler/one-cmds/tests/one-resize_002.test new file mode 100644 index 00000000000..1f8b69e5695 --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_002.test @@ -0,0 +1,43 @@ +#!/bin/bash + +# Copyright (c) 2025 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. + +# positive usage with overriding option + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +config_file="one-resize_001.cfg" +output_file_cfg="inception_v3.resized.circle" + +rm -f ${filename}.log +rm -f ${output_file_cfg} + +# run test +one-resize -C ${config_file} > ${filename}.log 2>&1 + +if [[ ! -s "${output_file_cfg}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-resize_003.test b/compiler/one-cmds/tests/one-resize_003.test new file mode 100644 index 00000000000..3b246413a30 --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_003.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright (c) 2025 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%.*}" +test_model_name="Net_InstanceNorm_003" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +input_path="${test_model_name}.circle" +input_shapes="[2,8,6,12]" +output_path="${test_model_name}.resize.circle" + +rm -f ${filename}.log +rm -f ${output_path} + +# run test +one-resize \ +-i ${input_path} \ +-s ${input_shapes} \ +-o ${output_path} > ${filename}.log 2>&1 + +if [[ ! -s "${output_path}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-resize_004.test b/compiler/one-cmds/tests/one-resize_004.test new file mode 100644 index 00000000000..16dd6274ca1 --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_004.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright (c) 2025 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%.*}" +test_model_name="dyn_llama2_query" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +input_path="${test_model_name}.circle" +input_shapes="[2,16]" +output_path="${test_model_name}.resize.circle" + +rm -f ${filename}.log +rm -f ${output_path} + +# run test +one-resize \ +-i ${input_path} \ +-s ${input_shapes} \ +-o ${output_path} > ${filename}.log 2>&1 + +if [[ ! -s "${output_path}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-resize_005.test b/compiler/one-cmds/tests/one-resize_005.test new file mode 100644 index 00000000000..b5fc9c5c95d --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_005.test @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright (c) 2025 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%.*}" +test_model_name="dyn_llama2_norm" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +input_path="${test_model_name}.circle" +input_shapes="[2,16]" +output_path="${test_model_name}.resize.circle" + +rm -f ${filename}.log +rm -f ${output_path} + +# run test +one-resize \ +-i ${input_path} \ +-s ${input_shapes} \ +-o ${output_path} > ${filename}.log 2>&1 + +if [[ ! -s "${output_path}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-resize_neg_001.test b/compiler/one-cmds/tests/one-resize_neg_001.test new file mode 100644 index 00000000000..aaafdfa41aa --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_neg_001.test @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright (c) 2025 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%.*}" +test_model_name="Add_000" + +trap_err_onexit() +{ + if grep -q "the following arguments are required: input_shapes" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +input_path="${test_model_name}.circle" +output_path="${test_model_name}.resize.circle" + +rm -f ${filename}.log +rm -f ${output_path} + +# run test +one-resize \ +--input_path ${input_path} \ +--output_path ${output_path} > ${filename}.log 2>&1 + +if [[ ! -s "${output_path}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/one-resize_neg_002.test b/compiler/one-cmds/tests/one-resize_neg_002.test new file mode 100644 index 00000000000..f2e3b600561 --- /dev/null +++ b/compiler/one-cmds/tests/one-resize_neg_002.test @@ -0,0 +1,51 @@ +#!/bin/bash + +# Copyright (c) 2025 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%.*}" +test_model_name="Add_000" + +trap_err_onexit() +{ + if grep -q "No shapes found in input string: abcd" "${filename}.log"; then + echo "${filename_ext} SUCCESS" + exit 0 + fi + + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +input_path="${test_model_name}.circle" +input_shapes="abcd" +output_path="${test_model_name}.resize.circle" + +rm -f ${filename}.log +rm -f ${output_path} + +# run test +one-resize \ +--input_path ${input_path} \ +--input_shapes ${input_shapes} \ +--output_path ${output_path} > ${filename}.log 2>&1 + +if [[ ! -s "${output_path}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/onecc_070.cfg b/compiler/one-cmds/tests/onecc_070.cfg new file mode 100644 index 00000000000..481e8459f49 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_070.cfg @@ -0,0 +1,15 @@ +[onecc] +one-import-tf=False +one-import-tflite=False +one-import-bcq=False +one-import-onnx=False +one-resize=True +one-optimize=False +one-quantize=False +one-pack=False +one-codegen=False + +[one-resize] +input_path=inception_v3.circle +output_path=inception_v3.resized.circle +input_shapes=[2,299,299,3] diff --git a/compiler/one-cmds/tests/onecc_070.test b/compiler/one-cmds/tests/onecc_070.test new file mode 100644 index 00000000000..ef30ff07a75 --- /dev/null +++ b/compiler/one-cmds/tests/onecc_070.test @@ -0,0 +1,43 @@ +#!/bin/bash + +# Copyright (c) 2025 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-quantize + +filename_ext="$(basename -- $0)" +filename="${filename_ext%.*}" + +trap_err_onexit() +{ + echo "${filename_ext} FAILED" + exit 255 +} + +trap trap_err_onexit ERR + +config_file="onecc_070.cfg" +output_file="inception_v3.resized.circle" + +rm -f ${filename}.log +rm -rf ${output_file} + +# run test +onecc -C ${config_file} > ${filename}.log 2>&1 + +if [[ ! -s "${output_file}" ]]; then + trap_err_onexit +fi + +echo "${filename_ext} SUCCESS" diff --git a/compiler/one-cmds/tests/prepare_test_materials.sh b/compiler/one-cmds/tests/prepare_test_materials.sh index 065c2dcc5dd..067eb744c61 100644 --- a/compiler/one-cmds/tests/prepare_test_materials.sh +++ b/compiler/one-cmds/tests/prepare_test_materials.sh @@ -135,6 +135,21 @@ if [[ ! -s "onnx_conv2d_conv2d_split.onnx" ]]; then # https://github.com/Samsung/ONE/issues/11280#issuecomment-1732852295 fi +# prepare models to test circle-resizer +if [[ ! -s "dyn_llama2_query.circle" ]]; then + rm -rf dyn_llama2_query.zip + wget -nv https://github.com/user-attachments/files/19584809/dyn_llama2_query.zip + unzip dyn_llama2_query.zip + # https://github.com/Samsung/ONE/issues/14791#issue-2902255581 +fi + +if [[ ! -s "dyn_llama2_norm.circle" ]]; then + rm -rf dyn_llama2_norm.zip + wget -nv https://github.com/user-attachments/files/19584810/dyn_llama2_norm.zip + unzip dyn_llama2_norm.zip + # https://github.com/Samsung/ONE/issues/14791#issue-2902255581 +fi + if [[ ! -s "Add_000.inputs.txt" ]]; then rm -rf Add_000.inputs.txt echo "Add_000.circle.input0 Add_000.circle.input1" >> Add_000.inputs.txt diff --git a/infra/debian/compiler/docs/one-resize.1 b/infra/debian/compiler/docs/one-resize.1 new file mode 100644 index 00000000000..a75ca2bee11 --- /dev/null +++ b/infra/debian/compiler/docs/one-resize.1 @@ -0,0 +1,45 @@ +.TH ONE-RESIZE "1" "July 2025" "one-resize version 1.28.0" "User Commands" +.SH NAME +one-resize \- resize input shapes of the model +.SH DESCRIPTION +usage: one\-resize [\-h] [\-v] [\-V] [\-C CONFIG] [\-i INPUT_PATH] [\-s INPUT_SHAPES] [\-o OUTPUT_PATH] +.PP +\fBone\-resize\fR is a command line tool to change input shapes of Circle models. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +show this help message and exit +.TP +\fB\-v\fR, \fB\-\-version\fR +show program's version number and exit +.TP +\fB\-V\fR, \fB\-\-verbose\fR +output additional information to stdout or stderr +.TP +\fB\-C\fR CONFIG, \fB\-\-config\fR CONFIG +run with configuration file +.TP +\fB\-i\fR INPUT_PATH, \fB\-\-input_path\fR INPUT_PATH +The path to the input model (.circle) +.TP +\fB\-i\fR INPUT_SHAPES, \fB\-\-input_shapes\fR INPUT_SHAPES +New inputs shapes in in comma separated format. An example for 2 inputs: [1,2],[3,4] +.TP +\fB\-o\fR OUTPUT_PATH, \fB\-\-output_path\fR OUTPUT_PATH +The path to the resized model (.circle) +.SH COPYRIGHT +Copyright \(co 2020\-2025 Samsung Electronics Co., Ltd. All Rights Reserved +Licensed under the Apache License, Version 2.0 +https://github.com/Samsung/ONE +.SH "SEE ALSO" +The full documentation for +.B one-resize +is maintained as a Texinfo manual. If the +.B info +and +.B one-resize +programs are properly installed at your site, the command +.IP +.B info one-resize +.PP +should give you access to the complete manual. diff --git a/infra/debian/compiler/one-compiler.install b/infra/debian/compiler/one-compiler.install index 5b169677ec1..4330c5ab793 100644 --- a/infra/debian/compiler/one-compiler.install +++ b/infra/debian/compiler/one-compiler.install @@ -22,6 +22,7 @@ usr/bin/one-import-bcq usr/share/one/bin/ usr/bin/one-import-onnx usr/share/one/bin/ usr/bin/one-import-tf usr/share/one/bin/ usr/bin/one-import-tflite usr/share/one/bin/ +usr/bin/one-resize usr/share/one/bin/ usr/bin/one-infer usr/share/one/bin/ usr/bin/one-optimize usr/share/one/bin/ usr/bin/one-pack usr/share/one/bin/ diff --git a/infra/debian/compiler/one-compiler.manpages b/infra/debian/compiler/one-compiler.manpages index e0284ae4e4a..c4326421090 100644 --- a/infra/debian/compiler/one-compiler.manpages +++ b/infra/debian/compiler/one-compiler.manpages @@ -6,6 +6,7 @@ debian/docs/one-import-bcq.1 debian/docs/one-import-onnx.1 debian/docs/one-import-tf.1 debian/docs/one-import-tflite.1 +debian/docs/one-resize.1 debian/docs/one-optimize.1 debian/docs/one-pack.1 debian/docs/one-partition.1 diff --git a/res/TensorFlowLiteRecipes/GreaterEqual_001/test.recipe b/res/TensorFlowLiteRecipes/GreaterEqual_001/test.recipe new file mode 100644 index 00000000000..bae45f8b71c --- /dev/null +++ b/res/TensorFlowLiteRecipes/GreaterEqual_001/test.recipe @@ -0,0 +1,26 @@ +operand { + name: "ifm1" + type: FLOAT32 + shape { dim: 1 dim: 4 dim: 4 dim: 3 } +} +operand { + name: "ifm2" + type: FLOAT32 + shape { dim: 1 dim: 4 dim: 4 dim: 3 } +} +operand { + name: "ofm" + type: BOOL + shape { dim: 1 dim: 4 dim: 4 dim: 3 } +} +operation { + type: "GreaterEqual" + greaterequal_options { + } + input: "ifm1" + input: "ifm2" + output: "ofm" +} +input: "ifm1" +input: "ifm2" +output: "ofm" diff --git a/res/TensorFlowLiteRecipes/GreaterEqual_001/test.reverse b/res/TensorFlowLiteRecipes/GreaterEqual_001/test.reverse new file mode 100644 index 00000000000..e69de29bb2d diff --git a/res/TensorFlowLiteRecipes/GreaterEqual_001/test.rule b/res/TensorFlowLiteRecipes/GreaterEqual_001/test.rule new file mode 100644 index 00000000000..6e11af8f7cc --- /dev/null +++ b/res/TensorFlowLiteRecipes/GreaterEqual_001/test.rule @@ -0,0 +1,7 @@ +# To check if the model is resized properly + +RULE "VERIFY_FILE_FORMAT" $(verify_file_format) '=' 1 + +RULE "IFM1_SHAPE" $(tensor_shape ifm1) '=' [1,2,3] +RULE "IFM2_SHAPE" $(tensor_shape ifm2) '=' [1,2,3] +RULE "GREATER_EQUAL_SHAPE" $(tensor_shape ofm) '=' [1,2,3] diff --git a/res/TensorFlowLiteRecipes/Inf_StridedSlice_002/test.recipe b/res/TensorFlowLiteRecipes/Inf_StridedSlice_002/test.recipe new file mode 100644 index 00000000000..9db0593c066 --- /dev/null +++ b/res/TensorFlowLiteRecipes/Inf_StridedSlice_002/test.recipe @@ -0,0 +1,47 @@ +operand { + name: "ifm" + type: FLOAT32 + shape { dim: 1 dim: 0 dim: 0 dim: 5 } + shape_signature { dim: 1 dim: -1 dim: -1 dim: 5 } +} +operand { + name: "begin" + type: INT32 + shape { dim: 4 } + filler { tag: "explicit" arg: "0" arg: "0" arg: "0" arg: "0" } +} +operand { + name: "end" + type: INT32 + shape { dim: 4 } + filler { tag: "explicit" arg: "1" arg: "8" arg: "3" arg: "5" } +} +operand { + name: "strides" + type: INT32 + shape { dim: 4 } + filler { tag: "explicit" arg: "1" arg: "1" arg: "1" arg: "1" } +} +operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 0 dim: 0 dim: 5 } + shape_signature { dim: 1 dim: -1 dim: -1 dim: 5 } +} +operation { + type: "StridedSlice" + input: "ifm" + input: "begin" + input: "end" + input: "strides" + output: "ofm" + strided_slice_options { + begin_mask: 0 + end_mask: 0 + ellipsis_mask: 0 + new_axis_mask: 0 + shrink_axis_mask: 0 + } +} +input: "ifm" +output: "ofm" diff --git a/res/TensorFlowLiteRecipes/Inf_StridedSlice_002/test.rule b/res/TensorFlowLiteRecipes/Inf_StridedSlice_002/test.rule new file mode 100644 index 00000000000..eca45dc33f0 --- /dev/null +++ b/res/TensorFlowLiteRecipes/Inf_StridedSlice_002/test.rule @@ -0,0 +1,6 @@ +# To check if the model is resized properly + +RULE "VERIFY_FILE_FORMAT" $(verify_file_format) '=' 1 + +RULE "IFM_SHAPE" $(tensor_shape ifm) '=' [1,10,10,5] +RULE "STRIDED_SLICE_SHAPE" $(tensor_shape ofm) '=' [1,8,3,5] diff --git a/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.recipe b/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.recipe new file mode 100644 index 00000000000..0e47be64b46 --- /dev/null +++ b/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.recipe @@ -0,0 +1,90 @@ +operand { + name: "in" + type: FLOAT32 + shape { dim: 1 dim: 16 } +} +operand { + name: "weight" + type: FLOAT32 + shape { dim: 16 dim: 16 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "bias" + type: FLOAT32 + shape { dim: 16 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "out" + type: FLOAT32 + shape { dim: 1 dim: 16 } +} +operation { + type: "FullyConnected" + fullyconnected_options { + activation: RELU + } + input: "in" + input: "weight" + input: "bias" + output: "out" +} +operand { + name: "gelu_out" + type: FLOAT32 + shape { dim: 1 dim: 16 } +} +operation { + type: "Gelu" + gelu_options { + approximate: false + } + input: "out" + output: "gelu_out" +} +operand { + name: "weight_2" + type: FLOAT32 + shape { dim: 4 dim: 16 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "bias_2" + type: FLOAT32 + shape { dim: 4 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "out_2" + type: FLOAT32 + shape { dim: 1 dim: 4 } +} +operation { + type: "FullyConnected" + fullyconnected_options { + activation: RELU + } + input: "gelu_out" + input: "weight_2" + input: "bias_2" + output: "out_2" +} +input: "in" +output: "out_2" diff --git a/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.reverse b/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.reverse new file mode 100644 index 00000000000..e69de29bb2d diff --git a/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.rule b/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.rule new file mode 100644 index 00000000000..05ecff0e7c1 --- /dev/null +++ b/res/TensorFlowLiteRecipes/Net_FullyConnected_Gelu_001/test.rule @@ -0,0 +1,6 @@ +# To check if the model is resized properly + +RULE "VERIFY_FILE_FORMAT" $(verify_file_format) '=' 1 + +RULE "IN_SHAPE" $(tensor_shape in) '=' [2,16] +RULE "OUT_2_SHAPE" $(tensor_shape out_2) '=' [2,4] diff --git a/res/TensorFlowLiteRecipes/PRelu_002/test.recipe b/res/TensorFlowLiteRecipes/PRelu_002/test.recipe new file mode 100644 index 00000000000..35f88c16c6c --- /dev/null +++ b/res/TensorFlowLiteRecipes/PRelu_002/test.recipe @@ -0,0 +1,24 @@ +operand { + name: "ifm1" + type: FLOAT32 + shape { dim: 1 dim: 4 dim: 4 dim: 3 } +} +operand { + name: "ifm2" + type: FLOAT32 + shape { dim: 1 dim: 1 dim: 3 } +} +operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 4 dim: 4 dim: 3 } +} +operation { + type: "PRelu" + input: "ifm1" + input: "ifm2" + output: "ofm" +} +input: "ifm1" +input: "ifm2" +output: "ofm" diff --git a/res/TensorFlowLiteRecipes/PRelu_002/test.reverse b/res/TensorFlowLiteRecipes/PRelu_002/test.reverse new file mode 100644 index 00000000000..e69de29bb2d diff --git a/res/TensorFlowLiteRecipes/PRelu_002/test.rule b/res/TensorFlowLiteRecipes/PRelu_002/test.rule new file mode 100644 index 00000000000..39eacbd0a36 --- /dev/null +++ b/res/TensorFlowLiteRecipes/PRelu_002/test.rule @@ -0,0 +1,7 @@ +# To check if the model is resized properly + +RULE "VERIFY_FILE_FORMAT" $(verify_file_format) '=' 1 + +RULE "IFM1_SHAPE" $(tensor_shape ifm1) '=' [1,4,4,5] +RULE "IFM2_SHAPE" $(tensor_shape ifm2) '=' [1,1,5] +RULE "PRELU_SHAPE" $(tensor_shape ofm) '=' [1,4,4,5] diff --git a/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.recipe b/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.recipe new file mode 100644 index 00000000000..427bd05f17b --- /dev/null +++ b/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.recipe @@ -0,0 +1,31 @@ +operand { + name: "ifm" + type: BOOL + shape { dim: 1 dim: 3 dim: 4 } + shape_signature { dim: -1 dim: 3 dim: 4 } +} +operand { + name: "reduction_indices" + type: INT32 + shape { dim: 3 } + filler { + tag: "explicit" + arg: "0" arg: "1" arg: "2" + } +} +operand { + name: "ofm" + type: BOOL + shape { } +} +operation { + type: "ReduceAny" + reduce_any_options { + keep_dims: false + } + input: "ifm" + input: "reduction_indices" + output: "ofm" +} +input: "ifm" +output: "ofm" diff --git a/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.reverse b/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.reverse new file mode 100644 index 00000000000..e69de29bb2d diff --git a/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.rule b/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.rule new file mode 100644 index 00000000000..052a5727e75 --- /dev/null +++ b/res/TensorFlowLiteRecipes/ReduceAny_dynamic_004/test.rule @@ -0,0 +1,6 @@ +# To check if the model is resized properly + +RULE "VERIFY_FILE_FORMAT" $(verify_file_format) '=' 1 + +RULE "IFM_SHAPE" $(tensor_shape ifm) '=' [4,5,6] +RULE "REDUCE_ANY_SHAPE" $(tensor_shape ofm) '=' [] diff --git a/res/TensorFlowLiteRecipes/Split_001/test.recipe b/res/TensorFlowLiteRecipes/Split_001/test.recipe new file mode 100644 index 00000000000..e4bbe7620e1 --- /dev/null +++ b/res/TensorFlowLiteRecipes/Split_001/test.recipe @@ -0,0 +1,34 @@ +operand { + name: "ifm" + type: FLOAT32 + shape { dim: 6 dim: 1 dim: 2 } +} +operand { + name: "split_dim" + type: INT32 + shape { } + filler { tag: "explicit" arg: "0" } +} +operand { + name: "ofm1" + type: FLOAT32 + shape { dim: 3 dim: 1 dim: 2 } +} +operand { + name: "ofm2" + type: FLOAT32 + shape { dim: 3 dim: 1 dim: 2 } +} +operation { + type: "Split" + split_options { + num_splits: 2 + } + input: "split_dim" + input: "ifm" + output: "ofm1" + output: "ofm2" +} +input: "ifm" +output: "ofm1" +output: "ofm2" diff --git a/res/TensorFlowLiteRecipes/Split_001/test.reverse b/res/TensorFlowLiteRecipes/Split_001/test.reverse new file mode 100644 index 00000000000..e69de29bb2d diff --git a/res/TensorFlowLiteRecipes/Split_001/test.rule b/res/TensorFlowLiteRecipes/Split_001/test.rule new file mode 100644 index 00000000000..2f62e5e387c --- /dev/null +++ b/res/TensorFlowLiteRecipes/Split_001/test.rule @@ -0,0 +1,7 @@ +# To check if the model is resized properly + +RULE "VERIFY_FILE_FORMAT" $(verify_file_format) '=' 1 + +RULE "IFM_SHAPE" $(tensor_shape ifm) '=' [8,1,2] +RULE "OFM1_SHAPE" $(tensor_shape ofm1) '=' [4,1,2] +RULE "OFM2_SHAPE" $(tensor_shape ofm2) '=' [4,1,2]