-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[AutoDiff] Revamp usefulness propagation in activity analysis. #28225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AutoDiff] Revamp usefulness propagation in activity analysis. #28225
Conversation
Created PR as a draft because I feel there's room for improvement. |
@@ -1444,8 +1444,18 @@ class DifferentiableActivityInfo { | |||
void setUseful(SILValue value, unsigned dependentVariableIndex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: currently, setUseful
has two users (setUsefulAndPropagateToOperands
and propagateUsefulThroughAddress
), so it hasn't been inlined.
auto *inst = value->getDefiningInstruction(); | ||
if (!inst) | ||
return; | ||
propagateUseful(inst, dependentVariableIndex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: propagateUseful
cannot be inlined because it has multiple users (called multiple times in propagateUsefulThroughAddress
.
propagateUsefulThroughAddress(value, dependentVariableIndex); | ||
return; | ||
} | ||
setUseful(value, dependentVariableIndex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: both setUsefulAndPropagateToOperands
and propagateUsefulThroughAddress
call isUseful
and setUseful
, which seems suboptimal. I tried removing setUseful
from one of them but ran into infinite loops.
Related: I think setUsefulAndPropagateToOperands
should be the primary entry point for propagating usefulness, so I eliminated most direct calls to propagateUsefulThroughAddress
.
98cb4ec
to
05e0b86
Compare
Useful values are those that contribute to (specific) dependent variables, i.e. function results. For addresses: all projections of a useful address should be useful. This has special support: `DifferentiableActivityInfo::propagateUsefulThroughAddress`. Previously: - Usefulness was propagated by iterating through all instructions in post-dominance order. This is not efficient because irrelevant instructions may be visited. - For useful addresses, `propagateUsefulThroughAddress` propagated usefulness one step to projections, but not recursively to users of the projections. This caused some values to incorrectly not be marked useful. Now: - Usefulness is propagated by following use-def chains, starting from dependent variables (function results). This is handled by the following helpers: - `setUsefulAndPropagateToOperands(SILValue, unsigned)`: marks a value as useful and recursively propagates usefulness through defining instruction operands and basic block argument incoming values. - `propagateUseful(SILInstruction *inst, unsigned)`: propagates usefulness to the operands of the given instruction. - `DifferentiableActivityInfo::propagateUsefulThroughAddress` now calls `propagateUseful` to propagate usefulness recursively through users' operands. Effects: - More values are now (correctly) marked as useful, affecting non-differentiability diagnostics for active enum values (TF-956) and for-in loops (TF-957). Both have room for improvement. Resolves control flow differentiation correctness issue: TF-954.
05e0b86
to
af915c0
Compare
@swift-ci Please test tensorflow |
@swift-ci Please test tensorflow |
Hoist activity marking visited value set out of loop over original bbs. This is safe because bbs directly start with dominator bbs's active values. Visit bb arguments for activity marking. This was accidentally deleted in swiftlang#28225. Re-adding the logic doesn't seem to affect any tests.
Hoist activity marking visited value set out of loop over original bbs. This is safe because bbs directly start with dominator bbs's active values. Visit bb arguments for activity marking. This was accidentally deleted in #28225. Re-adding the logic doesn't seem to affect any tests.
Useful values are those that contribute to (specific) dependent variables, i.e. function results. For addresses: all projections of a useful address should be useful. This has special support: `DifferentiableActivityInfo::propagateUsefulThroughAddress`. Previously: - Usefulness was propagated by iterating through all instructions in post-dominance order. This is not efficient because irrelevant instructions may be visited. - For useful addresses, `propagateUsefulThroughAddress` propagated usefulness one step to projections, but not recursively to users of the projections. This caused some values to incorrectly not be marked useful. Now: - Usefulness is propagated by following use-def chains, starting from dependent variables (function results). This is handled by the following helpers: - `setUsefulAndPropagateToOperands(SILValue, unsigned)`: marks a value as useful and recursively propagates usefulness through defining instruction operands and basic block argument incoming values. - `propagateUseful(SILInstruction *inst, unsigned)`: propagates usefulness to the operands of the given instruction. - `DifferentiableActivityInfo::propagateUsefulThroughAddress` now calls `propagateUseful` to propagate usefulness recursively through users' operands. Effects: - More values are now (correctly) marked as useful, affecting non-differentiability diagnostics for active enum values (TF-956) and for-in loops (TF-957). Both have room for improvement. Resolves control flow differentiation correctness issue: TF-954.
Hoist activity marking visited value set out of loop over original bbs. This is safe because bbs directly start with dominator bbs's active values. Visit bb arguments for activity marking. This was accidentally deleted in #28225. Re-adding the logic doesn't seem to affect any tests.
Useful values are those that contribute to (specific) dependent variables,
i.e. function results.
For addresses: all projections of a useful address should be useful.
This has special support:
DifferentiableActivityInfo::propagateUsefulThroughAddress
.Previously:
post-dominance order. This is not efficient because irrelevant instructions
may be visited.
propagateUsefulThroughAddress
propagatedusefulness one step to projections, but not recursively to users of the
projections. This caused some values to incorrectly not be marked useful.
Now:
dependent variables (function results). This is handled by the
following helpers:
setUsefulAndPropagateToOperands(SILValue, unsigned)
: marks a value asuseful and recursively propagates usefulness through defining instruction
operands and basic block argument incoming values.
propagateUseful(SILInstruction *inst, unsigned)
: propagates usefulnessto the operands of the given instruction.
DifferentiableActivityInfo::propagateUsefulThroughAddress
now callspropagateUseful
to propagate usefulness recursively through users'operands.
Effects:
non-differentiability diagnostics for active enum values (TF-956) and for-in
loops (TF-957). Both have room for improvement.
Resolves control flow differentiation correctness issue: TF-954.