Repository navigation
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24219
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 New FailureAs of commit 0e62872 with merge base 0549e1e ( NEW FAILURE - The following job has failed:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@billmguo has exported this pull request. If you are a Meta employee, you can view the originating Diff in D127875036. |
This PR needs a
|
…rch#24219) Summary: `XNNExecutor::prepare_args` reshapes every external input and calls `xnn_reshape_runtime` on every execute, which re-runs each operator's reshape and re-plans memory even when no shape changed. Models built from many small XNNPACK partitions pay this per partition per call. In the Phoenix CARMM body synthesizer (38 XNNPACK delegates), a simpleperf profile of HandBodyReplay puts `prepare_args` at 7.8% of per-frame CPU, 5.7% of it inside `xnn_reshape_runtime`, versus 14.3% for the delegates' actual compute. prepare_args now collects each input's rank and dims and reshapes only when they differ from the last successful reshape (or the runtime was never reshaped). Input shapes are the whole reshape input: the runtime partitions work for the pthreadpool it was created with (`xnn_create_runtime_v4`), whose size cannot change; `UseNThreadsThreadPoolGuard` only limits threads per dispatch. This is safe because XNNPACK re-binds every data pointer in `xnn_setup_runtime_v2`, and when one runtime grows a shared workspace it rebases the value and op-workspace pointers of all runtimes sharing it (`runtime.c`). Two things captured at reshape are reused across skipped calls: per-thread scratch sized from that fixed pool, and the packed-weights address looked up from the weights cache, whose slots are only appended or cleared on release (`XNNWeightsCache.cpp`). A failed reshape clears the flag, so the next call reshapes again. Output resizing is unchanged. Edited in both the xplat and fbcode copies, which are kept byte-identical. Differential Revision: D127875036
f132e12 to
0e62872
Compare
Summary:
XNNExecutor::prepare_argsreshapes every external input and callsxnn_reshape_runtimeon every execute, which re-runs each operator's reshape and re-plans memory even when no shape changed. Models built from many small XNNPACK partitions pay this per partition per call. In the Phoenix CARMM body synthesizer (38 XNNPACK delegates), a simpleperf profile of HandBodyReplay putsprepare_argsat 7.8% of per-frame CPU, 5.7% of it insidexnn_reshape_runtime, versus 14.3% for the delegates' actual compute.prepare_args now collects each input's rank and dims and reshapes only when they differ from the last successful reshape (or the runtime was never reshaped). Input shapes are the whole reshape input: the runtime partitions work for the pthreadpool it was created with (
xnn_create_runtime_v4), whose size cannot change;UseNThreadsThreadPoolGuardonly limits threads per dispatch. This is safe because XNNPACK re-binds every data pointer inxnn_setup_runtime_v2, and when one runtime grows a shared workspace it rebases the value and op-workspace pointers of all runtimes sharing it (runtime.c). Two things captured at reshape are reused across skipped calls: per-thread scratch sized from that fixed pool, and the packed-weights address looked up from the weights cache, whose slots are only appended or cleared on release (XNNWeightsCache.cpp). A failed reshape clears the flag, so the next call reshapes again. Output resizing is unchanged.Edited in both the xplat and fbcode copies, which are kept byte-identical.
Differential Revision: D127875036