mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
118 lines
6.7 KiB
Swift
118 lines
6.7 KiB
Swift
/// Single basic block VJP.
|
|
|
|
// REQUIRES: executable_test
|
|
// UNSUPPORTED: OS=windows-msvc
|
|
|
|
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift %s -o %t/none.out -Onone
|
|
// RUN: %target-build-swift %s -o %t/opt.out -O
|
|
// RUN: %target-codesign %t/none.out
|
|
// RUN: %target-codesign %t/opt.out
|
|
// RUN: %target-run %t/none.out
|
|
// RUN: %target-run %t/opt.out
|
|
|
|
// RUN: %target-swift-frontend -emit-sil %s -O -o %t/out.sil
|
|
// RUN: cat %t/out.sil | %FileCheck %s --check-prefix=CHECK1
|
|
// RUN: cat %t/out.sil | %FileCheck %s --check-prefix=CHECK2
|
|
// RUN: cat %t/out.sil | %FileCheck %s --check-prefix=CHECK3
|
|
|
|
import DifferentiationUnittest
|
|
import StdlibUnittest
|
|
|
|
#if canImport(Glibc)
|
|
import Glibc
|
|
#elseif canImport(Android)
|
|
import Android
|
|
#else
|
|
import Foundation
|
|
#endif
|
|
|
|
var AutoDiffClosureSpecSingleBBTests = TestSuite("AutoDiffClosureSpecSingleBB")
|
|
|
|
AutoDiffClosureSpecSingleBBTests.testWithLeakChecking("Test1") {
|
|
// CHECK1-LABEL: {{^}}// reverse-mode derivative of test1 #1 (_:)
|
|
// CHECK1-NEXT: sil private @$s3outyycfU_5test1L_yS2fFTJrSpSr : $@convention(thin) (Float) -> (Float, @owned @callee_guaranteed (Float) -> Float) {
|
|
// CHECK1: %[[#A10:]] = function_ref @$s3outyycfU_5test1L_yS2fFTJpSpSr62$s16_Differentiation7_vjpSinySf5value_S2fc8pullbacktSfFS2fcfU_Sf0c1_d1_e4Cosyg1_hiJ2U_Sf026$sSf16_DifferentiationE12_e16Multiply3lhs3rhsg1_i17_SftSfc8pullbackti1_q5FZSf_Q6SfcfU_S2fTf1nccc_n : $@convention(thin) (Float, Float, Float, Float, Float) -> Float
|
|
// CHECK1: %[[#A11:]] = partial_apply [callee_guaranteed] %[[#A10]](%[[#]], %[[#]], %[[#]], %[[#]]) : $@convention(thin) (Float, Float, Float, Float, Float) -> Float
|
|
// CHECK1: %[[#A12:]] = tuple (%[[#]], %[[#A11]])
|
|
// CHECK1: return %[[#A12]]
|
|
// CHECK1: } // end sil function '$s3outyycfU_5test1L_yS2fFTJrSpSr'
|
|
|
|
// CHECK1-NONE: {{^}}// pullback of test1 #1 (_:)
|
|
// CHECK1: {{^}}// specialized pullback of test1 #1 (_:)
|
|
// CHECK1: sil private @$s3outyycfU_5test1L_yS2fFTJpSpSr62$s16_Differentiation7_vjpSinySf5value_S2fc8pullbacktSfFS2fcfU_Sf0c1_d1_e4Cosyg1_hiJ2U_Sf026$sSf16_DifferentiationE12_e16Multiply3lhs3rhsg1_i17_SftSfc8pullbackti1_q5FZSf_Q6SfcfU_S2fTf1nccc_n : $@convention(thin) (Float, Float, Float, Float, Float) -> Float {
|
|
|
|
@differentiable(reverse)
|
|
func test1(_ x: Float) -> Float {
|
|
return sin(x) * cos(x)
|
|
}
|
|
|
|
func test1Derivative(_ x: Float) -> Float {
|
|
return cos(x) * cos(x) - sin(x) * sin(x)
|
|
}
|
|
|
|
for x in -100...100 {
|
|
expectEqual((1000 * gradient(at: Float(x), of: test1)).rounded(), (1000 * test1Derivative(Float(x))).rounded())
|
|
}
|
|
}
|
|
|
|
AutoDiffClosureSpecSingleBBTests.testWithLeakChecking("Test2") {
|
|
// CHECK2-LABEL: {{^}}// reverse-mode derivative of test2 #1 (_:)
|
|
// CHECK2-NEXT: sil private @$s3outyycfU0_5test2L_yS2fFTJrSpSr : $@convention(thin) (Float) -> (Float, @owned @callee_guaranteed (Float) -> Float) {
|
|
// CHECK2: %[[#B19:]] = function_ref @$s3outyycfU0_5test2L_yS2fFTJpSpSr073$sSf16_DifferentiationE12_vjpMultiply3lhs3rhsSf5value_Sf_SftSfc8pullbacktj1_k5FZSf_K6SfcfU_S2f022$s16_Differentiation7_g4Sinyi15_S2fc8pullbacktJ8FS2fcfU_SfADSf0o1_p1_g4Cosyi1_rjS2U_SfACS2fAESf0cd1_e3E7_g11Add3lhs3rhsi1_j1_klj1_km1_kN2U_Tf1nccccccc_n : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float
|
|
// CHECK2: %[[#B20:]] = partial_apply [callee_guaranteed] %[[#B19]](%[[#]], %[[#]], %[[#]], %[[#]], %[[#]], %[[#]], %[[#]], %[[#]]) : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float
|
|
// CHECK2: %[[#B21:]] = tuple (%[[#]], %[[#B20]])
|
|
// CHECK2: return %[[#B21]]
|
|
// CHECK2: } // end sil function '$s3outyycfU0_5test2L_yS2fFTJrSpSr'
|
|
|
|
// CHECK2-NONE: {{^}}// pullback of test2 #1 (_:)
|
|
// CHECK2: {{^}}// specialized pullback of test2 #1 (_:)
|
|
// CHECK2: sil private @$s3outyycfU0_5test2L_yS2fFTJpSpSr073$sSf16_DifferentiationE12_vjpMultiply3lhs3rhsSf5value_Sf_SftSfc8pullbacktj1_k5FZSf_K6SfcfU_S2f022$s16_Differentiation7_g4Sinyi15_S2fc8pullbacktJ8FS2fcfU_SfADSf0o1_p1_g4Cosyi1_rjS2U_SfACS2fAESf0cd1_e3E7_g11Add3lhs3rhsi1_j1_klj1_km1_kN2U_Tf1nccccccc_n : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float {
|
|
|
|
@differentiable(reverse)
|
|
func test2(_ x: Float) -> Float {
|
|
return sin(37 * x) * cos(sin(x)) + cos(x)
|
|
}
|
|
|
|
func test2Derivative(_ x: Float) -> Float {
|
|
return -cos(x)*sin(37*x)*sin(sin(x)) + 37*cos(37*x)*cos(sin(x)) - sin(x)
|
|
}
|
|
|
|
for x in -100...100 {
|
|
expectEqual((1000 * gradient(at: Float(x), of: test2)).rounded(), (1000 * test2Derivative(Float(x))).rounded())
|
|
}
|
|
}
|
|
|
|
AutoDiffClosureSpecSingleBBTests.testWithLeakChecking("Test3") {
|
|
// CHECK3-LABEL: {{^}}// reverse-mode derivative of test3 #1 (_:_:_:)
|
|
// CHECK3-NEXT: sil private @$s3outyycfU1_5test3L_yS2f_S2ftFTJrSSSpSr : $@convention(thin) (Float, Float, Float) -> (Float, @owned @callee_guaranteed (Float) -> (Float, Float, Float)) {
|
|
// CHECK3: %[[#C18:]] = function_ref @$s3outyycfU1_5test3L_yS2f_S2ftFTJpSSSpSr62$s16_Differentiation7_vjpSinySf5value_S2fc8pullbacktSfFS2fcfU_Sf0c1_d1_e4Cosyg1_hiJ2U_Sf025$sSf16_DifferentiationE7_e11Add3lhs3rhsg1_i17_SftSfc8pullbackti1_q5FZSf_Q6SfcfU_0c1_d1_e4Tanyg1_hiJ2U_Sf0lm1_n4E12_e16Subtract3lhs3rhsg1_i1_qri1_qs1_qT2U_Tf1nccccc_n : $@convention(thin) (Float, Float, Float, Float) -> (Float, Float, Float)
|
|
// CHECK3: %[[#C19:]] = partial_apply [callee_guaranteed] %[[#C18]](%[[#]], %[[#]], %[[#]]) : $@convention(thin) (Float, Float, Float, Float) -> (Float, Float, Float)
|
|
// CHECK3: %[[#C20:]] = tuple (%[[#]], %[[#C19]])
|
|
// CHECK3: return %[[#C20]]
|
|
// CHECK3: } // end sil function '$s3outyycfU1_5test3L_yS2f_S2ftFTJrSSSpSr'
|
|
|
|
// CHECK3-NONE: {{^}}// pullback of test3 #1 (_:_:_:)
|
|
// CHECK3: {{^}}// specialized pullback of test3 #1 (_:_:_:)
|
|
// CHECK3: sil private @$s3outyycfU1_5test3L_yS2f_S2ftFTJpSSSpSr62$s16_Differentiation7_vjpSinySf5value_S2fc8pullbacktSfFS2fcfU_Sf0c1_d1_e4Cosyg1_hiJ2U_Sf025$sSf16_DifferentiationE7_e11Add3lhs3rhsg1_i17_SftSfc8pullbackti1_q5FZSf_Q6SfcfU_0c1_d1_e4Tanyg1_hiJ2U_Sf0lm1_n4E12_e16Subtract3lhs3rhsg1_i1_qri1_qs1_qT2U_Tf1nccccc_n : $@convention(thin) (Float, Float, Float, Float) -> (Float, Float, Float) {
|
|
|
|
@differentiable(reverse)
|
|
func test3(_ x: Float, _ y: Float, _ z: Float) -> Float {
|
|
return sin(x) + cos(y) - tan(z)
|
|
}
|
|
|
|
for x in -5...5 {
|
|
for y in -5...5 {
|
|
for z in -5...5 {
|
|
let pb = pullback(at: Float(x), Float(y), Float(z), of: test3)
|
|
let (der1, der2, der3) = pb(1)
|
|
expectEqual((10000 * der1).rounded(), (10000 * cos(Float(x))).rounded())
|
|
expectEqual((10000 * der2).rounded(), (10000 * (-sin(Float(y)))).rounded())
|
|
expectEqual((10000 * der3).rounded(), (10000 * (-(tan(Float(z)) * tan(Float(z)) + 1))).rounded())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
runAllTests()
|