Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions backends/qualcomm/qnn_preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ def preprocess_multimethod(

if len(py_op_wrapper_list) == len(edge_programs.values()):
qnn_context_binary = qnn_manager.Compile(graph_name, py_op_wrapper_list)
if option.saver:
# TODO: Currently, only the first method is saved. Update this logic if saving multiple methods becomes necessary in the future.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you share what it means?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider the scenario for lowering a multi-method pte:

When the saver option is enabled in QNN, the program is configured to not generate context binary. So, the condition len(qnn_context_binary) != 0 will be False. In this case, we hope the program can exit immediately before reaching the assertion checks. As a result, only the result for method_0 will be saved. If support for saving multi-method with option.saver=True is required in the future, this will need to be extended.

exit(
f"Record all QNN API calls from saver backend at: {option.saver_output_dir}"
)
assert (
len(qnn_context_binary) != 0
), "Failed to generate Qnn context binary."
Expand Down
32 changes: 32 additions & 0 deletions backends/qualcomm/tests/test_qnn_delegate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3384,6 +3384,38 @@ def test_qnn_backend_rewrite_prepared_observer(self):
quantized_module = convert_pt2e(prepared)
self.lower_module_and_test_output(quantized_module, sample_input)

def test_qnn_backend_saver_backend(self):
backend_options = generate_htp_compiler_spec(use_fp16=False)
TestQNN.compiler_specs = generate_qnn_executorch_compiler_spec(
soc_model=self.chipset_table[TestQNN.model],
backend_options=backend_options,
saver=True,
)
module = Relu() # noqa: F405
sample_input = (torch.randn([2, 5, 1, 3]),)
module = self.get_qdq_module(module, sample_input)

from executorch.backends.qualcomm.serialization.qc_schema_serialize import (
flatbuffer_to_option,
option_to_flatbuffer,
)

with tempfile.TemporaryDirectory() as tmp_dir:
option = flatbuffer_to_option(TestQNN.compiler_specs[0].value)
option.saver_output_dir = f"{tmp_dir}/saver_output"
TestQNN.compiler_specs[0].value = option_to_flatbuffer(option)

with self.assertRaises(SystemExit):
self.lower_module_and_test_output(module, sample_input)
self.assertTrue(
os.path.isfile(f"{tmp_dir}/saver_output/params.bin"),
"failed to find params.bin",
)
self.assertTrue(
os.path.isfile(f"{tmp_dir}/saver_output/saver_output.c"),
"failed to find saver_output.c",
)

def test_qnn_backend_skip_node_id_partitioner(self):
module = SimpleModel() # noqa: F405
sample_input = (torch.ones(1, 32, 28, 28), torch.ones(1, 32, 28, 28))
Expand Down
Loading