我目前正在使用OpenCL实现一个二维FFT,用于处理真实输入数据(更具体地说是使用FFT进行快速二维卷积,因此我只需要一些类似的函数来应用卷积)。二维FFT是在行上执行一维FFT之后,在列上执行另一个一维FFT来实现的。
为了使这个过程更加高效,我试图利用实数输入的FFT对称性,以便能够计算较小的FFT。我发现可以将两行合并成一行,第一行作为实部,第二行作为虚部,对结果行进行第一次1D FFT,然后使用对称性质从中构造单独行的1D FFT结果。所以我正在做的基本上是以下操作:
设f和g是矩阵中的行。
1. 构造x = f + i * g 2. 进行变换以获得 F(x) = F(f) + i * F(g) 3. 使用对称性从F(x)中提取F(f)和F(g)
但是,我不能直接将结果输入第二个1D FFT,因为在这种情况下,我将不会转换整个矩阵,而是转换两个子矩阵。然而,提取转换之间的数据意味着要么存储更多数据(需要n/2+1个条目来表示实输入上的1D FFT结果),要么将索引0和n/2的元素结合成一个元素(使用相同的技巧进行组合,因为这两个数字保证是实数),并且在我的卷积中需要针对此情况进行特殊处理。
由于我尽量重复利用缓冲区(由于GPU上可用内存有限),因此使用更多存储空间不是一个好的解决方案。此外,我的算法无法处理非2的幂次方/16的倍数大小的矩阵(从内核到内核都有所不同)。我宁愿避免引入特殊情况,因为这些会使我的内核更加复杂,从而损害效率(我已经在试图将每个内核使用的寄存器计数最小化时遇到了麻烦)。
因此,我的问题是是否有一种优雅的方法来解决这个问题,即在不使用更多内存或特殊情况的情况下工作?
理想情况下,我希望能够在不将组合数据分割在FFT的中间的情况下完成整个FFT,但我不确定是否可能。
为了使这个过程更加高效,我试图利用实数输入的FFT对称性,以便能够计算较小的FFT。我发现可以将两行合并成一行,第一行作为实部,第二行作为虚部,对结果行进行第一次1D FFT,然后使用对称性质从中构造单独行的1D FFT结果。所以我正在做的基本上是以下操作:
设f和g是矩阵中的行。
1. 构造x = f + i * g 2. 进行变换以获得 F(x) = F(f) + i * F(g) 3. 使用对称性从F(x)中提取F(f)和F(g)
但是,我不能直接将结果输入第二个1D FFT,因为在这种情况下,我将不会转换整个矩阵,而是转换两个子矩阵。然而,提取转换之间的数据意味着要么存储更多数据(需要n/2+1个条目来表示实输入上的1D FFT结果),要么将索引0和n/2的元素结合成一个元素(使用相同的技巧进行组合,因为这两个数字保证是实数),并且在我的卷积中需要针对此情况进行特殊处理。
由于我尽量重复利用缓冲区(由于GPU上可用内存有限),因此使用更多存储空间不是一个好的解决方案。此外,我的算法无法处理非2的幂次方/16的倍数大小的矩阵(从内核到内核都有所不同)。我宁愿避免引入特殊情况,因为这些会使我的内核更加复杂,从而损害效率(我已经在试图将每个内核使用的寄存器计数最小化时遇到了麻烦)。
因此,我的问题是是否有一种优雅的方法来解决这个问题,即在不使用更多内存或特殊情况的情况下工作?
理想情况下,我希望能够在不将组合数据分割在FFT的中间的情况下完成整个FFT,但我不确定是否可能。