mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
91 lines
2.0 KiB
Swift
91 lines
2.0 KiB
Swift
// RUN: %target-run-simple-swift
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
import _Differentiation
|
|
|
|
var InoutControlFlowTests = TestSuite("InoutControlFlow")
|
|
|
|
// https://github.com/apple/swift/issues/55999
|
|
|
|
struct Model: Differentiable {
|
|
var first: Float = 3
|
|
var second: Float = 1
|
|
|
|
mutating func outer() {
|
|
inner()
|
|
}
|
|
|
|
mutating func inner() {
|
|
self.second = self.first
|
|
|
|
// Dummy no-op if block, required to introduce control flow.
|
|
let x = 5
|
|
if x < 50 {}
|
|
}
|
|
}
|
|
|
|
@differentiable(reverse)
|
|
func loss(model: Model) -> Float{
|
|
var model = model
|
|
model.outer()
|
|
return model.second
|
|
}
|
|
|
|
InoutControlFlowTests.test("MutatingBeforeControlFlow") {
|
|
var model = Model()
|
|
let grad = gradient(at: model, of: loss)
|
|
expectEqual(1, grad.first)
|
|
expectEqual(0, grad.second)
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/56444
|
|
|
|
@differentiable(reverse)
|
|
func adjust(model: inout Model, multiplier: Float) {
|
|
model.first = model.second * multiplier
|
|
|
|
// Dummy no-op if block, required to introduce control flow.
|
|
let x = 5
|
|
if x < 50 {}
|
|
}
|
|
|
|
@differentiable(reverse)
|
|
func loss2(model: Model, multiplier: Float) -> Float {
|
|
var model = model
|
|
adjust(model: &model, multiplier: multiplier)
|
|
return model.first
|
|
}
|
|
|
|
InoutControlFlowTests.test("InoutParameterWithControlFlow") {
|
|
var model = Model(first: 1, second: 3)
|
|
let grad = gradient(at: model, 5.0, of: loss2)
|
|
expectEqual(0, grad.0.first)
|
|
expectEqual(5, grad.0.second)
|
|
}
|
|
|
|
@differentiable(reverse)
|
|
func adjust2(multiplier: Float, model: inout Model) {
|
|
model.first = model.second * multiplier
|
|
|
|
// Dummy no-op if block, required to introduce control flow.
|
|
let x = 5
|
|
if x < 50 {}
|
|
}
|
|
|
|
@differentiable(reverse)
|
|
func loss3(model: Model, multiplier: Float) -> Float {
|
|
var model = model
|
|
adjust2(multiplier: multiplier, model: &model)
|
|
return model.first
|
|
}
|
|
|
|
InoutControlFlowTests.test("LaterInoutParameterWithControlFlow") {
|
|
var model = Model(first: 1, second: 3)
|
|
let grad = gradient(at: model, 5.0, of: loss3)
|
|
expectEqual(0, grad.0.first)
|
|
expectEqual(5, grad.0.second)
|
|
}
|
|
|
|
runAllTests()
|