!> !> @file pex11.f90 !> !> @brief Parallel write/read a 3d array partionned on 2d processor grid !> A(n1/P1, n2/P2, n3), with GHOST CELLS on the partitionned dimensions !> !> @copyright !> Copyright (©) 2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) !> SPC (Swiss Plasma Center) !> !> futils is free software: you can redistribute it and/or modify it under !> the terms of the GNU Lesser General Public License as published by the Free !> Software Foundation, either version 3 of the License, or (at your option) !> any later version. !> !> futils is distributed in the hope that it will be useful, but WITHOUT ANY !> WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS !> FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. !> !> You should have received a copy of the GNU Lesser General Public License !> along with this program. If not, see . !> !> @authors !> (in alphabetical order) !> @author Trach-Minh Tran !> PROGRAM main ! ! Parallel write/read a 3d array partionned on 2d processor grid ! A(n1/P1, n2/P2, n3), with GHOST CELLS on the partitionned dimensions. ! USE futils IMPLICIT NONE INCLUDE "mpif.h" CHARACTER(len=32) :: file='para.h5' INTEGER :: ierr, fid, me, npes INTEGER, PARAMETER :: ndims=2 INTEGER, PARAMETER :: n1p=3, n2p=2, n3=2 ! Dimension of local array REAL, DIMENSION(0:n1p+1,0:n2p+1,n3) :: arrayg ! Local array including ghost area COMPLEX, DIMENSION(0:n1p+1,0:n2p+1,n3) :: carrayg INTEGER, DIMENSION(ndims) :: dims, coords LOGICAL :: periods(ndims), reorder INTEGER :: cart, i, j, k, iglob, jglob, nerrors(2) REAL :: a COMPLEX :: ca !=========================================================================== ! 1. Prologue ! ! Init MPI CALL mpi_init(ierr) CALL mpi_comm_size(MPI_COMM_WORLD, npes, ierr) CALL mpi_comm_rank(MPI_COMM_WORLD, me, ierr) ! ! Create cartesian topololy ! dims = (/2, 4/) periods = (/.FALSE., .TRUE./) reorder = .FALSE. IF( PRODUCT(dims) .NE. npes ) THEN IF( me .EQ. 0 ) THEN PRINT*, PRODUCT(dims), " processors required!" CALL mpi_abort(MPI_COMM_WORLD, -1, ierr) END IF END IF CALL mpi_cart_create(MPI_COMM_WORLD, ndims, dims, periods, reorder, cart, ierr) CALL mpi_cart_coords(cart, me, ndims, coords, ierr) ! ! Define local array ! arrayg = me DO i=1,n1p iglob = coords(1)*n1p + i DO j=1,n2p jglob = coords(2)*n2p + j DO k=1,n3 arrayg(i,j,k) = 100*iglob + 10*jglob + k END DO END DO END DO carrayg = CMPLX(arrayg, REAL(me+1)) !=========================================================================== ! 2. Parallel write file ! ! Create file collectively, passing the comm. with cartesian topopily CALL creatf(file, fid, mpicomm=cart) ! ! Write to file collectively using "nd" version of "putarr". CALL putarrnd(fid, '/parray0', arrayg, (/1,2/), & & desc='With ghost area') CALL putarrnd(fid, '/parray', arrayg, (/1,2/), garea=(/1,1/), & & desc='Without ghost area') CALL putarrnd(fid, '/pcarray', carrayg, (/1,2/), garea=(/1,1/), & & desc='Without ghost area') !=========================================================================== ! 3. Parallel read file ! ! Close and reopen file CALL closef(fid) CALL openf(file, fid, mpicomm=cart) ! ! Read file arrayg = 0 carrayg = 0 CALL getarrnd(fid, '/parray', arrayg, (/1,2/), garea=(/1,1/)) CALL getarrnd(fid, '/pcarray', carrayg, (/1,2/), garea=(/1,1/)) ! ! Check read arrays nerrors = 0 DO i=1,n1p iglob = coords(1)*n1p + i DO j=1,n2p jglob = coords(2)*n2p + j DO k=1,n3 a = 100*iglob + 10*jglob + k ca = CMPLX(a, REAL(me+1)) IF( a .NE. arrayg(i,j,k)) nerrors(1) = nerrors(1)+1 IF( ca .NE. carrayg(i,j,k)) nerrors(2) = nerrors(2)+1 END DO END DO END DO WRITE(*,'(a,6i5)') 'nerrors reading /parray and /pcarray', nerrors ! !=========================================================================== ! 9. Epilogue ! ! Clean up and quit CALL closef(fid) CALL mpi_finalize(ierr) ! END PROGRAM main