FFTW (2-D MPI) (Real to Complex to Real) (with transposed arrays)
Program rupak
use, intrinsic :: iso_c_binding
implicit none
include 'mpif.h'
integer (C_INTPTR_T), parameter :: nx = 7
integer (C_INTPTR_T), parameter :: ny = 5
integer (C_INTPTR_T), parameter :: nh = ( nx / 2 ) + 1
include "fftw3-mpi.f03"
integer(C_INTPTR_T) :: i, j
real(C_DOUBLE), dimension(nx,ny) :: in,in2
complex(C_DOUBLE_COMPLEX), dimension(nh,ny) :: out
integer :: ierr, myid, nproc, seed
type(C_PTR) :: plan, plan1, cdatar, cdatac
integer(C_INTPTR_T) :: alloc_local, local_ny, local_j_offset
real(C_DOUBLE), pointer :: rdata(:,:)
complex(C_DOUBLE_complex), pointer :: cdata(:,:)
seed = 123456789
call mpi_init(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, nproc, ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
do i = 1, nx
do j = 1, ny
in(i,j) = ran(seed)
seed=in(i,j)*seed
end do
end do
call fftw_mpi_init()
! get local data size and allocate (note dimension reversal)
alloc_local = fftw_mpi_local_size_2d(ny, nh, MPI_COMM_WORLD, &
local_ny, local_ny_offset)
cdatar = fftw_alloc_real(2 * alloc_local)
call c_f_pointer(cdatar, rdata, [2*nh,local_ny])
alloc_local = fftw_mpi_local_size_2d(nh,ny, MPI_COMM_WORLD, &
local_nx, local_nx_offset)
cdatac = fftw_alloc_complex(alloc_local)
call c_f_pointer(cdatac, cdata, [ny,local_nx])
! create MPI plan for out-of-place DFT (note dimension reversal)
plan1 = fftw_mpi_plan_dft_r2c_2d(ny,nx,rdata,cdata, MPI_COMM_WORLD, &
ior(FFTW_MEASURE, FFTW_MPI_TRANSPOSED_OUT))
plan2 = fftw_mpi_plan_dft_c2r_2d(ny,nx,cdata,rdata2, MPI_COMM_WORLD, &
ior(FFTW_MEASURE, FFTW_MPI_TRANSPOSED_IN))
! initialize data to some function my_function(i,j)
do i = 1, nx
do j = 1, local_ny
rdata(i, j) = in(i, j + local_j_offset)
write ( *, '(2x,i4,2x,i4,2x,2g14.6)' ) i,j+local_j_offset,rdata(i,j),local_j_offset!,myid
end do
end do
! compute transform (as many times as desired)
call fftw_mpi_execute_dft_r2c(plan, rdata, cdata)
! COPY TO OUTPUT ARRAY
do i = 1, nh
do j = 1, local_ny
out(i,j+local_j_offset) = cdata(i,j)
write ( *, '(2x,i4,2x,i4,2x,2g14.6)' ) i, j+local_j_offset, cdata(i,j)!,out(i,j+local_j_offset)!, local_j_offset
end do
end do
call fftw_mpi_execute_dft_c2r(plan1, cdata, rdata)
! COPY TO OUTPUT ARRAY
do i = 1, nx
do j = 1, local_ny
in2(i,j+local_j_offset) = rdata(i,j)
write ( *, '(2x,i4,2x,i4,2x,2g14.6)' ) i, j+local_j_offset, rdata(i,j)/(ny*nx)!,in2(i,j+local_j_offset)!, local_j_offset
end do
end do
! deallocate and destroy plans
call fftw_destroy_plan(plan)
call fftw_mpi_cleanup()
call fftw_free(cdatar)
call fftw_free(cdatac)
do i = 1, nh
do j = 1, ny
!write ( *, '(2x,i4,2x,i4,2x,2g14.6)' ) i, j, out(i,j)
end do
end do
do i = 1, nx
do j = 1, ny
!write ( *, '(2x,i4,2x,i4,2x,2g14.6)' ) i, j, in2(i,j)/(ny*nx)
end do
end do
call mpi_finalize(ierr)
end