我正在尝试使用Accelerate框架在Swift中进行矩阵乘法。使用了vDSP_mmulD。这在iPhone6,6 plus,iPad Air模拟器(所有64位架构)中完美运行,但不适用于任何32位架构设备。 它看起来像32位架构无法识别vDSP_mmulD并且程序无法构建。显示的错误消息是"使用未解析的标识符' vDSP_mmulD'"有没有人看到这个错误?请让我知道你的想法。我正在使用Xcode 6.1。 感谢。
答案 0 :(得分:3)
简单解决方案:改为使用cblas_dgemm
(也是Accelerate的一部分)。它至少与所有系统上的vDSP_mmulD
一样快,而且在某些系统上要快得多(在iOS 8和Yosemite中,vDSP_mmulD
实际上只是cblas_dgemm
的包装),并且它应该在这里工作。
我怀疑你的构建在32位模拟器上失败了;在i386上,vDSP_mmulD实际上是一个围绕mmulD的宏,而Swift并不完全支持C语言宏。
注意:我怀疑你可能正在使用3x3或4x4矩阵,在这种情况下,没有一个Accelerate例程真的是你想要的(他们的目标是更大的矩阵);你想要内联向量序列,如<simd/matrix.h>
中定义的那样。不幸的是,Swift并不支持SIMD向量,所以这不是一个选择。此时您最好的选择可能是简单地写出元素计算,并报告错误以请求Swift支持<simd/simd.h>
接口。
答案 1 :(得分:1)
所以这都是推测性的,因为我现在没有要测试的32位设备,我找不到任何文档来支持这一点,但也许Accelerate适用于不同的浮点类型两种不同的体系结构 - 32位体系结构上的Float
和64位体系结构上的Double
。 D
末尾的vDSP_mmulD
代表Double
,因此您需要能够在代码中使用32位架构上的Float
版本:{ {1}}。
您可以使用vDSP_mmul
预处理块来切换您正在使用的方法(bottom of this page处的信息)。绕过Swift严格的静态类型的一个技巧是将这样的预处理块放在文件的顶部:
#if...#else...#endif
然后,您无需选择是使用#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
还是Float
,还是在整个代码中使用哪种方法,而只需使用Double
和{{{} 1}}版本的加速功能:
M_Float
希望有所帮助!
答案 2 :(得分:0)
我为swift找到了这个collections library。它使用Accelerate提供了一个带有乘法运算符的矩阵结构。为我工作。