If you ignore the deprecation warnings about using the new BLAS and LAPACK interface for Accelerate, then you can use functions like cblas_cgemv
as shown in the following example:
import Accelerate
let a = [DSPComplex(real: 1.0, imag: 2.0), DSPComplex(real: 3.0, imag: 4.0),
DSPComplex(real: 5.0, imag: 6.0), DSPComplex(real: 7.0, imag: 8.0)]
let x = [DSPComplex(real: 1.0, imag: 2.0), DSPComplex(real: 3.0, imag: 4.0)]
let m: Int32 = 2
let n: Int32 = 2
let alpha = [DSPComplex(real: 1.0, imag: 0.0)]
let beta = [DSPComplex(real: 1.0, imag: 0.0)]
var y = [DSPComplex](repeating: DSPComplex(), count: Int(m))
cblas_cgemv(CblasRowMajor, CblasNoTrans, m, n, alpha, a, m, x, 1, beta, &y, 1)
To get rid of the warnings and use the new interface, you must use ACCELERATE_NEW_LAPACK=1
and ACCELERATE_LAPACK_ILP64=1
as preprocessor macros in Xcode projects or compile with the appropriate flags for swiftc
. Using this new interface requires the above example to be written as shown below. You have to write several nested closures to get unsafe pointers to the variables. This feels like a downgrade compared to the previous example. Is there a cleaner way to work with the new BLAS and LAPACK interface or do we have to go back to a "pyramid of doom" approach?
import Accelerate
let a = [DSPComplex(real: 1.0, imag: 2.0), DSPComplex(real: 3.0, imag: 4.0),
DSPComplex(real: 5.0, imag: 6.0), DSPComplex(real: 7.0, imag: 8.0)]
let x = [DSPComplex(real: 1.0, imag: 2.0), DSPComplex(real: 3.0, imag: 4.0)]
let m = 2 // rows in matrix A
let n = 2 // columns in matrix A
let alpha = [DSPComplex(real: 1.0, imag: 0.0)] // scale factor for Ī±AX
let beta = [DSPComplex(real: 1.0, imag: 0.0)] // scale factor for Ī²Y
var y = [DSPComplex](repeating: DSPComplex(), count: m)
alpha.withUnsafeBufferPointer { alphaPtr in
a.withUnsafeBufferPointer { aPtr in
x.withUnsafeBufferPointer { xPtr in
beta.withUnsafeBufferPointer { betaPtr in
y.withUnsafeMutableBufferPointer { yPtr in
cblas_cgemv(
CblasRowMajor,
CblasNoTrans,
m,
n,
.init(alphaPtr.baseAddress!),
.init(aPtr.baseAddress!),
m,
.init(xPtr.baseAddress!),
1,
.init(betaPtr.baseAddress!),
.init(yPtr.baseAddress!),
1
)
}
}
}
}
}