mirror of
https://github.com/apple/swift.git
synced 2026-10-10 13:50:43 +02:00
1. When differentiable nested function (closure) is specialized by capture promotion pass ensure we generate a differentiability witness for the specialized function as well. Ensure the original witness is removed if the original function becomes dead. 2. Differentiability witnesses for a function could originate either from its `@differentiable` attribute or from explicit `@derivative(of:)` attribute on the derivative. In the latter case the derivative itself might not be emitted, while original function is (e.g. original function is `@inlineable`, but derivative is `@usableFromInline`). Previously both cases were handled only when function body was emitted. As a result we missed witness in the aforementioned case. Ensure the differentiability witness originating from `@derivative(of:)` is emitted even if we're not going to emit body of the derivative. Fixes #59135
39 lines
1.8 KiB
Swift
39 lines
1.8 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-swift-emit-sil -emit-module -module-name M -emit-module-path %t/M.swiftmodule 2>&1 %s | %FileCheck %s
|
|
|
|
// The original function Tensor.subscriptIndexPath() is not marked as @differentiable. As a result, no explicit differentiable witness is generated for it.
|
|
// However, the witness is generated as a side effect of providing a derivative via @derivative(of: subscriptIndexPath) on _vjpSubscriptIndexPath.
|
|
// Since _vjpSubscriptIndexPath is not emitted when -emit-module is used, we need to ensure we still generate a witness.
|
|
|
|
import _Differentiation
|
|
|
|
// CHECK-LABEL: differentiability witness for Tensor.subscriptIndexPath()
|
|
// CHECK: sil_differentiability_witness [serialized] [reverse] [parameters 0] [results 0] @$s1M6TensorV18subscriptIndexPathACyF : $@convention(method) (Tensor) -> Tensor {
|
|
// CHECK: vjp: @$s1M6TensorV18subscriptIndexPathACyFTJrSpSr : $@convention(method) (Tensor) -> (Tensor, @owned @callee_guaranteed (Tensor) -> Tensor)
|
|
|
|
// CHECK-LABEL: reverse-mode derivative of Tensor.subscriptIndexPath()
|
|
// CHECK: @$s1M6TensorV18subscriptIndexPathACyFTJrSpSr : $@convention(method) (Tensor) -> (Tensor, @owned @callee_guaranteed (Tensor) -> Tensor) {
|
|
// CHECK: function_ref Tensor._vjpSubscriptIndexPath()
|
|
// CHECK: function_ref @$s1M6TensorV22_vjpSubscriptIndexPathAC5value_A2Cc8pullbacktyF : $@convention(method) (Tensor) -> (Tensor, @owned @callee_guaranteed (Tensor) -> Tensor)
|
|
|
|
public struct Tensor: Differentiable & AdditiveArithmetic {
|
|
@inlinable
|
|
func subscriptIndexPath() -> Tensor {
|
|
fatalError()
|
|
}
|
|
|
|
@inlinable
|
|
@differentiable(reverse, wrt: self)
|
|
func subscriptRanges() -> Tensor {
|
|
subscriptIndexPath()
|
|
}
|
|
|
|
@usableFromInline
|
|
@derivative(of: subscriptIndexPath)
|
|
func _vjpSubscriptIndexPath() -> (
|
|
value: Tensor, pullback: (Tensor) -> Tensor
|
|
) {
|
|
fatalError()
|
|
}
|
|
}
|