| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729 |
- module mpimod
- use pumamod
- ! include 'mpif.h'
- use mpi
- integer :: mpi_itype = MPI_INTEGER4
- integer :: mpi_rtype = MPI_REAL4
- integer :: mpi_ltype = MPI_LOGICAL
- character(len=80) ynode(NPRO) ! node names
- end module mpimod
- !
- ! interface routines to MPI:
- !
- ! ================
- ! SUBROUTINE MPBCI
- ! ================
- subroutine mpbci(k) ! broadcast 1 integer
- use mpimod
- integer :: k(*)
- call mpi_bcast(k,1,mpi_itype,NROOT,myworld,mpinfo)
- return
- end subroutine mpbci
- ! =================
- ! SUBROUTINE MPBCIN
- ! =================
- subroutine mpbcin(k,n) ! broadcast n integer
- use mpimod
- integer :: k(n)
- call mpi_bcast(k,n,mpi_itype,NROOT,myworld,mpinfo)
- return
- end subroutine mpbcin
- ! ================
- ! SUBROUTINE MPBCR
- ! ================
- subroutine mpbcr(p) ! broadcast 1 real
- use mpimod
- REAL :: p(*)
- call mpi_bcast(p,1,mpi_rtype,NROOT,myworld,mpinfo)
- return
- end subroutine mpbcr
- ! =================
- ! SUBROUTINE MPBCRN
- ! =================
- subroutine mpbcrn(p,n) ! broadcast n real
- use mpimod
- real :: p(n)
- call mpi_bcast(p,n,mpi_rtype,NROOT,myworld,mpinfo)
- return
- end subroutine mpbcrn
- ! ================
- ! SUBROUTINE MPBCL
- ! ================
- subroutine mpbcl(l) ! broadcast 1 logical
- use mpimod
- logical :: l(*)
- call mpi_bcast(l,1,mpi_ltype,NROOT,myworld,mpinfo)
- return
- end subroutine mpbcl
- ! =================
- ! SUBROUTINE MPSCIN
- ! =================
- subroutine mpscin(k,n) ! scatter n integer
- use mpimod
- integer :: k(n),l(n)
- call mpi_scatter(k,n,mpi_itype,l,n,mpi_itype,NROOT,myworld,mpinfo)
- k(:)=l(:)
- return
- end subroutine mpscin
- ! =================
- ! SUBROUTINE MPSCRN
- ! =================
- subroutine mpscrn(p,n) ! scatter n real
- use mpimod
- real :: p(*),l(n)
-
- call mpi_scatter(p,n,mpi_rtype,l,n,mpi_rtype,NROOT,myworld,mpinfo)
- p(1:n)=l(:)
- return
- end subroutine mpscrn
- ! =================
- ! SUBROUTINE MPSCDN
- ! =================
- subroutine mpscdn(p,n) ! scatter n double precision
- use mpimod
- real (kind=8) :: p(*),l(n)
- call mpi_scatter(p,n,MPI_REAL8,l,n,MPI_REAL8,NROOT,myworld,mpinfo)
- p(1:n)=l(:)
- return
- end subroutine mpscdn
- ! =================
- ! SUBROUTINE MPSCGP
- ! =================
- subroutine mpscgp(pf,pp,klev) ! scatter gridpoint fields
- use mpimod
- real :: pf(NUGP,klev)
- real :: pp(NHOR,klev)
- do jlev = 1 , klev
- call mpi_scatter(pf(:,jlev),NHOR,mpi_rtype, &
- & pp(:,jlev),NHOR,mpi_rtype, &
- & NROOT,myworld,mpinfo)
- enddo
- return
- end subroutine mpscgp
- ! =================
- ! SUBROUTINE MPGAGP
- ! =================
- subroutine mpgagp(pf,pp,klev) ! gather gridpoint fields
- use mpimod
- real :: pf(NLON*NLAT,klev)
- real :: pp(NHOR,klev)
- do jlev = 1 , klev
- call mpi_gather(pp(:,jlev),NHOR,mpi_rtype, &
- & pf(:,jlev),NHOR,mpi_rtype, &
- & NROOT,myworld,mpinfo)
- enddo
- return
- end subroutine mpgagp
- ! ===================
- ! SUBROUTINE MPGALLGP
- ! ===================
- subroutine mpgallgp(pf,pp,klev) ! gather gritpoint to all
- use mpimod
- real :: pf(NLON*NLAT,klev)
- real :: pp(NHOR,klev)
- do jlev = 1 , klev
- call mpi_allgather(pp(:,jlev),NHOR,mpi_rtype, &
- & pf(:,jlev),NHOR,mpi_rtype, &
- & myworld,mpinfo)
- enddo
- return
- end subroutine mpgallgp
- ! =================
- ! SUBROUTINE MPSCSP
- ! =================
- subroutine mpscsp(pf,pp,klev) ! scatter spectral fields
- use mpimod
- real :: pf(NESP,klev)
- real :: pp(NSPP,klev)
- do jlev = 1 , klev
- call mpi_scatter(pf(:,jlev),NSPP,mpi_rtype &
- & ,pp(:,jlev),NSPP,mpi_rtype &
- & ,NROOT,myworld,mpinfo)
- enddo
- return
- end subroutine mpscsp
- ! =================
- ! SUBROUTINE MPGASP
- ! =================
- subroutine mpgasp(pf,pp,klev) ! gather spectral fields
- use mpimod
- real :: pf(NESP,klev)
- real :: pp(NSPP,klev)
- do jlev = 1 , klev
- call mpi_gather(pp(:,jlev),NSPP,mpi_rtype &
- & ,pf(:,jlev),NSPP,mpi_rtype &
- & ,NROOT,myworld,mpinfo)
- enddo
- return
- end subroutine mpgasp
- ! =================
- ! SUBROUTINE MPGACS
- ! =================
- subroutine mpgacs(pcs) ! gather cross sections
- use mpimod
- real :: pcs(NLAT,NLEV),l(NLPP)
- do jlev = 1 , NLEV
- l(:)=pcs(1:NLPP,jlev)
- call mpi_gather(l,NLPP,mpi_rtype &
- & ,pcs(:,jlev),NLPP,mpi_rtype &
- & ,NROOT,myworld,mpinfo)
- enddo
- return
- end subroutine mpgacs
- ! ===================
- ! SUBROUTINE MPGALLSP
- ! ===================
- subroutine mpgallsp(pf,pp,klev) ! gather spectral to all
- use mpimod
- real :: pf(NESP,klev)
- real :: pp(NSPP,klev)
- do jlev = 1 , klev
- call mpi_allgather(pp(:,jlev),NSPP,mpi_rtype &
- & ,pf(:,jlev),NSPP,mpi_rtype &
- & ,myworld,mpinfo)
- enddo
- return
- end subroutine mpgallsp
- ! ================
- ! SUBROUTINE MPSUM
- ! ================
- subroutine mpsum(psp,klev) ! sum spectral fields
- use mpimod
- real :: psp(NESP*klev)
- real :: tmp(NESP*klev)
- call mpi_reduce(psp,tmp,NESP*klev,mpi_rtype,MPI_SUM &
- & ,NROOT,myworld,mpinfo)
- if (mypid == NROOT) psp = tmp
- return
- end subroutine mpsum
- ! ==================
- ! SUBROUTINE MPSUMSC
- ! ==================
- subroutine mpsumsc(psf,psp,klev) ! sum & scatter spectral
- use mpimod
- real :: psf(NESP,klev)
- real :: psp(NSPP,klev)
- do jlev = 1 , klev
- call mpi_reduce_scatter(psf(:,jlev),psp(:,jlev),nscatsp &
- & ,mpi_rtype,MPI_SUM,myworld,mpinfo)
- enddo
- return
- end subroutine mpsumsc
- ! ====================
- ! SUBROUTINE MPSUMR
- ! ====================
- subroutine mpsumr(pr,kdim) ! sum kdim reals
- use mpimod
- real pr(kdim)
- real tmp(kdim)
- call mpi_reduce(pr,tmp,kdim,mpi_rtype,MPI_SUM,NROOT,myworld,mpinfo)
- if (mypid == NROOT) pr = tmp
- return
- end subroutine mpsumr
- ! ====================
- ! SUBROUTINE MPSUMBCR
- ! ====================
- subroutine mpsumbcr(pr,kdim) ! sum & broadcast kdim reals
- use mpimod
- real pr(kdim)
- real tmp(kdim)
- call mpi_allreduce(pr,tmp,kdim,mpi_rtype,MPI_SUM,myworld,mpinfo)
- pr = tmp
- return
- end subroutine mpsumbcr
- ! ==================
- ! SUBROUTINE MPABORT
- ! ==================
- subroutine mpabort(ym)
- use mpimod
- character (len=* ) :: ym
- character (len=64) :: ystar = ' '
- character (len=64) :: yline = ' '
- character (len=64) :: yabor = 'Program aborted'
- character (len=64) :: ymess = ' '
- character (len=64) :: yhead = ' '
- ilmess = len_trim(ym)
- ilabor = len_trim(yabor)
- ilen = 60
- do j = 1 , ilen+4
- ystar(j:j) = '*'
- yline(j:j) = '-'
- enddo
- ioff = 2
- if (ilmess < ilen-1) ioff = ioff + (ilen - ilmess) / 2
- ymess(1+ioff:ilmess+ioff) = trim(ym)
- ioff = 2
- if (ilabor < ilen-1) ioff = ioff + (ilen - ilabor) / 2
- yhead(1+ioff:ilabor+ioff) = trim(yabor)
- yline(1:1) = '*'
- ymess(1:1) = '*'
- yhead(1:1) = '*'
- yline(2:2) = ' '
- ymess(2:2) = ' '
- yhead(2:2) = ' '
- j = ilen + 4
- yline(j:j) = '*'
- ymess(j:j) = '*'
- yhead(j:j) = '*'
- j = ilen + 3
- yline(j:j) = ' '
- ymess(j:j) = ' '
- yhead(j:j) = ' '
- if (mypid == NROOT) then
- open (44,file='Abort_Message')
- write(44,'(A)') trim(ystar)
- write(44,'(A)') trim(yhead)
- write(44,'(A)') trim(yline)
- write(44,'(A)') trim(ymess)
- write(44,'(A)') trim(ystar)
- close(44)
- write(nud,'(/,A)') trim(ystar)
- write(nud,'(A)') trim(yhead)
- write(nud,'(A)') trim(yline)
- write(nud,'(A)') trim(ymess)
- write(nud,'(A,/)') trim(ystar)
- call mpi_abort(myworld,mpinfo,mpinfo)
- endif
- stop
- end
-
- ! ==================
- ! SUBROUTINE MPSTART
- ! ==================
- subroutine mpstart(kworld) ! initialization
- use mpimod
- integer :: itest = 0
- real :: rtest = 0.0
- logical :: ltest = .true.
- character (80) :: myympname
- if (kind(itest) == 8) mpi_itype = MPI_INTEGER8
- if (kind(rtest) == 8) mpi_rtype = MPI_REAL8
- if (kworld < 0) then
- call mpi_init(mpinfo)
- myworld=MPI_COMM_WORLD
- else
- myworld = kworld
- endif
- call mpi_comm_size(myworld,nproc,mpinfo)
- call mpi_comm_rank(myworld,mypid,mpinfo)
- if (nproc .ne. NPRO .and. mypid == NROOT) then
- write(nud,*)'Compiled for ',NPRO,' nodes'
- write(nud,*)'Running on ',nproc,' nodes'
- call mpi_abort(myworld,mpinfo,mpinfo)
- endif
- allocate(ympname(npro)) ; ympname(:) = ' '
- call mpi_get_processor_name(myympname,ilen,mpinfo)
- call mpi_gather(myympname,80,MPI_CHARACTER, &
- ympname,80,MPI_CHARACTER, &
- NROOT,myworld,mpinfo)
- return
- end subroutine mpstart
- ! =================
- ! SUBROUTINE MPSTOP
- ! =================
- subroutine mpstop
- use mpimod
- call mpi_barrier(myworld,mpinfo)
- call mpi_finalize(mpinfo)
- return
- end subroutine mpstop
- ! ===================
- ! SUBROUTINE MPREADGP
- ! ===================
- subroutine mpreadgp(ktape,p,kdim,klev)
- use mpimod
- real p(kdim,klev)
- real z(NLON*NLAT,klev)
- z = 0.0
- if (mypid == NROOT) read (ktape) z(:,:)
- if (kdim == NHOR) then
- call mpscgp(z,p,klev)
- else
- if (mypid == NROOT) p = z
- endif
- return
- end subroutine mpreadgp
- ! ====================
- ! SUBROUTINE MPWRITEGP
- ! ====================
- subroutine mpwritegp(ktape,p,kdim,klev)
- use mpimod
- real p(kdim,klev)
- real z(NLON*NLAT,klev)
- if (kdim == NHOR) then
- call mpgagp(z,p,klev)
- if (mypid == NROOT) write(ktape) z(1:NLON*NLAT,:)
- else
- if (mypid == NROOT) write(ktape) p(1:NLON*NLAT,:)
- endif
- return
- end subroutine mpwritegp
- ! =====================
- ! SUBROUTINE MPWRITEGPH
- ! =====================
- subroutine mpwritegph(ktape,p,kdim,klev,ihead)
- use mpimod
- real p(kdim,klev)
- real z(NLON*NLAT,klev)
- !
- real(kind=4) :: zp(kdim,klev)
- real(kind=4) :: zz(NLON*NLAT,klev)
- !
- integer ihead(8)
- if (kdim == NHOR) then
- call mpgagp(z,p,klev)
- if (mypid == NROOT) then
- write(ktape) ihead
- zz(:,:)=z(:,:)
- write(ktape) zz(1:NLON*NLAT,:)
- endif
- else
- if (mypid == NROOT) then
- write(ktape) ihead
- zp(:,:)=p(:,:)
- write(ktape) zp(1:NLON*NLAT,:)
- endif
- endif
- return
- end subroutine mpwritegph
- ! ===================
- ! SUBROUTINE MPREADSP
- ! ===================
- subroutine mpreadsp(ktape,p,kdim,klev)
- use mpimod
- real p(kdim,klev)
- real z(NESP,klev)
- z = 0.0
- if (mypid == NROOT) read(ktape) ((z(i,j),i=1,NRSP),j=1,klev)
- if (kdim == NSPP) then
- call mpscsp(z,p,klev)
- else
- if (mypid == NROOT) p = z
- endif
- return
- end subroutine mpreadsp
- ! ====================
- ! SUBROUTINE MPWRITESP
- ! ====================
- subroutine mpwritesp(ktape,p,kdim,klev)
- use mpimod
- real p(kdim,klev)
- real z(NESP,klev)
- if (kdim == NSPP) then
- call mpgasp(z,p,klev)
- if (mypid == NROOT) write(ktape) ((z(i,j),i=1,NRSP),j=1,klev)
- else
- if (mypid == NROOT) write(ktape) ((z(i,j),i=1,NRSP),j=1,klev)
- endif
- return
- end subroutine mpwritesp
- ! ===================
- ! SUBROUTINE GET_MPI_INFO
- ! ===================
- subroutine get_mpi_info(nprocess,npid) ! get nproc and pid
- use mpimod
- myworld=MPI_COMM_WORLD
- call mpi_comm_size(myworld,nprocess,mpinfo)
- call mpi_comm_rank(myworld,npid,mpinfo)
- return
- end subroutine get_mpi_info
- ! ==================
- ! SUBROUTINE MPGETSP
- ! ==================
- subroutine mpgetsp(yn,p,kdim,klev)
- use mpimod
- character (len=*) :: yn
- real :: p(kdim,klev)
- real :: z(NESP,klev)
- z(:,:) = 0.0
- if (mypid == NROOT) call get_restart_array(yn,z,NRSP,NESP,klev)
- call mpscsp(z,p,klev)
- return
- end subroutine mpgetsp
- ! ==================
- ! SUBROUTINE MPGETGP
- ! ==================
- subroutine mpgetgp(yn,p,kdim,klev)
- use mpimod
- character (len=*) :: yn
- real :: p(kdim,klev)
- real :: z(NUGP,klev)
- if (mypid == NROOT) call get_restart_array(yn,z,NUGP,NUGP,klev)
- call mpscgp(z,p,klev)
- return
- end subroutine mpgetgp
- ! ==================
- ! SUBROUTINE MPPUTSP
- ! ==================
- subroutine mpputsp(yn,p,kdim,klev)
- use mpimod
- character (len=*) :: yn
- real :: p(kdim,klev)
- real :: z(NESP,klev)
- call mpgasp(z,p,klev)
- if (mypid == NROOT) call put_restart_array(yn,z,NRSP,NESP,klev)
- return
- end subroutine mpputsp
- ! ==================
- ! SUBROUTINE MPPUTGP
- ! ==================
- subroutine mpputgp(yn,p,kdim,klev)
- use mpimod
- character (len=*) :: yn
- real :: p(kdim,klev)
- real :: z(NUGP,klev)
- call mpgagp(z,p,klev)
- if (mypid == NROOT) call put_restart_array(yn,z,NUGP,NUGP,klev)
- return
- end subroutine mpputgp
- ! ===================
- ! SUBROUTINE MPSURFGP
- ! ===================
- subroutine mpsurfgp(yn,p,kdim,klev)
- use mpimod
- character (len=*) :: yn
- real :: p(kdim,klev)
- real :: z(NUGP,klev)
- integer :: iread(1)
- if (mypid == NROOT) call get_surf_array(yn,z,NUGP,klev,iread)
- call mpbci(iread)
- if (iread(1) == 1) call mpscgp(z,p,klev)
- return
- end subroutine mpsurfgp
- ! ===================
- ! SUBROUTINE MPMAXVAL
- ! ===================
- subroutine mpmaxval(p,kdim,klev,pmax)
- use mpimod
- real :: p(kdim,klev)
- real :: pmax(1)
- real zmax(1)
- zmax(1) = maxval(p(:,:))
- call mpi_allreduce(zmax,pmax,1,mpi_rtype,MPI_MAX,myworld,mpinfo)
- return
- end subroutine mpmaxval
- ! ===================
- ! SUBROUTINE MPSUMVAL
- ! ===================
- subroutine mpsumval(p,kdim,klev,psum)
- use mpimod
- real :: p(kdim,klev)
- real :: psum(1)
- real :: zsum(1)
- zsum = sum(p(:,:))
- call mpi_allreduce(zsum,psum,1,mpi_rtype,MPI_SUM,myworld,mpinfo)
- return
- end subroutine mpsumval
- subroutine mrsum(k) ! sum up 1 integer
- return
- end
- subroutine mrbci(k) ! broadcast 1 integer
- return
- end
- subroutine mrdiff(p,d,n)
- real :: p(n)
- real :: d(n)
- return
- end
- subroutine mrdimensions ! used in mpimod_multi.f90
- return
- end
|