Python numpy.fft更改了步幅

时间:2016-10-18 13:40:55

标签: python arrays numpy memory-management fft

亲爱的stackoverflow社区!

今天我发现在高端集群架构中,2个立方体的元素乘法与尺寸1921 x 512 x 512需要~27 s。这太长了,因为我必须对当前实现中的功率谱的方位角平均进行至少256次这样的计算。我发现性能缓慢主要是由于不同的步幅结构(一种情况下为C而另一种情况下为FORTRAN)。两个数组中的一个是新生成的布尔网格(C顺序),另一个(FORTRAN顺序)来自输入网格(C顺序)的3D numpy.fft.fftn()傅立叶变换。 numpy.fft.fftn()改变了如何防止除了反转轴之外的步幅和想法的任何原因(这只是一种解决方法)?有了类似的进步(FT网格的ndarray.copy()),可以实现~4s,这是一个巨大的进步。

因此问题如下:

考虑数组:

ran = np.random.rand(1921, 512, 512)
ran.strides
(2097152, 4096, 8)

a = np.fft.fftn(ran)
a.strides
(16, 30736, 15736832)

我们可以看到步幅结构不同。如何防止这种情况(不使用= np.fft.fftn(run,axes =(1,0)))?还有其他任何可能影响步幅结构的numpy数组例程吗?在这些情况下可以做些什么?

非常感谢有用的建议!

2 个答案:

答案 0 :(得分:2)

您可以使用scipy.fftpack.fftn(也可以使用hpaulj),而不是numpy.fft.fftn,看起来它正在做你想要的。但是表现稍差:

$location.search('');
$location.search('parameter', null);

答案 1 :(得分:1)

  

为什么numpy.fft.fftn()改变了除了反转轴之外如何防止它的步伐和想法的任何原因(这只是一种解决方法)?

计算阵列的多维度DFT包括在每个维度上连续计算1D DTF。有两种策略:

  1. 将1D DTF计算限制为连续的1D阵列。由于阵列是连续的,因此与延迟/缓存未命中相关的问题将会减少。该策略有一个主要缺点:阵列将在每个维度之间转置。这可能是numpy.fft采用的策略。在计算结束时,数组已被转置。为避免不必要的计算,返回转置数组并修改步幅。
  2. 为跨步数组启用1D DDFT计算。这可能会触发与延迟相关的一些问题。这是fftw的策略,可以通过界面pyfftw获得。因此,输出数组具有与输入数组相同的步幅。
  3. 执行heretherethere的时间numpy.fftnpyfftw.numpy.fftn将告诉您FFTW是否真的是西方最快的傅里叶变换...

      

    还有其他任何可能影响步幅结构的numpy数组例程吗?在这些情况下可以做些什么?

    你可以{{3}}:这个功能只使用了几次。因此,在我看来,这是一个大踏步的变化"特别是fft.fftn(),大多数numpy函数保持步幅不变。

    最后,"改变步伐"是第一个战略的一个特征,没有办法阻止这一点。唯一的解决方法是在计算结束时交换轴,这是昂贵的。但是你可以依赖pyfftw,因为fftw以非常有效的方式实现了第二个策略。 DFT计算会更快,如果不同数组的步幅变得一致,后续计算也会更快。