Skip to content

Commit ba18a61

Browse files
committed
[FbNet enablement]
- Add test cases
1 parent 4111b3f commit ba18a61

File tree

5 files changed

+179
-4
lines changed

5 files changed

+179
-4
lines changed

backends/qualcomm/scripts/build.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ if [ "$BUILD_AARCH64" = true ]; then
7171
-DCMAKE_INSTALL_PREFIX=$BUILD_ROOT \
7272
-DEXECUTORCH_BUILD_QNN=ON \
7373
-DEXECUTORCH_BUILD_SDK=ON \
74-
-DFLATCC_TEST=OFF \
7574
-DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
7675
-DQNN_SDK_ROOT=$QNN_SDK_ROOT \
7776
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \

backends/qualcomm/tests/test_qnn_delegate.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,51 @@ def test_qnn_backend_shared_buffer(self):
12211221
)
12221222

12231223

1224+
class TestExampleOssScript(TestQNN):
1225+
def required_envs(self, conditions=None) -> bool:
1226+
conditions = [] if conditions is None else conditions
1227+
return all(
1228+
[
1229+
self.executorch_root,
1230+
self.artifact_dir,
1231+
*conditions,
1232+
]
1233+
)
1234+
1235+
def test_fbnet(self):
1236+
if not self.required_envs([self.image_dataset]):
1237+
self.skipTest("missing required envs")
1238+
1239+
cmds = [
1240+
"python",
1241+
f"{self.executorch_root}/examples/qualcomm/oss_scripts/fbnet.py",
1242+
"--dataset",
1243+
self.image_dataset,
1244+
"--artifact",
1245+
self.artifact_dir,
1246+
"--build_folder",
1247+
self.build_folder,
1248+
"--device",
1249+
self.device,
1250+
"--model",
1251+
self.model,
1252+
"--ip",
1253+
self.ip,
1254+
"--port",
1255+
str(self.port),
1256+
]
1257+
if self.host:
1258+
cmds.extend(["--host", self.host])
1259+
1260+
p = subprocess.Popen(cmds, stdout=subprocess.DEVNULL)
1261+
with Listener((self.ip, self.port)) as listener:
1262+
conn = listener.accept()
1263+
p.communicate()
1264+
msg = json.loads(conn.recv())
1265+
self.assertGreaterEqual(msg["top_1"], 60)
1266+
self.assertGreaterEqual(msg["top_5"], 90)
1267+
1268+
12241269
class TestExampleScript(TestQNN):
12251270
def required_envs(self, conditions=None) -> bool:
12261271
conditions = [] if conditions is None else conditions

build/executorch-config.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ set_target_properties(
3636
target_include_directories(portable_kernels INTERFACE ${_root})
3737

3838
if(CMAKE_BUILD_TYPE MATCHES "Debug")
39-
set(FLATCC_LIB flatcc_d)
39+
set(FLATCCRT_LIB flatccrt_d)
4040
else()
41-
set(FLATCC_LIB flatcc)
41+
set(FLATCCRT_LIB flatccrt)
4242
endif()
4343

4444
set(lib_list
45-
etdump bundled_program extension_data_loader ${FLATCC_LIB} mpsdelegate
45+
etdump bundled_program extension_data_loader ${FLATCCRT_LIB} mpsdelegate
4646
qnn_executorch_backend portable_ops_lib extension_module xnnpack_backend
4747
XNNPACK cpuinfo pthreadpool vulkan_backend optimized_kernels
4848
optimized_ops_lib optimized_native_cpu_ops_lib
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
import json
8+
import os
9+
import re
10+
import sys
11+
from multiprocessing.connection import Client
12+
13+
import numpy as np
14+
import timm
15+
from executorch.examples.qualcomm.scripts.inception_v4 import (
16+
get_dataset
17+
)
18+
from executorch.backends.qualcomm.quantizer.quantizer import QuantDtype
19+
from executorch.examples.qualcomm.scripts.utils import (
20+
build_executorch_binary,
21+
make_output_dir,
22+
setup_common_args_and_variables,
23+
SimpleADB,
24+
topk_accuracy,
25+
)
26+
27+
28+
if __name__ == "__main__":
29+
parser = setup_common_args_and_variables()
30+
parser.add_argument(
31+
"-a",
32+
"--artifact",
33+
help="path for storing generated artifacts by this example. Default ./fbnet",
34+
default="./fbnet",
35+
type=str,
36+
)
37+
38+
parser.add_argument(
39+
"-d",
40+
"--dataset",
41+
help=(
42+
"path to the validation folder of ImageNet dataset. "
43+
"e.g. --dataset imagenet-mini/val "
44+
"for https://www.kaggle.com/datasets/ifigotin/imagenetmini-1000)"
45+
),
46+
type=str,
47+
required=True,
48+
)
49+
50+
args = parser.parse_args()
51+
52+
if not args.compile_only and args.device is None:
53+
raise RuntimeError(
54+
"device serial is required if not compile only. "
55+
"Please specify a device serial by -s/--device argument."
56+
)
57+
58+
# ensure the working directory exist.
59+
os.makedirs(args.artifact, exist_ok=True)
60+
61+
instance = timm.create_model('fbnetc_100', pretrained=True).eval()
62+
63+
data_num = 100
64+
inputs, targets, input_list = get_dataset(
65+
dataset_path=f"{args.dataset}",
66+
data_size=data_num,
67+
)
68+
69+
pte_filename = "fbnet"
70+
71+
build_executorch_binary(
72+
instance,
73+
inputs[0],
74+
args.model,
75+
f"{args.artifact}/{pte_filename}",
76+
inputs,
77+
quant_dtype=QuantDtype.use_8a8w,
78+
)
79+
80+
if args.compile_only:
81+
sys.exit(0)
82+
83+
adb = SimpleADB(
84+
qnn_sdk=os.getenv("QNN_SDK_ROOT"),
85+
artifact_path=f"{args.build_folder}",
86+
pte_path=f"{args.artifact}/{pte_filename}.pte",
87+
workspace=f"/data/local/tmp/executorch/{pte_filename}",
88+
device_id=args.device,
89+
host_id=args.host,
90+
soc_model=args.model,
91+
)
92+
adb.push(inputs=inputs, input_list=input_list)
93+
adb.execute()
94+
95+
# collect output data
96+
output_data_folder = f"{args.artifact}/outputs"
97+
make_output_dir(output_data_folder)
98+
99+
output_raws = []
100+
101+
def post_process():
102+
for f in sorted(
103+
os.listdir(output_data_folder), key=lambda f: int(f.split("_")[1])
104+
):
105+
filename = os.path.join(output_data_folder, f)
106+
if re.match(r"^output_[0-9]+_[1-9].raw$", f):
107+
os.remove(filename)
108+
else:
109+
output = np.fromfile(filename, dtype=np.float32)
110+
output_raws.append(output)
111+
112+
adb.pull(output_path=args.artifact, callback=post_process)
113+
114+
# top-k analysis
115+
predictions = []
116+
for i in range(data_num):
117+
predictions.append(
118+
np.fromfile(
119+
os.path.join(output_data_folder, f"output_{i}_0.raw"), dtype=np.float32
120+
)
121+
)
122+
123+
k_val = [1, 5]
124+
topk = [topk_accuracy(predictions, targets, k).item() for k in k_val]
125+
if args.ip and args.port != -1:
126+
with Client((args.ip, args.port)) as conn:
127+
conn.send(json.dumps({f"top_{k}": topk[i] for i, k in enumerate(k_val)}))
128+
else:
129+
for i, k in enumerate(k_val):
130+
print(f"top_{k}->{topk[i]}%")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pip install timm

0 commit comments

Comments
 (0)