matrix multiplication in swift using Accelerate framework 32 bit vs 64 bit

谁都会走 提交于 2019-12-05 02:06:40

问题


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.


回答1:


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.




回答2:


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!




回答3:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!