From 79bb43f7cce5ea4bd5807f3856210f5784d8aa14 Mon Sep 17 00:00:00 2001 From: HonestDeng <2958906959@qq.com> Date: Sun, 6 Apr 2025 20:26:33 +0800 Subject: [PATCH 1/3] generate etrecord and bundle program --- devtools/test/test_end2end.py | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 devtools/test/test_end2end.py diff --git a/devtools/test/test_end2end.py b/devtools/test/test_end2end.py new file mode 100644 index 00000000000..037add15ccb --- /dev/null +++ b/devtools/test/test_end2end.py @@ -0,0 +1,83 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + +# pyre-unsafe + +import copy +import os +import shutil +import tempfile +import unittest + +import torch +from executorch.devtools import BundledProgram +from executorch.devtools.etrecord import generate_etrecord, parse_etrecord +from executorch.devtools.inspector import Inspector +from executorch.exir import EdgeCompileConfig, EdgeProgramManager, to_edge +from executorch.exir.capture._config import CaptureConfig +from executorch.exir.program import ExecutorchProgram +from torch.export import export, ExportedProgram +from executorch.devtools.bundled_program.config import MethodTestCase, MethodTestSuite +from executorch.devtools.bundled_program.serialize import ( + serialize_from_bundled_program_to_flatbuffer, +) + +# 定义一个简单的模型用于测试 +class SimpleAddModel(torch.nn.Module): + def __init__(self): + super().__init__() + + def forward(self, x, y): + return x + y + + +class TestDevtoolsEndToEnd(unittest.TestCase): + def setUp(self): + self.tmp_dir = tempfile.mkdtemp() + self.etrecord_path = os.path.join(self.tmp_dir, "etrecord.bin") + self.etdump_path = os.path.join(self.tmp_dir, "etdump.bin") + + self.model = SimpleAddModel() + + def tearDown(self): + shutil.rmtree(self.tmp_dir) + + def generate_etrecord(self): + aten_model: ExportedProgram = export( + self.model, + (torch.randn(1, 1, 32, 32),), + ) + edge_program_manager = to_edge( + aten_model, + compile_config=EdgeCompileConfig( + _use_edge_ops=False, + _check_ir_validity=False, + ), + ) + edge_program_manager_copy = copy.deepcopy(edge_program_manager) + et_program_manager = edge_program_manager.to_executorch() + + generate_etrecord(self.etrecord_path, edge_program_manager_copy, et_program_manager) + + def generate_bundled_program(self): + method_name = "forward" + method_graphs = {method_name: export(self.model, (torch.randn(1, 1, 32, 32),))} + + inputs = [torch.randn(1, 1, 32, 32)] + method_test_suites = [ + MethodTestSuite( + method_name=method_name, + test_cases=[MethodTestCase(inputs=inp, expected_outputs=self.model(inp)) for inp in inputs], + ) + ] + + executorch_program = to_edge(method_graphs).to_executorch() + bundled_program = BundledProgram( + executorch_program=executorch_program, + method_test_suites=method_test_suites, + ) + + return bundled_program \ No newline at end of file From e449350886a8bdb18f7f95184e05cb83735dec9f Mon Sep 17 00:00:00 2001 From: HonestDeng <2958906959@qq.com> Date: Tue, 8 Apr 2025 18:42:46 +0800 Subject: [PATCH 2/3] add generate_etdump --- devtools/test/test_end2end.py | 51 ++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/devtools/test/test_end2end.py b/devtools/test/test_end2end.py index 037add15ccb..3f67318fabb 100644 --- a/devtools/test/test_end2end.py +++ b/devtools/test/test_end2end.py @@ -24,6 +24,10 @@ from executorch.devtools.bundled_program.serialize import ( serialize_from_bundled_program_to_flatbuffer, ) +from executorch.extension.pybindings.portable_lib import ( + _load_for_executorch_from_bundled_program, + _load_bundled_program_from_buffer +) # 定义一个简单的模型用于测试 class SimpleAddModel(torch.nn.Module): @@ -34,9 +38,9 @@ def forward(self, x, y): return x + y -class TestDevtoolsEndToEnd(unittest.TestCase): - def setUp(self): - self.tmp_dir = tempfile.mkdtemp() +class TestDevtoolsEndToEnd(): + def __init__(self): + self.tmp_dir = "./" self.etrecord_path = os.path.join(self.tmp_dir, "etrecord.bin") self.etdump_path = os.path.join(self.tmp_dir, "etdump.bin") @@ -45,10 +49,10 @@ def setUp(self): def tearDown(self): shutil.rmtree(self.tmp_dir) - def generate_etrecord(self): + def generate_etrecord_(self): aten_model: ExportedProgram = export( self.model, - (torch.randn(1, 1, 32, 32),), + (torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32)), ) edge_program_manager = to_edge( aten_model, @@ -64,13 +68,13 @@ def generate_etrecord(self): def generate_bundled_program(self): method_name = "forward" - method_graphs = {method_name: export(self.model, (torch.randn(1, 1, 32, 32),))} + method_graphs = {method_name: export(self.model, (torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32)))} - inputs = [torch.randn(1, 1, 32, 32)] + inputs = [(torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32))] method_test_suites = [ MethodTestSuite( method_name=method_name, - test_cases=[MethodTestCase(inputs=inp, expected_outputs=self.model(inp)) for inp in inputs], + test_cases=[MethodTestCase(inputs=inp, expected_outputs=self.model(*inp)) for inp in inputs], ) ] @@ -80,4 +84,33 @@ def generate_bundled_program(self): method_test_suites=method_test_suites, ) - return bundled_program \ No newline at end of file + return bundled_program + + def generate_etdump(self): + bundled_program_py = self.generate_bundled_program() + + bundled_program_bytes = serialize_from_bundled_program_to_flatbuffer( + bundled_program_py + ) + + bundled_program_cpp = _load_bundled_program_from_buffer(bundled_program_bytes) + + program = _load_for_executorch_from_bundled_program( + bundled_program_cpp, + enable_etdump=True + ) + + example_inputs = (torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32)) + program.forward(example_inputs) + + program.write_etdump_result_to_file(self.etdump_path) + + def test_profile(self): + pass + + +if __name__ == "__main__": + tester = TestDevtoolsEndToEnd() + tester.generate_etrecord_() + tester.generate_bundled_program() + tester.generate_etdump() \ No newline at end of file From 8dcba7417440d13970ec240376f4c720cd2b2f7b Mon Sep 17 00:00:00 2001 From: HonestDeng <2958906959@qq.com> Date: Fri, 18 Apr 2025 16:48:21 +0800 Subject: [PATCH 3/3] use _load_for_executorch_from_buffer instead --- devtools/test/test_end2end.py | 49 +++++++---------------------------- 1 file changed, 9 insertions(+), 40 deletions(-) diff --git a/devtools/test/test_end2end.py b/devtools/test/test_end2end.py index 3f67318fabb..ec5d5758a8a 100644 --- a/devtools/test/test_end2end.py +++ b/devtools/test/test_end2end.py @@ -25,11 +25,9 @@ serialize_from_bundled_program_to_flatbuffer, ) from executorch.extension.pybindings.portable_lib import ( - _load_for_executorch_from_bundled_program, - _load_bundled_program_from_buffer + _load_for_executorch_from_buffer, ) -# 定义一个简单的模型用于测试 class SimpleAddModel(torch.nn.Module): def __init__(self): super().__init__() @@ -43,6 +41,7 @@ def __init__(self): self.tmp_dir = "./" self.etrecord_path = os.path.join(self.tmp_dir, "etrecord.bin") self.etdump_path = os.path.join(self.tmp_dir, "etdump.bin") + self.et_program_manager = None self.model = SimpleAddModel() @@ -64,45 +63,16 @@ def generate_etrecord_(self): edge_program_manager_copy = copy.deepcopy(edge_program_manager) et_program_manager = edge_program_manager.to_executorch() - generate_etrecord(self.etrecord_path, edge_program_manager_copy, et_program_manager) - - def generate_bundled_program(self): - method_name = "forward" - method_graphs = {method_name: export(self.model, (torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32)))} - - inputs = [(torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32))] - method_test_suites = [ - MethodTestSuite( - method_name=method_name, - test_cases=[MethodTestCase(inputs=inp, expected_outputs=self.model(*inp)) for inp in inputs], - ) - ] - - executorch_program = to_edge(method_graphs).to_executorch() - bundled_program = BundledProgram( - executorch_program=executorch_program, - method_test_suites=method_test_suites, - ) + self.et_program_manager = et_program_manager - return bundled_program + generate_etrecord(self.etrecord_path, edge_program_manager_copy, et_program_manager) def generate_etdump(self): - bundled_program_py = self.generate_bundled_program() - - bundled_program_bytes = serialize_from_bundled_program_to_flatbuffer( - bundled_program_py - ) - - bundled_program_cpp = _load_bundled_program_from_buffer(bundled_program_bytes) - - program = _load_for_executorch_from_bundled_program( - bundled_program_cpp, - enable_etdump=True - ) - - example_inputs = (torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32)) - program.forward(example_inputs) - + # load executorch program from buffer, and set enable_etdump to True + program = _load_for_executorch_from_buffer(self.et_program_manager.buffer, enable_etdump=True) + # run program with example inputs to generate etdump + program.forward((torch.randn(1, 1, 32, 32), torch.randn(1, 1, 32, 32))) + # write etdump to file program.write_etdump_result_to_file(self.etdump_path) def test_profile(self): @@ -112,5 +82,4 @@ def test_profile(self): if __name__ == "__main__": tester = TestDevtoolsEndToEnd() tester.generate_etrecord_() - tester.generate_bundled_program() tester.generate_etdump() \ No newline at end of file