Fuse consecutive clamps into a single clamp (#21013)#21013
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21013
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 New Failure, 1 Pending, 1 Unrelated Failure, 1 Unclassified FailureAs of commit 6da120a with merge base 0dec2b6 ( NEW FAILURE - The following job has failed:
UNCLASSIFIED FAILURE - DrCI could not classify the following job because the workflow did not run on the merge base. The failure may be pre-existing on trunk or introduced by this PR:
BROKEN TRUNK - The following job failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@apullin has exported this pull request. If you are a Meta employee, you can view the originating Diff in D112351522. |
This PR needs a
|
|
Can you fix up the lintrunner? Thanks! |
9b482ed to
f72666e
Compare
Summary: ConvertToClampPass normalizes hardtanh, relu and relu6 into aten.clamp. Chains like HardTanh -> ReLU therefore become two adjacent clamps, the second of which is redundant. Add FuseConsecutiveClampsPass, which folds any chain of adjacent (single-user) clamp.default ops into one clamp using exact composition: clamp(clamp(x,a,b),c,d) == clamp(x, max(a,c), min(b,d)). This subsumes HardTanh->ReLU, ReLU->ReLU, HardTanh->HardTanh, ReLU6->ReLU, explicit clamp->clamp, and longer chains, dropping one op (and one intermediate tensor) per fused pair. Runs after FoldAndAnnotateQParamsPass so it fires in both the FP and INT paths; in the quantized case the surviving clamp inherits the first clamp's input qparams and the second's output qparams, dropping the intermediate requant (qtol=1, same tradeoff as FuseConsecutiveRescalesPass). Branching clamps (multiple users) are left untouched. Differential Revision: D112351522
f72666e to
4a81b5a
Compare
Summary: ConvertToClampPass normalizes hardtanh, relu and relu6 into aten.clamp. Chains like HardTanh -> ReLU therefore become two adjacent clamps, the second of which is redundant. Add FuseConsecutiveClampsPass, which folds any chain of adjacent (single-user) clamp.default ops into one clamp using exact composition: clamp(clamp(x,a,b),c,d) == clamp(x, max(a,c), min(b,d)). This subsumes HardTanh->ReLU, ReLU->ReLU, HardTanh->HardTanh, ReLU6->ReLU, explicit clamp->clamp, and longer chains, dropping one op (and one intermediate tensor) per fused pair. Runs after FoldAndAnnotateQParamsPass so it fires in both the FP and INT paths; in the quantized case the surviving clamp inherits the first clamp's input qparams and the second's output qparams, dropping the intermediate requant (qtol=1, same tradeoff as FuseConsecutiveRescalesPass). Branching clamps (multiple users) are left untouched. Differential Revision: D112351522
4a81b5a to
d97e61a
Compare
Summary: ConvertToClampPass normalizes hardtanh, relu and relu6 into aten.clamp. Chains like HardTanh -> ReLU therefore become two adjacent clamps, the second of which is redundant. Add FuseConsecutiveClampsPass, which folds any chain of adjacent (single-user) clamp.default ops into one clamp using exact composition: clamp(clamp(x,a,b),c,d) == clamp(x, max(a,c), min(b,d)). This subsumes HardTanh->ReLU, ReLU->ReLU, HardTanh->HardTanh, ReLU6->ReLU, explicit clamp->clamp, and longer chains, dropping one op (and one intermediate tensor) per fused pair. Runs after FoldAndAnnotateQParamsPass so it fires in both the FP and INT paths; in the quantized case the surviving clamp inherits the first clamp's input qparams and the second's output qparams, dropping the intermediate requant (qtol=1, same tradeoff as FuseConsecutiveRescalesPass). Branching clamps (multiple users) are left untouched. Differential Revision: D112351522
d97e61a to
6da120a
Compare
|
Should be good to go, now. |
Summary:
ConvertToClampPass normalizes hardtanh, relu and relu6 into aten.clamp. Chains like HardTanh -> ReLU therefore become two adjacent clamps, the second of which is redundant.
Add FuseConsecutiveClampsPass, which folds any chain of adjacent (single-user) clamp.default ops into one clamp using exact composition: clamp(clamp(x,a,b),c,d) == clamp(x, max(a,c), min(b,d)). This subsumes HardTanh->ReLU, ReLU->ReLU, HardTanh->HardTanh, ReLU6->ReLU, explicit clamp->clamp, and longer chains, dropping one op (and one intermediate tensor) per fused pair.
Runs after FoldAndAnnotateQParamsPass so it fires in both the FP and INT paths; in the quantized case the surviving clamp inherits the first clamp's input qparams and the second's output qparams, dropping the intermediate requant (qtol=1, same tradeoff as FuseConsecutiveRescalesPass). Branching clamps (multiple users) are left untouched.
Differential Revision: D112351522