Skip to content
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] Runtime EXC_BAD_ACCESS when running a pullback in certain cases. #73526

Open
fibrechannelscsi opened this issue May 8, 2024 · 1 comment
Assignees
Labels
AutoDiff bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. run-time crash Bug → crash: Swift code crashed during execution triage needed This issue needs more specific labels

Comments

@fibrechannelscsi
Copy link
Contributor

Description

The code below generates a runtime EXC_BAD_ACCESS when executed.

Reproduction

Copy and paste the following code into a new project, and build in Debug mode.

import Foundation; import _Differentiation
public protocol N {}
public protocol H: Differentiable {}
public protocol D: H & N where Self.TangentVector: N {}
public struct O<V> {var v: V}
extension O: Differentiable where V: Differentiable {}
public extension N {var d: [String : PartialKeyPath<Self>] {return self.e(i: self) as! [String : PartialKeyPath<Self>]}}
public extension H {var z: TangentVector {Self.TangentVector.zero}}
public struct R: D {public var a: Double = 7}
public struct B<F, G> {
    @noDerivative public internal(set) var s: [String : WritableKeyPath<F, G>]
    @noDerivative public var a: Set<WritableKeyPath<F, G>> {var a = Set<WritableKeyPath<F, G>>(); a.insert(self.s.values.first!); return a}
    public init<S: Sequence>(to: S) where S.Element == WritableKeyPath<F, G> {self.s = ["0" : \R.a] as! [String : WritableKeyPath<F, G>]}
    @differentiable(reverse where F: D, G: Differentiable) public func o(f i: F) -> O<G> {
        var y: [G] = []
        for k in self.a {y = y + [p(i, at: k)]}
        var b = [O<G>]()
        for i in 0 ..< withoutDerivative(at: y.count) {
            b.append(O<G>(v: y[i]))
           // b = b + [O<G>(v: y[i])]
        }
        if withoutDerivative(at: b.count) > 1 {return O<G>(v: b[0].v)}
        else {return O<G>(v: y[0])}
    }
}
@inlinable @differentiable(reverse where W: D, M: Differentiable) public func p<W, M>(_ o: W, at j: WritableKeyPath<W, M>) -> M {return o[keyPath: j]}
@inlinable @derivative(of: p) public func vjpP<O, M>(_ o: O, at m: WritableKeyPath<O, M>) -> (value: M, pullback: (M.TangentVector) -> O.TangentVector) where O: D, M: Differentiable
{
    var z = o.z
    let r = o.d.mapValues { $0 as? WritableKeyPath<O, M> }.compactMapValues { $0 }.filter { $0.value == m }.compactMap { $0.key }
    let u = z.d.filter {r.first! == $0.key}.values.map { $0 } as! [WritableKeyPath<O.TangentVector, M.TangentVector>]
    return (value: o[keyPath: m], pullback: { d in z[keyPath: u.first!] = d; return z})
}
extension N {func e(i: any N) -> [String : AnyKeyPath] {if g == 0 {g += 1; return ["a": \R.a]}; return ["a" : \R.TangentVector.a]}}
var g = 0;
let b = R(a: 9)
@differentiable(reverse) func s(b: R) -> Double {return B<R, Double>(to: [\R.a]).o(f: b).v * 3}
print(valueWithGradient(at: b, of: s))

If run in Xcode, the error will be highlighted in line 19, which contains b.append(O<G>(v: y[i])). Here, it will indicate an "index out of range" error.
If built via swift build and executed in lldb, an EXC_BAD_ACCESS will be triggered with an attempt to access 0x0. The stack trace for this is listed below.

Expected behavior

The program should print:
(value: 27.0, gradient: i2.R.TangentVector(a: 3.0))
and exit with an exit code of 0.
Here, i2 is the name of the current project.

Environment

M1 Mac
Every toolchain I've tried exhibits this, from 2023-07-10a nightly all the way to 2024-05-01a. I can even reproduce this with the 6.0 2024-04-29a snapshot.

Additional information

Stack trace when run in lldb. Note that the executable is simply called a.

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x0000000100155fa4 a`reverse-mode derivative of B.o(i=<unavailable>, self=_9999.B<_9999.R, Swift.Double> @ 0x000000016fdff018) at main.swift:14:72
    frame #2: 0x000000010015a1b0 a`reverse-mode derivative of s(b=(a = 9)) at main.swift:37:82
    frame #3: 0x0000000100152790 a`$s5_99991RVS2dAC13TangentVectorVIegyd_Igydo_ACSdxq_Ri_zRi0_zRi__Ri0__r0_lySdAEIsegnr_Iegnro_TR at <compiler-generated>:0
    frame #4: 0x0000000227a92f98 libswift_Differentiation.dylib`_Differentiation.valueWithPullback<τ_0_0, τ_0_1 where τ_0_0: _Differentiation.Differentiable, τ_0_1: _Differentiation.Differentiable>(at: τ_0_0, of: @differentiable(reverse) (τ_0_0) -> τ_0_1) -> (value: τ_0_1, pullback: (τ_0_1.TangentVector) -> τ_0_0.TangentVector) + 152
    frame #5: 0x0000000227a94780 libswift_Differentiation.dylib`_Differentiation.valueWithGradient<τ_0_0, τ_0_1 where τ_0_0: _Differentiation.Differentiable, τ_0_1: Swift.FloatingPoint, τ_0_1: _Differentiation.Differentiable, τ_0_1 == τ_0_1._Differentiation.Differentiable.TangentVector>(at: τ_0_0, of: @differentiable(reverse) (τ_0_0) -> τ_0_1) -> (value: τ_0_1, gradient: τ_0_0.TangentVector) + 184
    frame #6: 0x0000000100152494 a`_9999_main at main.swift:38:7
    frame #7: 0x000000018665d0e0 dyld`start + 2360

If we perform the append operation via b = b + [O<G>(v: y[i])], which is commented out in line 20, then the runtime error will not occur.

@fibrechannelscsi fibrechannelscsi added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels May 8, 2024
@fibrechannelscsi
Copy link
Contributor Author

@jkshtj

@jkshtj jkshtj self-assigned this May 8, 2024
@jkshtj jkshtj added run-time crash Bug → crash: Swift code crashed during execution AutoDiff labels May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AutoDiff bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. run-time crash Bug → crash: Swift code crashed during execution triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

2 participants