Nested Do Loops of Complex Arrays

!  This program takes an input data set in complex domain and adds (1 + i * 1) with it in the output.

!  The program is in MPI & OPENMP OR HybrID Parallalisation.

!  To run this code: 

!  mpif90 -fopenmp comp_2d_hybrid.f90

!  mpirun -np 2 ./a.out

PROGRAM main

  use omp_lib

  implicit none

  INCLUDE 'mpif.h'

  integer ( kind = 4 ), parameter :: nx = 3

  integer ( kind = 4 ), parameter :: ny = 4

  integer ( kind = 4 ) i, j

  integer ( kind = 4 ) root, ny_loc, dim_array

  INTEGER ( kind = 4 ) NPROCS, MYRANK, IERR !MPI

  integer ( kind = 4 ) THREAD_NUM,num_thread,PROC_NUM,ID !OPENMP

  complex, dimension(nx,ny) :: in, out

  complex, allocatable :: loc(:,:)

! INITIALIZE OPENMP

  PROC_NUM = OMP_GET_NUM_PROCS()

  THREAD_NUM = 8

  CALL OMP_SET_NUM_THREADS (THREAD_NUM)

 

! INITIALIZE MPI

  CALL MPI_INIT(IERR)

  CALL MPI_COMM_SIZE(MPI_COMM_WORLD, NPROCS, IERR)

  CALL MPI_COMM_RANK(MPI_COMM_WORLD, MYRANK, IERR)

  root = 0

! ny has to be an integer multiple of ny_loc.

  ny_loc = ny / NPROCS

  allocate(loc(nx,ny_loc))

  dim_array = nx*ny_loc

! input data 

  if (MYRANK == root) then

!$OMP PARALLEL SHARED(in) PRIVATE(i,j)

!$OMP DO

    do j = 1, ny

      do i = 1, nx

        in(i,j) = (1.0d0,1.0d0)!float(i)+float(j) ! your data-file here.

        print*, i,j,in(i,j),"IN"

      enddo

    enddo

!$OMP END PARALLEL

  endif

! DISTRIBUTE AMONG MEMORY

  CALL  MPI_SCATTER( in, dim_array, MPI_COMPLEX, loc, dim_array, MPI_COMPLEX, root, &

                                                               MPI_COMM_WORLD, IERR )

! evaluate task

!$OMP PARALLEL SHARED(ny_loc,loc,MYRANK) PRIVATE(i,j,ID)

!  ID = OMP_GET_THREAD_NUM()

!  print*, MYRANK,ID

!$OMP DO

    do j = 1,ny_loc

      do i = 1,nx

        loc(i,j) = loc(i,j) + (1.0d0,1.0d0) !+float(j+ny_loc*MYRANK)

        !print*, i,j+ny_loc*MYRANK,loc(i,j),MYRANK!,ID

      enddo

    enddo

!$OMP END PARALLEL

! COLLECT FROM MEMORY

  CALL  MPI_GATHER( loc, dim_array, MPI_COMPLEX, out, dim_array, MPI_COMPLEX, root, &

                                                               MPI_COMM_WORLD, IERR )

! output data

  if (MYRANK == root) then                                      

!$OMP PARALLEL SHARED(out) PRIVATE(i,j)

!$OMP DO

    do j = 1, ny

      do i = 1, nx

        print*, i,j,out(i,j),"OUT"

      enddo

    enddo

!$OMP END PARALLEL

  endif

! FINALIZE MPI

  CALL MPI_FINALIZE(IERR)

END