Very interesting example. I watched your talk yesterday and left somewhat confused although you state at the end of your talk that things are hopefully clearer now
There are a lot of different pointer types around and it is not clear to me what the exact semantics of what is. Is there a formal semantics somewhere for the pointer API? That might help.
So given the definition of
fileprivate func recast<U, V>(_ ptr : UnsafeMutablePointer<U>) -> UnsafeMutablePointer<V> {
let p = UnsafeMutableRawPointer(ptr)
return p.assumingMemoryBound(to: V.self)
}
is for example this code safe or not (where in the Dispatch/float branch Self
will be Complex<Float>
and in the Dispatch/double branch Self
will be Complex<Double>
):
public static func lapack_gesvd(_ jobu : UnsafeMutablePointer<Int8>, _ jobvt : UnsafeMutablePointer<Int8>,
_ m : UnsafeMutablePointer<IntLA>, _ n : UnsafeMutablePointer<IntLA>,
_ a : UnsafeMutablePointer<Self>, _ lda : UnsafeMutablePointer<IntLA>,
_ s : UnsafeMutablePointer<Self.Magnitude>,
_ u : UnsafeMutablePointer<Self>, _ ldu : UnsafeMutablePointer<IntLA>,
_ vt : UnsafeMutablePointer<Self>, _ ldvt : UnsafeMutablePointer<IntLA>,
_ work : UnsafeMutablePointer<Self>, _ lwork : UnsafeMutablePointer<IntLA>,
_ info : UnsafeMutablePointer<IntLA>) -> Int32
{
return dispatch(
float: {
var rwork = [Float](repeating: 0, count: 5*Int(min(m.pointee, n.pointee)))
return cgesvd_(jobu, jobvt, m, n, recast(a), lda, recast(s), recast(u), ldu, recast(vt), ldvt, recast(work), lwork, &rwork, info)
},
double: {
var rwork = [Double](repeating: 0, count: 5*Int(min(m.pointee, n.pointee)))
return zgesvd_(jobu, jobvt, m, n, recast(a), lda, recast(s), recast(u), ldu, recast(vt), ldvt, recast(work), lwork, &rwork, info)
}
)
}