Skip to content

Commit 01c49fd

Browse files
committed
Update on "[et] generate debug handle before opeartor decomposition"
This diff update the debug handle generation, from each node in the edge program having a individual debug handle, to all nodes having a same ancestor in export graph sharing a same debug handle, which update the start point of tracing our node transformation from edge graph to exported graph. Differential Revision: [D76860368](https://our.internmc.facebook.com/intern/diff/D76860368/) [ghstack-poisoned]
2 parents b51110f + fe99951 commit 01c49fd

File tree

37 files changed

+1414
-223
lines changed

37 files changed

+1414
-223
lines changed

.ci/scripts/test_model.sh

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,22 @@ test_model_with_qnn() {
188188
EXPORT_SCRIPT=edsr
189189
# Additional deps for edsr
190190
pip install piq
191+
elif [[ "${MODEL_NAME}" == "cvt" ]]; then
192+
EXPORT_SCRIPT=cvt
193+
elif [[ "${MODEL_NAME}" == "dit" ]]; then
194+
EXPORT_SCRIPT=dit
195+
elif [[ "${MODEL_NAME}" == "efficientnet" ]]; then
196+
EXPORT_SCRIPT=efficientnet
197+
elif [[ "${MODEL_NAME}" == "focalnet" ]]; then
198+
EXPORT_SCRIPT=focalnet
199+
elif [[ "${MODEL_NAME}" == "mobilevit_v1" ]]; then
200+
EXPORT_SCRIPT=mobilevit_v1
201+
elif [[ "${MODEL_NAME}" == "mobilevit_v2" ]]; then
202+
EXPORT_SCRIPT=mobilevit_v2
203+
elif [[ "${MODEL_NAME}" == "pvt" ]]; then
204+
EXPORT_SCRIPT=pvt
205+
elif [[ "${MODEL_NAME}" == "swin" ]]; then
206+
EXPORT_SCRIPT=swin_transformer
191207
elif [[ "${MODEL_NAME}" == "albert" ]]; then
192208
EXPORT_SCRIPT=albert
193209
elif [[ "${MODEL_NAME}" == "bert" ]]; then
@@ -196,6 +212,8 @@ test_model_with_qnn() {
196212
EXPORT_SCRIPT=distilbert
197213
elif [[ "${MODEL_NAME}" == "eurobert" ]]; then
198214
EXPORT_SCRIPT=eurobert
215+
elif [[ "${MODEL_NAME}" == "roberta" ]]; then
216+
EXPORT_SCRIPT=roberta
199217
else
200218
echo "Unsupported model $MODEL_NAME"
201219
exit 1
@@ -210,10 +228,13 @@ test_model_with_qnn() {
210228
"dl3"|"mv3"|"mv2"|"ic4"|"ic3"|"vit"|"mb"|"w2l")
211229
SCRIPT_FOLDER=scripts
212230
;;
213-
"albert"|"bert"|"distilbert")
231+
"cvt"|"dit"|"focalnet"|"mobilevit_v2"|"pvt"|"swin")
232+
SCRIPT_FOLDER=oss_scripts
233+
;;
234+
"albert"|"bert"|"distilbert"|"roberta"|"efficientnet"|"mobilevit_v1")
214235
pip install evaluate
215236
SCRIPT_FOLDER=oss_scripts
216-
# Bert models running in 16bit will encounter op validation fail on some operations,
237+
# 16bit models will encounter op validation fail on some operations,
217238
# which requires CHIPSET >= SM8550.
218239
QNN_CHIPSET=SM8550
219240
;;

.github/workflows/apple.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
id: set_version
4040
shell: bash
4141
run: |
42-
VERSION="0.7.0.$(TZ='PST8PDT' date +%Y%m%d)"
42+
VERSION="0.8.0.$(TZ='PST8PDT' date +%Y%m%d)"
4343
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
4444
4545
build-demo-ios:

.github/workflows/trunk.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ jobs:
470470
docker-image: executorch-ubuntu-22.04-qnn-sdk
471471
submodules: 'recursive'
472472
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
473-
timeout: 900
473+
timeout: 90
474474
script: |
475475
# The generic Linux job chooses to use base env, not the one setup by the image
476476
CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]")
@@ -489,14 +489,14 @@ jobs:
489489
strategy:
490490
matrix:
491491
dtype: [fp32]
492-
model: [albert, bert, distilbert] # eurobert requires transfomer >= 4.48.0, skip for now
492+
model: [cvt, dit, efficientnet, focalnet, mobilevit_v1, mobilevit_v2, pvt, swin, albert, bert, distilbert, roberta] # eurobert requires transfomer >= 4.48.0, skip for now
493493
fail-fast: false
494494
with:
495495
runner: linux.2xlarge
496496
docker-image: executorch-ubuntu-22.04-qnn-sdk
497497
submodules: 'recursive'
498498
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
499-
timeout: 900
499+
timeout: 90
500500
script: |
501501
# The generic Linux job chooses to use base env, not the one setup by the image
502502
CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]")

backends/arm/test/test_arm_baremetal.sh

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,32 @@ all() { # Run all tests
7373
test_pytest_ops() { # Test ops and other things
7474
echo "${TEST_SUITE_NAME}: Run pytest"
7575

76+
# Make sure to not run this tests on FVP by removing the elf builds,
77+
# as they are detected by the unit tests and used if they exists
78+
rm -Rf arm_test/arm_semihosting_executor_runner_corstone-300
79+
rm -Rf arm_test/arm_semihosting_executor_runner_corstone-320
80+
7681
# Prepare for pytest
7782
backends/arm/scripts/build_executorch.sh
7883

7984
# Run arm baremetal pytest tests without FVP
80-
pytest --verbose --color=yes --numprocesses=auto backends/arm/test/ --ignore=backends/arm/test/models
85+
pytest --verbose --color=yes --numprocesses=auto --durations=10 backends/arm/test/ --ignore=backends/arm/test/models
8186
echo "${TEST_SUITE_NAME}: PASS"
8287
}
8388

8489
test_pytest_models() { # Test ops and other things
8590
echo "${TEST_SUITE_NAME}: Run pytest"
8691

92+
# Make sure to not run this tests on FVP by removing the elf builds,
93+
# as they are detected by the unit tests and used if they exists
94+
rm -Rf arm_test/arm_semihosting_executor_runner_corstone-300
95+
rm -Rf arm_test/arm_semihosting_executor_runner_corstone-320
96+
8797
# Prepare for pytest
8898
backends/arm/scripts/build_executorch.sh
8999

90100
# Run arm baremetal pytest tests without FVP
91-
pytest --verbose --color=yes backends/arm/test/models
101+
pytest --verbose --color=yes --durations=0 backends/arm/test/models
92102
echo "${TEST_SUITE_NAME}: PASS"
93103
}
94104

@@ -105,11 +115,13 @@ test_pytest_ops_ethosu_fvp() { # Same as test_pytest but also sometime verify us
105115
# Prepare Corstone-3x0 FVP for pytest
106116
backends/arm/scripts/build_executorch.sh
107117
backends/arm/scripts/build_portable_kernels.sh
108-
# Build semihosting version of the runner used by pytest testing when
118+
# Build semihosting version of the runner used by pytest testing. This builds:
119+
# arm_test/arm_semihosting_executor_runner_corstone-300
120+
# arm_test/arm_semihosting_executor_runner_corstone-320
109121
backends/arm/test/setup_testing.sh
110122

111123
# Run arm baremetal pytest tests with FVP
112-
pytest --verbose --color=yes --numprocesses=auto backends/arm/test/ --ignore=backends/arm/test/models
124+
pytest --verbose --color=yes --numprocesses=auto --durations=10 backends/arm/test/ --ignore=backends/arm/test/models
113125
echo "${TEST_SUITE_NAME}: PASS"
114126
}
115127

@@ -119,11 +131,13 @@ test_pytest_models_ethosu_fvp() { # Same as test_pytest but also sometime verify
119131
# Prepare Corstone-3x0 FVP for pytest
120132
backends/arm/scripts/build_executorch.sh
121133
backends/arm/scripts/build_portable_kernels.sh
122-
# Build semihosting version of the runner used by pytest testing
134+
# Build semihosting version of the runner used by pytest testing. This builds:
135+
# arm_test/arm_semihosting_executor_runner_corstone-300
136+
# arm_test/arm_semihosting_executor_runner_corstone-320
123137
backends/arm/test/setup_testing.sh
124138

125139
# Run arm baremetal pytest tests with FVP
126-
pytest --verbose --color=yes backends/arm/test/models
140+
pytest --verbose --color=yes --durations=0 backends/arm/test/models
127141
echo "${TEST_SUITE_NAME}: PASS"
128142
}
129143

backends/arm/test/test_model.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import subprocess
99
import sys
10+
import time
1011

1112

1213
def get_args():
@@ -199,12 +200,17 @@ def run_elf_with_fvp(script_path: str, elf_file: str, target: str, timeout: int)
199200

200201

201202
if __name__ == "__main__":
202-
203+
total_start_time = time.perf_counter()
203204
args = get_args()
204205
script_path = os.path.join("backends", "arm", "scripts")
205206

206207
if args.build_libs:
208+
start_time = time.perf_counter()
207209
build_libs(args.test_output, script_path)
210+
end_time = time.perf_counter()
211+
print(
212+
f"[Test model: {end_time - start_time:.2f} s] Build needed executorch libs"
213+
)
208214

209215
if args.model:
210216
model_name = args.model.split(" ")[0].split(";")[0]
@@ -217,6 +223,7 @@ def run_elf_with_fvp(script_path: str, elf_file: str, target: str, timeout: int)
217223
args.test_output, f"{model_name}_arm_delegate_{args.target}"
218224
)
219225

226+
start_time = time.perf_counter()
220227
pte_file = build_pte(
221228
args.test_output,
222229
model_name,
@@ -226,13 +233,17 @@ def run_elf_with_fvp(script_path: str, elf_file: str, target: str, timeout: int)
226233
output,
227234
args.no_intermediate,
228235
)
229-
print(f"PTE file created: {pte_file} ")
236+
end_time = time.perf_counter()
237+
print(
238+
f"[Test model: {end_time - start_time:.2f} s] PTE file created: {pte_file}"
239+
)
230240

231241
if "ethos-u" in args.target:
232242
elf_build_path = os.path.join(
233243
output, f"{model_name}_arm_delegate_{args.target}"
234244
)
235245

246+
start_time = time.perf_counter()
236247
elf_file = build_ethosu_runtime(
237248
args.test_output,
238249
script_path,
@@ -243,7 +254,18 @@ def run_elf_with_fvp(script_path: str, elf_file: str, target: str, timeout: int)
243254
args.extra_flags,
244255
elf_build_path,
245256
)
246-
print(f"ELF file created: {elf_file} ")
257+
end_time = time.perf_counter()
258+
print(
259+
f"[Test model: {end_time - start_time:.2f} s] ELF file created: {elf_file}"
260+
)
247261

262+
start_time = time.perf_counter()
248263
run_elf_with_fvp(script_path, elf_file, args.target, args.timeout)
249-
print(f"Model: {model_name} on {args.target} -> PASS")
264+
end_time = time.perf_counter()
265+
print(
266+
f"[Test model: {end_time - start_time:.2f} s] Tested elf on FVP {elf_file}"
267+
)
268+
total_end_time = time.perf_counter()
269+
print(
270+
f"[Test model: {total_end_time - total_start_time:.2f} s total] Model: {model_name} on {args.target} -> PASS"
271+
)

backends/qualcomm/builders/op_slice_copy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def define_node(
5656
if start < 0:
5757
start = start % input_tensor.shape[dim]
5858

59-
if len(node.args) > 3:
59+
if len(node.args) > 3 and node.args[3] is not None:
6060
end = min(cast(int, node.args[3]), input_tensor.shape[dim])
6161
if end < 0:
6262
end = end % input_tensor.shape[dim]

backends/qualcomm/quantizer/custom_annotation.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,40 @@ def annotate_single_in_single_out(
227227
_annotated=True,
228228
)
229229

230+
def annotate_single_in_share_out(
231+
node: Node, quantization_config: QuantizationConfig
232+
) -> None:
233+
234+
input_qspec_map = {}
235+
input_act = node.args[0]
236+
input_qspec_map[input_act] = quantization_config.input_activation
237+
238+
node.meta[QUANT_ANNOTATION_KEY] = QuantizationAnnotation(
239+
input_qspec_map=input_qspec_map,
240+
output_qspec=SharedQuantizationSpec((input_act, node)),
241+
_annotated=True,
242+
)
243+
244+
def annotate_stack(node: Node, quantization_config: QuantizationConfig) -> None:
245+
input_nodes = node.args[0]
246+
247+
first_input_node = input_nodes[0]
248+
input_qspec_map = {}
249+
input_qspec_map[first_input_node] = quantization_config.input_activation
250+
share_qparams_with_input_act0_qspec = SharedQuantizationSpec(
251+
(first_input_node, node)
252+
)
253+
254+
for input_node in input_nodes[1:]:
255+
if input_node not in input_qspec_map:
256+
input_qspec_map[input_node] = share_qparams_with_input_act0_qspec
257+
258+
node.meta[QUANT_ANNOTATION_KEY] = QuantizationAnnotation(
259+
input_qspec_map=input_qspec_map,
260+
output_qspec=share_qparams_with_input_act0_qspec,
261+
_annotated=True,
262+
)
263+
230264
def annotate_matmul_input1(node: Node):
231265
quantization_config_8a8w = get_8a8w_qnn_ptq_config(
232266
act_symmetric=True, act_observer=MinMaxObserver
@@ -247,6 +281,12 @@ def annotate_matmul_input1(node: Node):
247281
]:
248282
annotate_single_in_single_out(node, quantization_config_8a8w)
249283
node = node.args[0]
284+
elif node.target == torch.ops.aten.stack.default:
285+
annotate_stack(node, quantization_config_8a8w)
286+
node = node.args[0]
287+
elif node.target == torch.ops.aten.flatten.using_ints:
288+
annotate_single_in_share_out(node, quantization_config_8a8w)
289+
node = node.args[0]
250290
elif node.target == torch.ops.aten.cat.default:
251291
annotate_cat(node, quantization_config_8a8w)
252292
# For v, we tag 8a until conv op.

backends/qualcomm/tests/test_qnn_delegate.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4585,14 +4585,13 @@ def test_gMLP(self):
45854585
self.assertGreaterEqual(msg["top_1"], 60)
45864586
self.assertGreaterEqual(msg["top_5"], 85)
45874587

4588-
@unittest.skip("Only outputs good accuracy in QNN 2.29")
4589-
def test_mobilevit_v2(self):
4588+
def test_mobilevit_v1(self):
45904589
if not self.required_envs([self.image_dataset]):
45914590
self.skipTest("missing required envs")
45924591

45934592
cmds = [
45944593
"python",
4595-
f"{self.executorch_root}/examples/qualcomm/oss_scripts/mobilevit_v2.py",
4594+
f"{self.executorch_root}/examples/qualcomm/oss_scripts/mobilevit_v1.py"
45964595
"--dataset",
45974596
self.image_dataset,
45984597
"--artifact",
@@ -4610,8 +4609,6 @@ def test_mobilevit_v2(self):
46104609
]
46114610
if self.host:
46124611
cmds.extend(["--host", self.host])
4613-
if self.shared_buffer:
4614-
cmds.extend(["--shared_buffer"])
46154612

46164613
p = subprocess.Popen(cmds, stdout=subprocess.DEVNULL)
46174614
with Listener((self.ip, self.port)) as listener:
@@ -4621,17 +4618,22 @@ def test_mobilevit_v2(self):
46214618
if "Error" in msg:
46224619
self.fail(msg["Error"])
46234620
else:
4624-
self.assertGreaterEqual(msg["top_1"], 50)
4621+
self.assertGreaterEqual(msg["top_1"], 70)
46254622
self.assertGreaterEqual(msg["top_5"], 85)
46264623

4627-
def test_pvt(self):
4624+
@unittest.skip("Only outputs good accuracy in QNN 2.29")
4625+
def test_mobilevit_v2(self):
46284626
if not self.required_envs([self.image_dataset]):
46294627
self.skipTest("missing required envs")
46304628

46314629
cmds = [
46324630
"python",
4633-
f"{self.executorch_root}/examples/qualcomm/oss_scripts/pvt.py",
4631+
f"{self.executorch_root}/examples/qualcomm/oss_scripts/mobilevit_v2.py",
4632+
"--dataset",
46344633
self.image_dataset,
4634+
"--artifact",
4635+
self.artifact_dir,
4636+
"--build_folder",
46354637
self.build_folder,
46364638
"--device",
46374639
self.device,
@@ -4644,6 +4646,8 @@ def test_pvt(self):
46444646
]
46454647
if self.host:
46464648
cmds.extend(["--host", self.host])
4649+
if self.shared_buffer:
4650+
cmds.extend(["--shared_buffer"])
46474651

46484652
p = subprocess.Popen(cmds, stdout=subprocess.DEVNULL)
46494653
with Listener((self.ip, self.port)) as listener:
@@ -4653,21 +4657,17 @@ def test_pvt(self):
46534657
if "Error" in msg:
46544658
self.fail(msg["Error"])
46554659
else:
4656-
self.assertGreaterEqual(msg["top_1"], 65)
4660+
self.assertGreaterEqual(msg["top_1"], 50)
46574661
self.assertGreaterEqual(msg["top_5"], 85)
46584662

4659-
def test_mobilevit1(self):
4663+
def test_pvt(self):
46604664
if not self.required_envs([self.image_dataset]):
46614665
self.skipTest("missing required envs")
46624666

46634667
cmds = [
46644668
"python",
4665-
f"{self.executorch_root}/examples/qualcomm/oss_scripts/mobilevit1.py"
4666-
"--dataset",
4669+
f"{self.executorch_root}/examples/qualcomm/oss_scripts/pvt.py",
46674670
self.image_dataset,
4668-
"--artifact",
4669-
self.artifact_dir,
4670-
"--build_folder",
46714671
self.build_folder,
46724672
"--device",
46734673
self.device,
@@ -4689,7 +4689,7 @@ def test_mobilevit1(self):
46894689
if "Error" in msg:
46904690
self.fail(msg["Error"])
46914691
else:
4692-
self.assertGreaterEqual(msg["top_1"], 70)
4692+
self.assertGreaterEqual(msg["top_1"], 65)
46934693
self.assertGreaterEqual(msg["top_5"], 85)
46944694

46954695
def test_regnet(self):

backends/xnnpack/quantizer/xnnpack_quantizer_utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,6 @@ def _do_annotate_conv(
271271

272272
# skip if transposed conv has more than 1 group
273273
skip = skip or (is_conv_transpose and num_groups != 1)
274-
print(f"{skip} conv transpose and num_groups")
275274

276275
if is_conv_transpose:
277276
# transposed convs per output channel quantization

0 commit comments

Comments
 (0)