I am trying to do matrix multiplication in Swift using the Accelerate framework. Used the vDSP_mmulD. This worked perfectly in the iPhone6 , 6 plus, iPad Air simulator (all 64 bit architecture) but did not work with any of the 32 bit architecture devices. It sees like vDSP_mmulD is not recognized by the 32 bit architecture and the program does not build. Error message displayed is "use of unresolved identifier 'vDSP_mmulD'" Has anybody else seen this error? Please let me know your thoughts. I am using Xcode 6.1. Thanks.
Simple solution: use cblas_dgemm
instead (also part of Accelerate). It's at least as fast as vDSP_mmulD
on all systems, and much faster on some (in iOS 8 and Yosemite, vDSP_mmulD
is actually just a wrapper around cblas_dgemm
), and it should actually work here.
I suspect that your build is failing for the 32-bit simulator; on i386, vDSP_mmulD is actually a macro around mmulD, and Swift does not fully support C language macros.
Note: I have a suspicion that you may be working with 3x3 or 4x4 matrices, in which case none of the Accelerate routines are really what you want (they're aimed a larger matrices); you want inline vector sequences like the ones defined in <simd/matrix.h>
. Unfortunately, Swift doesn't support SIMD vectors, so that's not an option. Your best bet at this point may be to simply write out the elementwise computation, and report a bug to request that Swift support the <simd/simd.h>
interfaces.
So this is all speculative, since I don't have a 32-bit device to test with right now, and I can't find any documentation to support this, but perhaps Accelerate works with different floating-point types on the two different architectures - Float
on a 32-bit architecture and Double
on a 64-bit architecture. The D
at the end of vDSP_mmulD
stands for Double
, so you'd need to be able to use the Float
version on 32-bit architecture in your code: vDSP_mmul
.
You can use an #if...#else...#endif
preprocessing block to toggle which methods you're using (info at the bottom of this page). One trick to get around Swift's strict static typing would be to put something like this preprocessing block at the top of your file:
#if arch(x86_64) || arch(arm64)
typealias M_Float = Double
let M_vDSP_mmul = vDSP_mmulD
// add Double versions of other Accelerate functions you need
#else
typealias M_Float = Float
let M_vDSP_mmul = vDSP_mmul
// add Float versions of other Accelerate functions you need
#endif
Then instead of having to pick whether you're working with Float
or Double
, or which method to use all throughout your code, you could just use M_Float
and your M_...
versions of the Accelerate functions:
var number: M_Float = 0 // Double on 64-bit, Float on 32-bit
M_vDSP_mmul(...) // correct version either way
Hope that helps!
I found this collections library for swift. It provides a matrix struct with multiplication operators using Accelerate. Worked for me.
来源:https://stackoverflow.com/questions/26519169/matrix-multiplication-in-swift-using-accelerate-framework-32-bit-vs-64-bit