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

纵然是瞬间 提交于 2019-12-03 17:25:37

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.

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