-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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] Derive Differentiable.zeroTangentVectorInitializer
.
#31823
[AutoDiff] Derive Differentiable.zeroTangentVectorInitializer
.
#31823
Conversation
/// | ||
/// The parser typically takes care of assigning unique discriminators to | ||
/// closures, but the parser is unavailable to this transform. | ||
class DiscriminatorFinder : public ASTWalker { |
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: I moved DiscriminatorFinder
to a shared location lib/Sema/CodeSynthesis.h
.
@CodaFi: I'll add you as reviewer in case you'd like to look at any of these derived conformances changes. |
@swift-ci Please test |
test/AutoDiff/Sema/DerivedConformances/class_differentiable.swift
Outdated
Show resolved
Hide resolved
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.
Can you derive a default implementation for zeroTangentVectorInitializer
even when the user has a custom tangent vector? If you do that then this PR won't be source-breaking.
I asked offline for clarification. What @rxwei has in mind is: deriving @marcrasi: do you agree whether this makes sense and is desirable? I think you have experience with custom This behavior should be possible but requires more work. I'd like to reach consensus before exploring. |
I have some thoughts about default synthesis of zeroTangentVectorInitializer. The ultimate ideal behavior
What to do today Yes, derive |
From a usability point of view It's already pretty difficult to define a custom Therefore the usability point of view also says that, it's good to derive |
The root problem is that types like @derivative(of: foo)
func _(x: T) -> (value: U, differential: @differentiable(linear) (x.TangentVector) -> value.TangentVector) However, |
97f6739
to
cf81768
Compare
Thanks for the feedback above!
I implemented this behavior. There are now two cases for
The result is improved usability: almost no types (including "primitive"
import _Differentiation
struct Struct<T: Differentiable, U: Differentiable>: Differentiable {
var x: T
var y: U
// Previously synthesized, incorrectly captures `self`:
// var zeroTangentVectorInitializer: () -> TangentVector {
// {
// // Accesses to `self.x` and `self.y` cause `self` to be captured.
// TangentVector(x: x.zeroTangentVectorInitializer(),
// y: y.zeroTangentVectorInitializer())
// }
// }
// Now synthesized, correct:
// var zeroTangentVectorInitializer: () -> TangentVector {
// { [xZeroTanInit = x.zeroTangentVectorInitializer,
// yZeroTanInit = y.zeroTangentVectorInitializer] in
// TangentVector(x: xZeroTanInit(), y: yZeroTanInit())
// }
// }
} Ready for re-review. |
`Differentiable` conformance derivation now supports `Differentiable.zeroTangentVectorInitializer`. There are two potential cases: 1. Memberwise derivation: done when `TangentVector` can be initialized memberwise. 2. `{ TangentVector.zero }` derivation: done as a fallback. `zeroTangentVectorInitializer` is a closure that produces a zero tangent vector, capturing minimal necessary information from `self`. It is an instance property, unlike the static property `AdditiveArithmetic.zero`, and should be used by the differentiation transform for correctness. Remove `Differentiable.zeroTangentVectorInitializer` dummy default implementation. Update stdlib `Differentiable` conformances and tests. Clean up DerivedConformanceDifferentiable.cpp cruft. Resolves TF-1007. Progress towards TF-1008: differentiation correctness for projection operations.
cf81768
to
be54faa
Compare
@swift-ci Please smoke test |
test/AutoDiff/Sema/DerivedConformances/derived_zero_tangent_vector_initializer.swift
Outdated
Show resolved
Hide resolved
Add test for enum with custom non-`Self` `TangentVector` type. Fallback `{ TangentVector.zero }` synthesis is expected and correct.
@swift-ci Please smoke test |
@swift-ci Please clean smoke test Linux |
Differentiable
conformance derivation now supportsDifferentiable.zeroTangentVectorInitializer
.zeroTangentVectorInitializer
is a closure that produces a zero tangent vector,capturing minimal necessary information from
self
.It is an instance property, unlike the static property
AdditiveArithmetic.zero
,and should be used by the differentiation transform for correctness.
Remove
zeroTangentVectorInitializer
dummy default implementation.Primitive
Differentiable
-conforming types now must implement it.Update stdlib
Differentiable
conformances and tests.Resolves TF-1007.
Progress towards TF-1008: differentiation correctness for projection operations.
Examples: