Skip to content
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] Registers VJPs for FloatingPoint.[maximum|minimum] #35379

Merged
merged 2 commits into from Jan 13, 2021

Conversation

vguerra
Copy link
Contributor

@vguerra vguerra commented Jan 12, 2021

Resolves TF-1134.

static func _vjpMinimum(_ x: Self, _ y: Self) -> (
value: Self, pullback: (TangentVector) -> (TangentVector, TangentVector)
) {
func pullback(_ v: TangentVector) -> (TangentVector, TangentVector) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pullback is defined according to the logic of FloatingPoint.minimum so that the corner cases for returning either x or y are respected.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is running the identical control flow in the VJP and the pullback. It should be simplified so that the pullback is just straight line code and the control flow is executed only once. You can do:

@inlinable
@derivative(of: minimum)
static func _vjpMinimum(_ x: Self, _ y: Self) -> (
  value: Self, pullback: (TangentVector) -> (TangentVector, TangentVector)
) {
  if x <= y || y.isNaN { return (x, { v in (v, .zero) }) }
  return (y, { v in (.zero, v) })
}

The same suggestion applies to maximum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see.. yes, thanks for the remark @rxwei .. i am fixing that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in bc40409.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

static func _vjpMaximum(_ x: Self, _ y: Self) -> (
value: Self, pullback: (TangentVector) -> (TangentVector, TangentVector)
) {
func pullback(_ v: TangentVector) -> (TangentVector, TangentVector) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above but for FloatingPoint.maximum.

Copy link
Collaborator

@dan-zheng dan-zheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IANAM (I am not a mathematician) but LGTM! Let me ping one.

@dan-zheng
Copy link
Collaborator

@swift-ci Please test

To avoid executing control flow code twice ( once in VJP and
once in the pullback ).
@rxwei
Copy link
Member

rxwei commented Jan 13, 2021

@swift-ci please test

@rxwei rxwei merged commit 6298351 into apple:main Jan 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants