gpt4 book ai didi

fortran - 进行从复数到实数的 fftw3 MPI 傅立叶变换时的奇怪行为

转载 作者:行者123 更新时间:2023-12-02 03:34:32 28 4
gpt4 key购买 nike

考虑一个问题,您想要将 f(x,y) ~ cos(x) 的光谱表示转换为坐标空间。所以 exp(i*x) + exp(-i*x) ----> f(x,y),其中 f(x,y) = some_factor * cos(x) 。

在列优先布局中(我的示例在下面用 Fortran 2003/8 编写),光谱数组将初始化为,

src=(0.,0.)
src(2,1)=(1.,0.) .

转换后应该得到一个 tgt 实数( double )数组,其中所有列都相同,并且每一列都表现为 cos(x) 函数。

但是,使用下面给出的代码,我得到了一个 tgt 数组,其中只有奇数列行为正确,而偶数列全部为零。

什么,如果我做错了什么?

我的 fftw3 版本是 3.4.4 。

    program c2r
! COMPLEX --> REAL 2D MPI TRANSFORM

! compiled using: mpif90 -O0 -g -I/usr/include c2rnot.F90 -o c2rnot -L /usr/lib/x86_64-linux-gnu -lfftw3_mpi -lfftw3
use, intrinsic :: iso_c_binding
use MPI

implicit none
include 'fftw3-mpi.f03'
integer :: ierr,id

! logical dimensions of the transform
integer(C_INTPTR_T), parameter :: N1 = 32
integer(C_INTPTR_T), parameter :: N2 = 32

! helper variables: storage size, extents along the slow dim, offsets
integer(C_INTPTR_T) :: alloc_local, slicec,slicer,offc,offr

! pointers to planner, real (image) and complex (original) arrays
type(C_PTR) :: plan, ctgt, csrc

! fortran array representation of csrc ...
complex(8), pointer :: src(:,:)
! ..., ctgt and a total array to hold the mpi-gathered result
real(8), pointer :: tgt(:,:),total(:,:)


integer(C_INTPTR_T) :: i,y0

! init mpi and fftw ...
call mpi_init(ierr)

call mpi_comm_rank(MPI_COMM_WORLD,id,ierr)

call fftw_mpi_init()
! done with init


! calculate local complex array storage requirements and layout
alloc_local = fftw_mpi_local_size_2d(N2,N1/2+1, &
& MPI_COMM_WORLD,slicec,offc)
! allocate local complex array
csrc = fftw_alloc_complex(alloc_local)
! fortran representation
call c_f_pointer(csrc, src, [N1/2+1,slicec])

! allocate local real array
ctgt = fftw_alloc_real(2*alloc_local)
! for non-transposed arrays slices are the same
slicer=slicec
offr=offc
! fortran representation
call c_f_pointer(ctgt, tgt, [2*(N1/2+1),slicer])

! allocate global container (holds gathered tgt arrays)
if (id==0) allocate(total(N1,N2))

! N1 - fast, N2 - slow dimension, in: src, out: tgt
plan = fftw_mpi_plan_dft_c2r_2d(N2,N1,src,tgt, MPI_COMM_WORLD, FFTW_MEASURE)


src=(0.D0,0.D0)

! ~ exp(i*x) + exp(-i*x) which should turn into ~ cos(x)
src(2,1)=(1.D0,0.D0)

tgt=0.D0
! do transform
call fftw_mpi_execute_dft_c2r(plan,src,tgt)

! collect tgt-s into total in process 0
call mpi_gather(tgt(1:n1,1:slicer),slicer*n1,mpi_double,total,slicer*n1,mpi_double,0,mpi_comm_world,ierr)

! The scalar field total has x: 1..N1, y:1..N2 layout. Print
! behaviour along the x-axis for a given, constant y. The result
! should be ~ cos(x) function for any y0 in [1..N2]. However, I get
! such result only for odd y0. For even, total(i,y0) is 0.
y0=3
if (id == 0) then
do i=1,n1
print *, i, total(i,y0)
enddo
endif

call mpi_finalize(ierr)
end program c2r

最佳答案

请记住,所有进程都执行 mpi 中的代码。

因此,当您编写 src(2,1)=(1.D0,0.D0) 时,您正在设置 size 频率,每个进程一个。

因此,如果使用单个进程 mpiexec -np 1 c2rnot,您的代码似乎可以正常工作。但是,如果你运行许多进程 mpiexec -np 2 c2rnot,你会得到其他东西......

你可以尝试 if(id==0) src(2,1)=(1.D0,0.D0) 吗? id 是排名,如您的代码中所示。

您也可以在 mpi_gather() 中使用 MPI_REAL8:我的编译器提示 mpi_double 没有 IMPLICIT 类型。

祝你好运!再见,

关于fortran - 进行从复数到实数的 fftw3 MPI 傅立叶变换时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24484881/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com