From e609a58f3b21aa0a99dfa6496b3ff59684b41089 Mon Sep 17 00:00:00 2001 From: chenyx113 Date: Wed, 19 Feb 2025 21:01:32 +0800 Subject: [PATCH 1/3] [tools/onnx-subgraph] Add onnx subgraph python code by given nodes position 1. subgraphs_ios.txt is node position information for onnx model splitting, it will be generated by future code, we use it for smoking test now. 2. extract_onnx.py can split the onnx model to sub models ONE-DCO-1.0-Signed-off-by: Youxin Chen --- tools/onnx_subgraph/CMakeLists.txt | 2 + tools/onnx_subgraph/extract_onnx.py | 68 +++++++++++++++++++++++++++ tools/onnx_subgraph/subgraphs_ios.txt | 4 ++ 3 files changed, 74 insertions(+) create mode 100644 tools/onnx_subgraph/extract_onnx.py create mode 100644 tools/onnx_subgraph/subgraphs_ios.txt diff --git a/tools/onnx_subgraph/CMakeLists.txt b/tools/onnx_subgraph/CMakeLists.txt index b6727d7f2e8..31868fe54be 100644 --- a/tools/onnx_subgraph/CMakeLists.txt +++ b/tools/onnx_subgraph/CMakeLists.txt @@ -16,6 +16,8 @@ include_directories(${Python3_INCLUDE_DIRS}) set(ONNX_SUBGRAPH_FILES test_model_download.sh + extract_onnx.py + subgraphs_ios.txt ) foreach(ONNX_SUBGRAPH IN ITEMS ${ONNX_SUBGRAPH_FILES}) set(ONNX_SUBGRAPH_FILE ${ONNX_SUBGRAPH}) diff --git a/tools/onnx_subgraph/extract_onnx.py b/tools/onnx_subgraph/extract_onnx.py new file mode 100644 index 00000000000..c7990d095ef --- /dev/null +++ b/tools/onnx_subgraph/extract_onnx.py @@ -0,0 +1,68 @@ +# 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 onnx +import re +import os + + +def split_subgraph_ios(iofile): + iolist = re.split('--input-name |;--output-name ', iofile) + in_ = iolist[1].split(';') + out_ = iolist[2].split(';') + del out_[-1] + type = iolist[0].split('subgraph')[0] + return in_, out_, type + + +def split_onnx_ios(instrfile, + input_path='net/generation_model_simplify.onnx', + out_folder='subgraphs/'): + if not os.path.exists(input_path): + print(input_path + " not exist") + return + + model = onnx.load(input_path) + onnx.checker.check_model(input_path) + for output in model.graph.output: + model.graph.value_info.append(output) + onnx.save(model, input_path) + f1 = open(instrfile, "r") + lines = f1.readlines() + cpu_count = 0 + npu_count = 0 + count = 0 + if not os.path.exists(out_folder): + os.makedirs(out_folder) + for line in lines: + input_names, output_names, type = split_subgraph_ios(line) + if (type == 'CPU'): + count = cpu_count + cpu_count = cpu_count + 1 + else: + count = npu_count + npu_count = npu_count + 1 + output_path_folder = out_folder + if not os.path.exists(output_path_folder): + os.makedirs(output_path_folder) + output_path = output_path_folder + type + 'subgraph' + str(count) + '.onnx' + if ((input_names != ['']) and (output_names != [''])): + onnx.utils.extract_model(input_path, output_path, input_names, output_names) + print("succeed", count) + count = count + 1 + f1.close() + + +if __name__ == "__main__": + split_onnx_ios('./scripts/subgraphs_ios.txt', './resnet-test.onnx') diff --git a/tools/onnx_subgraph/subgraphs_ios.txt b/tools/onnx_subgraph/subgraphs_ios.txt new file mode 100644 index 00000000000..9dfdc95e32e --- /dev/null +++ b/tools/onnx_subgraph/subgraphs_ios.txt @@ -0,0 +1,4 @@ +NPUsubgraph0: order0--input-name x;--output-name /stem/conv3/bn/act/Mul_output_0; +NPUsubgraph1: order2--input-name /stem/pool/MaxPool_output_0;--output-name /stages/stages.3/stages.3.1/act/Mul_output_0; +CPUsubgraph0: order1--input-name /stem/conv3/bn/act/Mul_output_0;--output-name /stem/pool/MaxPool_output_0; +CPUsubgraph1: order3--input-name /stages/stages.3/stages.3.1/act/Mul_output_0;--output-name 316; From fab91a11866a1c4a408a7ed09216316c8567af2b Mon Sep 17 00:00:00 2001 From: chenyx113 Date: Thu, 20 Feb 2025 13:50:56 +0800 Subject: [PATCH 2/3] [tools/onnx-subgraph] update as code review comments 1. remove useless default value 2. change fixed setting to args ONE-DCO-1.0-Signed-off-by: Youxin Chen --- tools/onnx_subgraph/extract_onnx.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tools/onnx_subgraph/extract_onnx.py b/tools/onnx_subgraph/extract_onnx.py index c7990d095ef..e13649e418a 100644 --- a/tools/onnx_subgraph/extract_onnx.py +++ b/tools/onnx_subgraph/extract_onnx.py @@ -15,6 +15,7 @@ import onnx import re import os +import argparse def split_subgraph_ios(iofile): @@ -26,25 +27,24 @@ def split_subgraph_ios(iofile): return in_, out_, type -def split_onnx_ios(instrfile, - input_path='net/generation_model_simplify.onnx', - out_folder='subgraphs/'): - if not os.path.exists(input_path): - print(input_path + " not exist") - return +def split_onnx_ios(instrfile, input_path, out_folder='subgraphs/'): + os.makedirs(out_folder, exist_ok=True) model = onnx.load(input_path) onnx.checker.check_model(input_path) for output in model.graph.output: model.graph.value_info.append(output) onnx.save(model, input_path) + f1 = open(instrfile, "r") lines = f1.readlines() cpu_count = 0 npu_count = 0 count = 0 + if not os.path.exists(out_folder): os.makedirs(out_folder) + for line in lines: input_names, output_names, type = split_subgraph_ios(line) if (type == 'CPU'): @@ -53,16 +53,30 @@ def split_onnx_ios(instrfile, else: count = npu_count npu_count = npu_count + 1 + output_path_folder = out_folder if not os.path.exists(output_path_folder): os.makedirs(output_path_folder) output_path = output_path_folder + type + 'subgraph' + str(count) + '.onnx' + if ((input_names != ['']) and (output_names != [''])): onnx.utils.extract_model(input_path, output_path, input_names, output_names) print("succeed", count) count = count + 1 + f1.close() if __name__ == "__main__": - split_onnx_ios('./scripts/subgraphs_ios.txt', './resnet-test.onnx') + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('-s', + '--subio', + default='./scripts/subgraphs_ios.txt', + help="set subgraphs input/output node information") + arg_parser.add_argument('-m', + '--model', + default='./resnet-test.onnx', + help="set onnx model path") + args = arg_parser.parse_args() + + split_onnx_ios(args.subio, args.model) From 21eb4e662d649c05a5314f6c34617878b79e57e3 Mon Sep 17 00:00:00 2001 From: chenyx113 Date: Thu, 20 Feb 2025 14:01:01 +0800 Subject: [PATCH 3/3] remove duplicated code remove duplicated code --- tools/onnx_subgraph/extract_onnx.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/onnx_subgraph/extract_onnx.py b/tools/onnx_subgraph/extract_onnx.py index e13649e418a..4204901155b 100644 --- a/tools/onnx_subgraph/extract_onnx.py +++ b/tools/onnx_subgraph/extract_onnx.py @@ -42,9 +42,6 @@ def split_onnx_ios(instrfile, input_path, out_folder='subgraphs/'): npu_count = 0 count = 0 - if not os.path.exists(out_folder): - os.makedirs(out_folder) - for line in lines: input_names, output_names, type = split_subgraph_ios(line) if (type == 'CPU'):