首页
学习
活动
专区
圈层
工具
发布

cuda
EN

Stack Overflow用户
提问于 2020-12-10 00:38:01
回答 1查看 179关注 0票数 0

我在使用cufftPlanMany时遇到了麻烦。在创建计划并进行正向和反向FFT后,我无法获得原始数据。请查找附件中的代码的最低版本。

代码语言:javascript
复制
program test_cufft
  use cudafor
  use cufft

  integer :: plan_r2c
  integer :: plan_c2r
  real,allocatable,dimension(:,:,:,:), device :: eta_d
  complex,allocatable,dimension(:,:,:,:), device :: etak_d

  nv = 4
  nx = 256
  ny = 512
  nz = 512
  nx21 = nx/2+1

  allocate( eta_d(nv,nx,ny,nz) )
  allocate( etak_d(nv,nx21,ny,nz) )

  batch = nv;
  rank = 3;
  n = (/ nx, ny, nz /);
  idist = nx*ny*nz;
  odist = nx21*ny*nz;
  inembed = (/ nx, ny, nz /);
  onembed = (/ nx21, ny, nz /);
  istride = 1;
  ostride = 1;

  istat = cufftPlanMany( plan_r2c, rank, n, inembed, istride, idist, &
                         onembed, ostride, odist, CUFFT_R2C, batch )
  istat = cufftPlanMany( plan_c2r, rank, n, onembed, ostride, odist, &
                         inembed, istride, idist, CUFFT_C2R, batch )

  ! Initialize eta_d

  istat = cufftExecR2C( plan_r2c, eta_d, etak_d )
  istat = cufftExecC2R( plan_c2r, etak_d, eta_d )
  eta_d = eta_d/idist

end program test_cufft

问题是,在我做了正向和反向的FFTs之后,我无法得到原始数据。拜托,我做错什么了?数据的排序应该是eta_d(batch,nx,ny,nz) or eta_d(nx,ny,nz,batch)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-10 03:35:42

我认为正确的排序是(nz, ny, nx, batch)

但是,将它们与数组索引和存储顺序联系起来也很重要。

在CUFFT 术语中,对于三维变换(*),nz方向是变化最快的索引,其中典型用法(stride=1)是内存中的相邻数据,对应于变换中的相邻元素。

对于R2C/C2R转换类型,这个方向(我认为它是一行上的元素,即"z“索引是列索引)也是在复杂域中得到”约简“的多维转换的方向。

考虑到这一点,我将以如下方式重写您的代码:

代码语言:javascript
复制
$ cat t4.cuf
program test_cufft
  use cudafor
  use cufft

  integer :: plan_r2c
  integer :: plan_c2r
  real,allocatable,dimension(:,:,:,:), managed :: eta_d
  complex,allocatable,dimension(:,:,:,:), managed :: etak_d
  integer :: n(3), inembed(3), onembed(3),rank,istride,idist,ostride,odist,batch

  nv = 4
  nx = 8
  ny = 8
  nz = 4
  nz21 = nz/2+1

  allocate( eta_d(nz,ny,nx,nv) )
  allocate( etak_d(nz21,ny,nx,nv) )

  batch = nv;
  rank = 3;
  n = (/ nx, ny, nz /);
  idist = nx*ny*nz;
  odist = nx*ny*nz21;
  inembed = (/ nx, ny, nz /);
  onembed = (/ nx, ny, nz21 /);
  istride = 1;
  ostride = 1;

  istat = cufftPlanMany( plan_r2c, rank, n, inembed, istride, idist, onembed, ostride, odist, CUFFT_R2C, batch )
  istat = cufftPlanMany( plan_c2r, rank, n, onembed, ostride, odist, inembed, istride, idist, CUFFT_C2R, batch )

  ! Initialize eta_d
  eta_d(:,:,:,:) = 1.0
  eta_d(1,1,1,2) = 2.0
  istat = cufftExecR2C( plan_r2c, eta_d, etak_d )
  istat = cudaDeviceSynchronize()
  eta_d(:,:,:,:) = 0.0
  istat = cufftExecC2R( plan_c2r, etak_d, eta_d )
  istat = cudaDeviceSynchronize()
  eta_d = eta_d/idist
  print *,eta_d(1,1,1,1)
  print *,eta_d(1,1,1,2)
end program test_cufft
$ nvfortran t4.cuf -lcufft
$ ./a.out
    1.000000
    2.000000
$

(NVIDIA HPC SDK 20.9,Tesla V100 GPU)

它似乎给出了我的简单测试用例的预期结果。

(*)对于二维变换,ny维数变化最快,对于一维变换,nx维数(当然)变化最快。

多维转换和先进的数据布局CUFFT手册的章节也可能是有用的阅读。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65226929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档