Skip to content

Commit 4eb4265

Browse files
committed
Qualcomm AI Engine Direct - Update CLI tool to dump inference performace
1 parent be0cdee commit 4eb4265

3 files changed

Lines changed: 36 additions & 7 deletions

File tree

backends/qualcomm/tests/test_qnn_delegate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8311,6 +8311,7 @@ def test_cli(self):
83118311
cmds.extend(["--host", self.host])
83128312
subprocess.run(cmds, stdout=subprocess.DEVNULL)
83138313
self.assertTrue(os.path.isfile(f"{tmp_dir}/e_out/Result_0/output_0.pt"))
8314+
self.assertTrue(os.path.isfile(f"{tmp_dir}/e_out/performance.json"))
83148315

83158316
def test_cli_with_input_list_assignment(self):
83168317
with tempfile.TemporaryDirectory() as tmp_dir:
@@ -8379,11 +8380,10 @@ def test_cli_with_input_list_assignment(self):
83798380
"--input_list",
83808381
f"{tmp_dir}/input_list",
83818382
]
8382-
if self.host:
8383-
cmds.extend(["--host", self.host])
83848383
subprocess.run(cmds, stdout=subprocess.DEVNULL)
83858384
output_file = f"{tmp_dir}/e_out/Result_0/output_0.pt"
83868385
self.assertTrue(os.path.isfile(output_file))
8386+
self.assertTrue(os.path.isfile(f"{tmp_dir}/e_out/performance.json"))
83878387
device_output = torch.load(output_file, weights_only=True)
83888388
golden_output = ep.module()(sample_input, sample_input2)
83898389
self._assert_outputs_equal(golden_output, device_output)

examples/qualcomm/util_scripts/cli.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
# and executing models under various configuration flags.
99

1010
import argparse
11+
import csv
1112
import importlib
13+
import json
1214
import logging
1315
import os
1416
import re
@@ -37,6 +39,7 @@
3739
QNN_TENSOR_TYPE_MAP,
3840
to_edge_transform_and_lower_to_qnn,
3941
)
42+
from executorch.devtools import Inspector
4043
from executorch.examples.qualcomm.qaihub_scripts.utils.utils import preprocess_binary
4144
from executorch.examples.qualcomm.utils import (
4245
get_backend_type,
@@ -271,7 +274,13 @@ def execute(args):
271274
args.artifact,
272275
verification=Verification.Minimal,
273276
)
274-
input_order_func = program.load_method(INPUT_ORDER)
277+
try:
278+
input_order_func = program.load_method(INPUT_ORDER)
279+
except:
280+
logger.error(
281+
"Missing INPUT_ORDER in the .pte. The CLI execute command only supports .pte files generated by the CLI compile command, which preserves the input order."
282+
)
283+
exit(1)
275284
input_order = input_order_func.execute([])
276285

277286
# load input files
@@ -357,8 +366,27 @@ def post_process():
357366
)
358367
torch.save(output, f"{output_result_folder}/output_{output_index}.pt")
359368

369+
def post_process_etdump():
370+
etdump_path = f"{args.output_folder}/etdump.etdp"
371+
csv_path = f"{args.output_folder}/etdump.csv"
372+
json_path = f"{args.output_folder}/performance.json"
373+
inspector = Inspector(etdump_path=etdump_path)
374+
inspector.save_data_to_tsv(csv_path)
375+
# Create a list to hold the data
376+
data = []
377+
# Open the CSV file and read its contents
378+
with open(csv_path, encoding="utf-8") as csv_file:
379+
csv_reader = csv.DictReader(csv_file, delimiter="\t")
380+
# Convert each row into a dictionary and add it to the list
381+
for row in csv_reader:
382+
data.append(row)
383+
# Write the data to a JSON file
384+
with open(json_path, "w", encoding="utf-8") as json_file:
385+
json.dump(data, json_file, indent=4)
386+
360387
logger.info("collecting output data")
361-
adb.pull(tmp_dir, post_process)
388+
adb.pull(tmp_dir, callback=post_process)
389+
adb.pull_etdump(args.output_folder, callback=post_process_etdump)
362390
shutil.rmtree(tmp_dir)
363391
logger.info(f"execution finished, please check {args.output_folder} for results")
364392

examples/qualcomm/utils.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,15 @@ def _adb(self, cmd, output_callback: Optional[Callable[[str], None]] = None):
201201
)
202202
output_callback(result)
203203
else:
204-
subprocess.run(
204+
result = subprocess.run(
205205
cmds, stdout=subprocess.DEVNULL if self.error_only else sys.stdout
206206
)
207+
if result.returncode != 0:
208+
raise RuntimeError(f"adb command failed: {cmds}")
207209

208210
def push(
209211
self,
210212
inputs=None,
211-
input_list=None,
212213
files=None,
213214
backends: Optional[Set[QnnExecuTorchBackendType]] = None,
214215
init_env=True,
@@ -905,7 +906,7 @@ def setup_common_args_and_variables():
905906
"-H",
906907
"--host",
907908
help="hostname where android device is connected.",
908-
default=None,
909+
default="localhost",
909910
type=str,
910911
)
911912

0 commit comments

Comments
 (0)