使用快速加速vDSP_ctoz的分段错误



我正在尝试使用Swift Accelerate库中的vDSP_ctoz将交错的DSPComplex向量转换为DSPSplitComplex向量。下面代码的最后一行产生错误Segmentation fault: 11

我不明白为什么当我分配了大向量并且只尝试处理少量元素时,vDSP_ctoz会尝试访问越界内存。向量的大小为 2048,vDSP_ctozN(要处理的元素数(的参数为 1。

我还尝试在调用vDSP_ctoz时使用不同的步幅和N值,但无济于事。

// set stride values
let dspComplexStride = MemoryLayout<DSPComplex>.stride
let dspSplitComplexStride = MemoryLayout<DSPSplitComplex>.stride
// make interleaved vector
var interleaved = UnsafeMutablePointer<DSPComplex>.allocate(capacity: 2048)
for index in 0..<16 {
interleaved[index] = DSPComplex(real: Float(2*index), imag: Float(2*index+1))
}
// make split vector
var splitComplex = UnsafeMutablePointer<DSPSplitComplex>.allocate(capacity: 2048)
vDSP_ctoz(
interleaved, dspComplexStride, splitComplex, dspSplitComplexStride, 1
)

DSPSplitComplex是一个包含指针数组的结构, 所以你需要一个DSPSplitComplex元素,并且必须分配 存储其realpimagp属性。

">

步幅"参数不是以字节为单位,而是以"元素"单位来衡量。 所以你传递__IZ == 1因为你想填充连续的元素 在目标数组中。

您必须为源数组传递__IC == 2可能并不明显,即 源数组的步幅以Float为单位给出,而不是以DSPComplex单位。这可以从vDSP_ctoz文档中推断出来 其中提到该功能有效地做到了

for (n = 0; n < N; ++n)
{
Z->realp[n*IZ] = C[n*IC/2].real;
Z->imagp[n*IZ] = C[n*IC/2].imag;
}

最后,vDSP_ctoz的最后一个参数是元素的数量 过程。

综上所述,它应该这样工作:

import Accelerate
let N = 16
var interleaved = UnsafeMutablePointer<DSPComplex>.allocate(capacity: N)
for index in 0..<N {
interleaved[index] = DSPComplex(real: Float(2*index), imag: Float(2*index+1))
}
let realp = UnsafeMutablePointer<Float>.allocate(capacity: N)
let imagp = UnsafeMutablePointer<Float>.allocate(capacity: N)
var splitComplex = DSPSplitComplex(realp: realp, imagp: imagp)
vDSP_ctoz(interleaved, 2, &splitComplex, 1, vDSP_Length(N))
for index in 0..<N {
print(splitComplex.realp[index], splitComplex.imagp[index])
}

当然,您最终必须释放内存。

最新更新