Repository navigation
Commit 558c071
authored
[XNNPACK] Keep NHWC across scalar and low-rank broadcast operands (#24183)
### Summary
Split out of #24113 at review request: that PR now only lowers
`upsample_nearest2d`, this one carries the
`ChannelsLastTaggedReshapePass` change.
Profiling the MI-GAN inpainting model (a conv encoder-decoder, fp16) on
XNNPACK showed about 25% of the run time spent in NCHW<->NHWC transposes
around elementwise ops whose second operand is a Python scalar or a
low-rank tensor. `ChannelsLastTaggedReshapePass` now keeps NHWC across
scalar and low-rank broadcast operands of
add/sub/mul/div/maximum/minimum:
- A single-element operand, such as a lifted Python scalar (the gain in
`x * 1.4142`), no longer takes part in the layout decision. Before, the
NHWC activation was transposed to NCHW for the multiply and back for the
next convolution. The same filter is used by the re-converge loop from
#20376.
- A rank < 4 constant operand that broadcasts over the trailing dims (a
`[H, W]` noise map added to `[N, C, H, W]`, or a `[C, 1, 1]` scale) is
reshaped to 4D in the exported program and laid out as NHWC at
serialization, so it costs nothing at inference. For this,
`BroadcastBinaryConfig` delegates such a constant with the op, so it is
serialized as constant data. Only constants the pass can fold are pulled
in: non-mutated, static-shape, rank < 4, more than one element. A
mutated buffer or a 4D constant stays a delegate input, as on `main`. A
non-constant operand, or a constant shared by several ops, is reshaped
with a `view_copy` and converted in the graph, instead of dragging the
activation to NCHW.
- Dequantized operands are left at their own rank, because a view
between the dequantize and the op would carry no quant params. In qs8
graphs they take the existing NCHW path.
- A single-element operand of rank > 4 would make the op output rank >
4, which cannot be NHWC, so it takes part in the layout decision and the
op takes the NCHW path.
- Operands with symbolic dims also keep the NCHW path, because
`XNNStaticReshape` cannot express their shape. This covers the
dynamic-shape `conv_out + y` case with `y` of shape `[H, W]` or `[C, H,
W]` reported on #24113, which lowers again as it does on `main`.
Measured on MI-GAN 256/512 fp16 with the host runtime, together with the
`upsample_nearest2d` lowering from #24113, on an ExecuTorch 1.4.1-based
branch: layout conversions per forward went from 128 to 26, the
delegated share of run time from 87/82% to 98/95%, and `Method::execute`
dropped by 29%/28%. The output was unchanged (max abs diff 2e-3, fp16
noise). These numbers were taken before the constants were folded ahead
of time, when each of them still cost a reshape and a transpose per
forward.
Review order: `channels_last_tagged_reshape_pass.py`, then
`is_foldable_broadcast_operand` in `utils/utils.py` and
`BroadcastBinaryConfig` in `generic_node_configs.py`, then the tests.
### Test plan
Tested on macOS arm64 with locally built pybindings.
New tests in
`backends/xnnpack/test/passes/test_channels_last_tagged_reshape.py`
cover a scalar operand, a 5D single-element operand, `[H, W]`, `[C, 1,
1]` and `[C, H, W]` constants, a lower-rank left operand, a constant
shared by two ops, a `[H, W]` graph input, qs8 lower-rank operands that
keep their rank, a `[H, W]` operand with dynamic H and W that falls back
to NCHW and runs at a second input size, every kind of constant
(persistent and non-persistent buffer, parameter, lifted tensor), the
scalar and lower-rank operand of all six ops, a mutated buffer operand,
a 4D constant operand and a constant shared with a non-delegated op.
Each static case also runs through `to_edge_transform_and_lower`,
`to_executorch`, `serialize` and the runtime, and checks the serialized
XNNPACK graph for the expected transposes and reshapes.
```bash
python -m pytest backends/xnnpack/test/passes/test_channels_last_tagged_reshape.py backends/xnnpack/test/passes/test_remove_redundant_copy_pass.py backends/xnnpack/test/ops/test_{add,sub,multiply,div,maximum,minimum}.py backends/xnnpack/test/test_xnnpack_partitioner.py
# 77 passed
```
`lintrunner` reports no issues on the changed files.
cc @GregoryComer @digantdesai @cbilgin @JakeStevens @nil-is-all1 parent c8220d9 commit 558c071
4 files changed
Lines changed: 786 additions & 32 deletions
File tree
- backends/xnnpack
- _passes
- partition/config
- test/passes
- utils
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
22 | | - | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
23 | 29 | | |
24 | 30 | | |
| 31 | + | |
25 | 32 | | |
26 | 33 | | |
27 | 34 | | |
| |||
77 | 84 | | |
78 | 85 | | |
79 | 86 | | |
80 | | - | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
81 | 90 | | |
82 | 91 | | |
83 | 92 | | |
| |||
87 | 96 | | |
88 | 97 | | |
89 | 98 | | |
| 99 | + | |
| 100 | + | |
90 | 101 | | |
91 | 102 | | |
92 | 103 | | |
| |||
174 | 185 | | |
175 | 186 | | |
176 | 187 | | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
177 | 318 | | |
178 | 319 | | |
179 | 320 | | |
| |||
571 | 712 | | |
572 | 713 | | |
573 | 714 | | |
| 715 | + | |
574 | 716 | | |
575 | 717 | | |
576 | | - | |
| 718 | + | |
577 | 719 | | |
578 | | - | |
| 720 | + | |
579 | 721 | | |
580 | 722 | | |
581 | 723 | | |
582 | 724 | | |
583 | 725 | | |
584 | 726 | | |
585 | | - | |
586 | | - | |
587 | | - | |
588 | | - | |
589 | | - | |
590 | | - | |
591 | | - | |
592 | | - | |
593 | | - | |
594 | | - | |
595 | | - | |
596 | | - | |
| 727 | + | |
597 | 728 | | |
598 | 729 | | |
599 | 730 | | |
| |||
616 | 747 | | |
617 | 748 | | |
618 | 749 | | |
619 | | - | |
| 750 | + | |
620 | 751 | | |
621 | 752 | | |
622 | 753 | | |
| |||
625 | 756 | | |
626 | 757 | | |
627 | 758 | | |
628 | | - | |
629 | | - | |
630 | | - | |
631 | | - | |
632 | | - | |
633 | | - | |
634 | | - | |
635 | | - | |
636 | | - | |
| 759 | + | |
637 | 760 | | |
638 | 761 | | |
639 | 762 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
166 | 167 | | |
167 | 168 | | |
168 | 169 | | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
169 | 189 | | |
170 | 190 | | |
171 | 191 | | |
| |||
197 | 217 | | |
198 | 218 | | |
199 | 219 | | |
200 | | - | |
| 220 | + | |
201 | 221 | | |
202 | 222 | | |
203 | 223 | | |
| |||
342 | 362 | | |
343 | 363 | | |
344 | 364 | | |
345 | | - | |
| 365 | + | |
346 | 366 | | |
347 | 367 | | |
348 | 368 | | |
| |||
448 | 468 | | |
449 | 469 | | |
450 | 470 | | |
451 | | - | |
| 471 | + | |
452 | 472 | | |
453 | 473 | | |
454 | 474 | | |
455 | 475 | | |
456 | 476 | | |
457 | 477 | | |
458 | | - | |
| 478 | + | |
459 | 479 | | |
460 | 480 | | |
461 | 481 | | |
| |||
730 | 750 | | |
731 | 751 | | |
732 | 752 | | |
733 | | - | |
| 753 | + | |
734 | 754 | | |
735 | 755 | | |
736 | 756 | | |
| |||
864 | 884 | | |
865 | 885 | | |
866 | 886 | | |
867 | | - | |
| 887 | + | |
868 | 888 | | |
869 | 889 | | |
870 | 890 | | |
| |||
0 commit comments