blob: 35158015808afbb9a18cd941b3b5fbfb1ae0a5e8 [file] [log] [blame]
// RUN: %target-swift-emit-sil -verify -Xllvm -debug-only=differentiation 2>&1 %s | %FileCheck %s
// REQUIRES: asserts
// Test approaches for affecting activity analysis (non-varying semantics):
// - `@noDerivative` on declaration
// - `@_semantics("autodiff.nonvarying")` on declaration
// - `withoutDerivative(at:)` at use site
extension Float {
// No non-varying semantics.
var int: Int { Int(self) }
// Non-varying semantics.
@noDerivative
var intNoDerivative: Int { int }
// Non-varying semantics.
@_semantics("autodiff.nonvarying")
var intNonvarying: Int { int }
}
// expected-error @+1 {{function is not differentiable}}
@differentiable
@_silgen_name("id")
// expected-note @+1 {{when differentiating this function definition}}
func id(_ x: Float) -> Float {
// expected-note @+1 {{cannot differentiate through a non-differentiable result; do you want to use 'withoutDerivative(at:)'?}}
return Float(x.int)
}
// CHECK-LABEL: [AD] Activity info for id at parameter indices (0) and result indices (0):
// CHECK: bb0:
// CHECK: [ACTIVE] %0 = argument of bb0 : $Float
// CHECK: [USEFUL] %2 = metatype $@thin Float.Type
// CHECK: [NONE] // function_ref Float.int.getter
// CHECK: [ACTIVE] %4 = apply %3(%0) : $@convention(method) (Float) -> Int
// CHECK: [NONE] // function_ref Float.init(_:)
// CHECK: [ACTIVE] %6 = apply %5(%4, %2) : $@convention(method) (Int, @thin Float.Type) -> Float
@differentiable
@_silgen_name("idWithoutDerivativeAt")
func idWithoutDerivativeAt(_ x: Float) -> Float {
return Float(withoutDerivative(at: x.int))
}
// CHECK-LABEL: [AD] Activity info for idWithoutDerivativeAt at parameter indices (0) and result indices (0):
// CHECK: bb0:
// CHECK: [VARIED] %0 = argument of bb0 : $Float
// CHECK: [USEFUL] %2 = metatype $@thin Float.Type
// CHECK: [USEFUL] %3 = alloc_stack $Int
// CHECK: [NONE] // function_ref Float.int.getter
// CHECK: [VARIED] %5 = apply %4(%0) : $@convention(method) (Float) -> Int
// CHECK: [VARIED] %6 = alloc_stack $Int
// CHECK: [NONE] // function_ref withoutDerivative<A>(at:)
// CHECK: [NONE] %9 = apply %8<Int>(%3, %6) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
// CHECK: [USEFUL] %11 = load [trivial] %3 : $*Int
// CHECK: [NONE] // function_ref Float.init(_:)
// CHECK: [USEFUL] %13 = apply %12(%11, %2) : $@convention(method) (Int, @thin Float.Type) -> Float
@differentiable
@_silgen_name("idNoDerivative")
func idNoDerivative(_ x: Float) -> Float {
return Float(x.intNoDerivative)
}
// CHECK-LABEL: [AD] Activity info for idNoDerivative at parameter indices (0) and result indices (0):
// CHECK: bb0:
// CHECK: [VARIED] %0 = argument of bb0 : $Float
// CHECK: [USEFUL] %2 = metatype $@thin Float.Type
// CHECK: [NONE] // function_ref Float.intNoDerivative.getter
// CHECK: [USEFUL] %4 = apply %3(%0) : $@convention(method) (Float) -> Int
// CHECK: [NONE] // function_ref Float.init(_:)
// CHECK: [USEFUL] %6 = apply %5(%4, %2) : $@convention(method) (Int, @thin Float.Type) -> Float
@differentiable
@_silgen_name("idNonvaryingSemantics")
func idNonvaryingSemantics(_ x: Float) -> Float {
return Float(x.intNonvarying)
}
// CHECK-LABEL: [AD] Activity info for idNonvaryingSemantics at parameter indices (0) and result indices (0):
// CHECK: bb0:
// CHECK: [VARIED] %0 = argument of bb0 : $Float
// CHECK: [USEFUL] %2 = metatype $@thin Float.Type
// CHECK: [NONE] // function_ref Float.intNonvarying.getter
// CHECK: [USEFUL] %4 = apply %3(%0) : $@convention(method) (Float) -> Int
// CHECK: [NONE] // function_ref Float.init(_:)
// CHECK: [USEFUL] %6 = apply %5(%4, %2) : $@convention(method) (Int, @thin Float.Type) -> Float