【问题标题】:cuFFT in column direction列方向的 cuFFT
【发布时间】:2020-04-13 12:25:05
【问题描述】:

我有一个 nx * ny 的复矩阵。我只想在列方向上执行 FFT。一种方法是转置整个矩阵,然后使用 cufftPlan1d 获得 FFT。有没有其他有效的方法来获得 FFT 而无需矩阵转置。 cufftPlanMany 将有助于获得列方向的 fft。例如让我们假设 nx = 8192 和 ny = 32768。 cufftPlanMany 的参数如下:

rank = 1;
idist = 1  // distance b/w batches
odist = 1
istride = nx
ostride = nx
int inembed[]={nx}
int onembed[]={nx}

cufftPlanMany(&plan,rank,ny,&inembed,istride,idist,&onembed,ostride,odist,CUFFT_C2C,1)

这是使用 cufftPlanMany 的正确方法吗?

【问题讨论】:

  • 您可以使用高级数据布局来做到这一点。它在 cufft 文档中进行了描述,其用法与您对 fftw 所做的相同。
  • 例如让我们假设 nx = 8192 和 ny = 32768。 cufftPlanMany 的参数如下: rank = 1; idist = 1 ; odist = 1 ;跨步 = nx ;跨步= nx; int inembed[]={nx}; int onembed[]={nx};cufftPlanMany(&plan,rank,ny,&inembed,istride,idist,&onembed,ostride,odist,CUFFT_C2C,1) 这是使用 cufftPlanMany 的正确方法吗?

标签: cuda cufft


【解决方案1】:

您提到了批次和一维,所以我假设您想要进行按行的 1D 变换或按列的 1D 变换。

在这种情况下,批次数等于行数情况下的行数或列数情况下的列数。

对于一维变换,inembedonembed 并不重要,但它们不能设置为 NULL。

idististrideodistostride 参数是此示例中要更改的关键参数(以及 batch)。使用 CUFFT advanced data layout 信息。

这是一个工作示例,显示了按行和按列的转换:

$ cat t1620.cu
#include <cufft.h>
#include <iostream>

int main(){

  cufftComplex data[] = {
    {1.0f, 0}, {2.0f, 0}, {3.0f, 0}, {4.0f, 0},
    {1.0f, 0}, {2.0f, 0}, {3.0f, 0}, {4.0f, 0},
    {1.0f, 0}, {2.0f, 0}, {3.0f, 0}, {4.0f, 0},
    {1.0f, 0}, {2.0f, 0}, {3.0f, 0}, {4.0f, 0}};
  cufftComplex *d_data;
  int ds = sizeof(data)/sizeof(data[0]);
  cudaMalloc(&d_data, ds*sizeof(data[0]));
  cudaMemcpy(d_data, data, ds*sizeof(data[0]), cudaMemcpyHostToDevice);
  cufftHandle plan;
  int dim = 4;
  int rank = 1;
  int nx = dim;
  int ny = dim;
#ifdef ROW_WISE
  int batch = ny;
  int inembed[rank] = {nx};
  int onembed[rank] = {nx};
  int istride = 1;
  int idist = nx;
  int ostride = 1;
  int odist = nx;
  int n[] = {nx};
#else
  int batch = nx;
  int inembed[rank] = {ny};
  int onembed[rank] = {ny};
  int istride = nx;
  int idist = 1;
  int ostride = nx;
  int odist = 1;
  int n[] = {ny};
#endif
  cufftResult err = cufftPlanMany(&plan, rank, n, inembed,
    istride, idist, onembed, ostride,
    odist, CUFFT_C2C, batch);
  std::cout << "plan :" << (int)err << std::endl;
  err = cufftExecC2C(plan, d_data, d_data, CUFFT_FORWARD);
  std::cout << "exec :" << (int)err << std::endl;
  cudaMemcpy(data, d_data, ds*sizeof(data[0]), cudaMemcpyDeviceToHost);
  for (int i = 0; i < ds; i++) std::cout << data[i].x << "," << data[i].y << std::endl;
  return 0;
}
$ nvcc -o t1620 t1620.cu -lcufft -DROW_WISE
$ ./t1620
plan :0
exec :0
10,0
-2,2
-2,0
-2,-2
10,0
-2,2
-2,0
-2,-2
10,0
-2,2
-2,0
-2,-2
10,0
-2,2
-2,0
-2,-2
$ nvcc -o t1620 t1620.cu -lcufft
$ ./t1620
plan :0
exec :0
4,0
8,0
12,0
16,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 2012-03-09
    • 2016-08-08
    • 2023-03-15
    相关资源
    最近更新 更多