10 use iso_fortran_env,
only : output_unit
17 use fckit_mpi_module,
only: fckit_mpi_comm,fckit_mpi_sum,fckit_mpi_status
23 integer,
parameter ::
ddis = 5
36 type(fckit_mpi_comm) :: f_comm
41 logical,
allocatable :: done(:)
44 character(len=1024) :: black
45 character(len=1024) :: green
46 character(len=1024) :: peach
47 character(len=1024) :: aqua
48 character(len=1024) :: purple
49 character(len=1024) :: err
50 character(len=1024) :: wng
53 character(len=1024) :: vunitchar
96 class(mpl_type),
intent(in) :: mpl
97 integer,
intent(out) :: lunit
105 inquire(unit=lun,opened=lopened)
106 if (.not.lopened)
then 113 if (lopened)
call mpl%abort(
'cannot find a free unit')
126 class(mpl_type),
intent(inout) :: mpl
129 mpl%f_comm = fckit_mpi_comm()
132 mpl%nproc = mpl%f_comm%size()
135 mpl%myproc = mpl%f_comm%rank()+1
139 mpl%main = (mpl%myproc==mpl%ioproc)
143 call system_clock(count=mpl%tag)
144 call mpl%update_tag(0)
146 call mpl%f_comm%broadcast(mpl%tag,mpl%ioproc-1)
164 class(mpl_type),
intent(inout) :: mpl
167 call mpl%f_comm%final
180 class(mpl_type),
intent(inout) :: mpl
181 character(len=*),
intent(in) :: prefix
182 character(len=*),
intent(in) :: model
183 logical,
intent(in) :: colorlog
184 logical,
intent(in) :: logpres
185 integer,
intent(in),
optional :: lunit
189 character(len=1024) :: filename
193 mpl%black = char(27)//
'[0;0m' 194 mpl%green = char(27)//
'[0;32m' 195 mpl%peach = char(27)//
'[1;91m' 196 mpl%aqua = char(27)//
'[1;36m' 197 mpl%purple = char(27)//
'[1;35m' 198 mpl%err = char(27)//
'[0;37;41;1m' 199 mpl%wng = char(27)//
'[0;37;42;1m' 211 if (trim(model)==
'online')
then 212 mpl%vunitchar =
'vert. unit' 215 mpl%vunitchar =
'log(Pa)' 217 mpl%vunitchar =
'lev.' 223 if (mpl%main.and.
present(lunit))
then 228 if (iproc==mpl%myproc)
then 230 call mpl%newunit(mpl%info)
233 write(filename,
'(a,i4.4)') trim(prefix)//
'.info.',mpl%myproc-1
234 open(unit=mpl%info,file=trim(filename),action=
'write',status=
'replace')
239 call mpl%f_comm%barrier
245 if (iproc==mpl%myproc)
then 247 call mpl%newunit(mpl%test)
250 write(filename,
'(a,i4.4)') trim(prefix)//
'.test.',mpl%myproc-1
251 open(unit=mpl%test,file=trim(filename),action=
'write',status=
'replace')
255 call mpl%f_comm%barrier
269 class(mpl_type),
intent(in) :: mpl
270 character(len=*),
intent(in) :: message
273 write(mpl%info,
'(a)') trim(mpl%err)//
'!!! Error: '//trim(message)//trim(mpl%black)
277 write(output_unit,
'(a,i4.4,a)')
'!!! ABORT on task #',mpl%myproc,
': '//trim(message)
278 call flush(output_unit)
284 call mpl%f_comm%abort(1)
297 class(mpl_type),
intent(in) :: mpl
298 character(len=*),
intent(in) :: message
301 write(mpl%info,
'(a)') trim(mpl%wng)//
'!!! Warning: '//trim(message)//trim(mpl%black)
315 class(mpl_type),
intent(inout) :: mpl
316 integer,
intent(in) :: nprog
319 write(mpl%info,
'(i3,a)',advance=
'no') 0,
'%' 323 if (
allocated(mpl%done))
deallocate(mpl%done)
324 allocate(mpl%done(nprog))
342 class(mpl_type),
intent(inout) :: mpl
343 integer,
intent(in),
optional :: i
346 real(kind_real) :: prog
349 if (
present(i)) mpl%done(i) = .true.
352 prog = 100.0*
real(count(mpl%done),kind_real)/
real(mpl%nprog,kind_real)
353 if (int(prog)>mpl%progint)
then 354 if (mpl%progint<100)
then 355 write(mpl%info,
'(i3,a)',advance=
'no') mpl%progint,
'% ' 358 mpl%progint = mpl%progint+
ddis 372 class(mpl_type),
intent(in) :: mpl
373 character(len=*),
intent(in) :: subr
374 integer,
intent(in) :: info
377 if (info/=nf90_noerr)
call mpl%abort(
'in '//trim(subr)//
': '//trim(nf90_strerror(info)))
390 class(mpl_type),
intent(inout) :: mpl
391 integer,
intent(in) :: add
394 mpl%tag = mpl%tag+add
397 mpl%tag = mod(mpl%tag,10000)
398 mpl%tag =
max(mpl%tag,1)
411 class(mpl_type),
intent(in) :: mpl
412 character(len=*),
dimension(:),
intent(inout) :: var
413 integer,
intent(in) :: root
420 call mpl%f_comm%broadcast(var(i),root)
434 class(mpl_type),
intent(in) :: mpl
435 real(kind_real),
intent(in) :: fld1(:)
436 real(kind_real),
intent(in) :: fld2(:)
437 real(kind_real),
intent(out) :: dp
440 real(kind_real) :: dp_loc(1),dp_out(1)
443 dp_loc(1) = sum(fld1*fld2)
446 call mpl%f_comm%allreduce(dp_loc,dp_out,fckit_mpi_sum())
451 call mpl%f_comm%broadcast(dp,mpl%ioproc-1)
464 class(mpl_type),
intent(in) :: mpl
465 real(kind_real),
intent(in) :: fld1(:,:)
466 real(kind_real),
intent(in) :: fld2(:,:)
467 real(kind_real),
intent(out) :: dp
470 real(kind_real) :: dp_loc(1),dp_out(1)
473 dp_loc(1) = sum(fld1*fld2)
476 call mpl%f_comm%allreduce(dp_loc,dp_out,fckit_mpi_sum())
480 call mpl%f_comm%broadcast(dp,mpl%ioproc-1)
493 class(mpl_type),
intent(in) :: mpl
494 real(kind_real),
intent(in) :: fld1(:,:,:)
495 real(kind_real),
intent(in) :: fld2(:,:,:)
496 real(kind_real),
intent(out) :: dp
499 real(kind_real) :: dp_loc(1),dp_out(1)
502 dp_loc(1) = sum(fld1*fld2)
505 call mpl%f_comm%allreduce(dp_loc,dp_out,fckit_mpi_sum())
509 call mpl%f_comm%broadcast(dp,mpl%ioproc-1)
522 class(mpl_type),
intent(in) :: mpl
523 real(kind_real),
intent(in) :: fld1(:,:,:,:)
524 real(kind_real),
intent(in) :: fld2(:,:,:,:)
525 real(kind_real),
intent(out) :: dp
528 real(kind_real) :: dp_loc(1),dp_out(1)
531 dp_loc(1) = sum(fld1*fld2)
534 call mpl%f_comm%allreduce(dp_loc,dp_out,fckit_mpi_sum())
538 call mpl%f_comm%broadcast(dp,mpl%ioproc-1)
546 subroutine mpl_split(mpl,n,i_s,i_e,n_loc)
551 class(mpl_type),
intent(in) :: mpl
552 integer,
intent(in) :: n
553 integer,
intent(out) :: i_s(mpl%nproc)
554 integer,
intent(out) :: i_e(mpl%nproc)
555 integer,
intent(out) :: n_loc(mpl%nproc)
558 integer :: iproc,nres,delta
566 i_s(iproc) = i_e(iproc-1)+1
569 if (nres>(mpl%nproc-iproc+1)*delta) delta = delta+1
570 i_e(iproc) = i_s(iproc)+delta-1
586 class(mpl_type),
intent(inout) :: mpl
587 integer,
intent(in) :: n_loc
588 integer,
intent(in) :: loc_to_glb(n_loc)
589 integer,
intent(in) :: n_glb
590 integer,
intent(out) :: glb_to_loc(n_glb)
593 integer :: iproc,i_loc,n_loc_tmp
594 integer,
allocatable :: loc_to_glb_tmp(:)
595 type(fckit_mpi_status) :: status
599 if (iproc==mpl%ioproc)
then 604 call mpl%f_comm%receive(n_loc_tmp,iproc-1,mpl%tag,status)
608 allocate(loc_to_glb_tmp(n_loc_tmp))
610 if (iproc==mpl%ioproc)
then 612 loc_to_glb_tmp = loc_to_glb
615 call mpl%f_comm%receive(loc_to_glb_tmp,iproc-1,mpl%tag+1,status)
620 glb_to_loc(loc_to_glb_tmp(i_loc)) = i_loc
624 deallocate(loc_to_glb_tmp)
628 call mpl%f_comm%send(n_loc,mpl%ioproc-1,mpl%tag)
631 call mpl%f_comm%send(loc_to_glb,mpl%ioproc-1,mpl%tag+1)
633 call mpl%update_tag(2)
636 call mpl%f_comm%broadcast(glb_to_loc,mpl%ioproc-1)
649 class(mpl_type),
intent(inout) :: mpl
650 integer,
intent(in) :: n_glb
651 integer,
intent(in) :: glb_to_proc(n_glb)
652 integer,
intent(in) :: glb_to_loc(n_glb)
653 real(kind_real),
intent(in) :: glb(:)
654 integer,
intent(in) :: n_loc
655 real(kind_real),
intent(out) :: loc(n_loc)
656 type(fckit_mpi_status) :: status
659 integer :: iproc,jproc,i_glb,i_loc,n_loc_tmp
660 real(kind_real),
allocatable :: sbuf(:)
664 if (
size(glb)/=n_glb)
call mpl%abort(
'wrong dimension for the global array in mpl_glb_to_loc_real_1d')
670 n_loc_tmp = count(glb_to_proc==iproc)
671 allocate(sbuf(n_loc_tmp))
675 jproc = glb_to_proc(i_glb)
676 if (iproc==jproc)
then 677 i_loc = glb_to_loc(i_glb)
678 sbuf(i_loc) = glb(i_glb)
682 if (iproc==mpl%ioproc)
then 687 call mpl%f_comm%send(sbuf,iproc-1,mpl%tag)
695 call mpl%f_comm%receive(loc,mpl%ioproc-1,mpl%tag,status)
697 call mpl%update_tag(1)
710 class(mpl_type),
intent(inout) :: mpl
711 integer,
intent(in) :: nl
712 integer,
intent(in) :: n_glb
713 integer,
intent(in) :: glb_to_proc(n_glb)
714 integer,
intent(in) :: glb_to_loc(n_glb)
715 real(kind_real),
intent(in) :: glb(:,:)
716 integer,
intent(in) :: n_loc
717 real(kind_real),
intent(out) :: loc(n_loc,nl)
720 integer :: iproc,jproc,i_glb,i_loc,n_loc_tmp,il
721 real(kind_real),
allocatable :: sbuf(:),rbuf(:)
722 type(fckit_mpi_status) :: status
726 if (
size(glb,1)/=n_glb)
call mpl%abort(
'wrong first dimension for the global array in mpl_glb_to_loc_real_2d')
727 if (
size(glb,2)/=nl)
call mpl%abort(
'wrong second dimension for the global array in mpl_glb_to_loc_real_2d')
731 allocate(rbuf(n_loc*nl))
735 n_loc_tmp = count(glb_to_proc==iproc)
736 allocate(sbuf(n_loc_tmp*nl))
740 jproc = glb_to_proc(i_glb)
741 if (iproc==jproc)
then 742 i_loc = glb_to_loc(i_glb)
744 sbuf((il-1)*n_loc_tmp+i_loc) = glb(i_glb,il)
749 if (iproc==mpl%ioproc)
then 754 call mpl%f_comm%send(sbuf,iproc-1,mpl%tag)
762 call mpl%f_comm%receive(rbuf,mpl%ioproc-1,mpl%tag,status)
764 call mpl%update_tag(1)
769 loc(i_loc,il) = rbuf((il-1)*n_loc+i_loc)
784 class(mpl_type),
intent(inout) :: mpl
785 integer,
intent(in) :: n_loc
786 real(kind_real),
intent(in) :: loc(n_loc)
787 integer,
intent(in) :: n_glb
788 integer,
intent(in) :: glb_to_proc(n_glb)
789 integer,
intent(in) :: glb_to_loc(n_glb)
790 logical,
intent(in) :: bcast
791 real(kind_real),
intent(out) :: glb(:)
792 type(fckit_mpi_status) :: status
795 integer :: iproc,jproc,i_glb,i_loc,n_loc_tmp
796 real(kind_real),
allocatable :: rbuf(:)
799 if (mpl%main.or.bcast)
then 800 if (
size(glb)/=n_glb)
call mpl%abort(
'wrong dimension for the global array in mpl_loc_to_glb_real_1d')
806 n_loc_tmp = count(glb_to_proc==iproc)
807 allocate(rbuf(n_loc_tmp))
809 if (iproc==mpl%ioproc)
then 814 call mpl%f_comm%receive(rbuf,iproc-1,mpl%tag,status)
819 jproc = glb_to_proc(i_glb)
820 if (iproc==jproc)
then 821 i_loc = glb_to_loc(i_glb)
822 glb(i_glb) = rbuf(i_loc)
831 call mpl%f_comm%send(loc,mpl%ioproc-1,mpl%tag)
833 call mpl%update_tag(1)
836 if (bcast)
call mpl%f_comm%broadcast(glb,mpl%ioproc-1)
849 class(mpl_type),
intent(inout) :: mpl
850 integer,
intent(in) :: nl
851 integer,
intent(in) :: n_loc
852 real(kind_real),
intent(in) :: loc(n_loc,nl)
853 integer,
intent(in) :: n_glb
854 integer,
intent(in) :: glb_to_proc(n_glb)
855 integer,
intent(in) :: glb_to_loc(n_glb)
856 logical,
intent(in) :: bcast
857 real(kind_real),
intent(out) :: glb(:,:)
860 integer :: iproc,jproc,i_glb,i_loc,n_loc_tmp,il
861 real(kind_real),
allocatable :: rbuf(:),sbuf(:)
862 type(fckit_mpi_status) :: status
865 if (mpl%main.or.bcast)
then 866 if (
size(glb,1)/=n_glb)
call mpl%abort(
'wrong first dimension for the global array in mpl_loc_to_glb_real_2d')
867 if (
size(glb,2)/=nl)
call mpl%abort(
'wrong second dimension for the global array in mpl_loc_to_glb_real_1d')
871 allocate(sbuf(n_loc*nl))
876 sbuf((il-1)*n_loc+i_loc) = loc(i_loc,il)
883 n_loc_tmp = count(glb_to_proc==iproc)
884 allocate(rbuf(n_loc_tmp*nl))
886 if (iproc==mpl%ioproc)
then 891 call mpl%f_comm%receive(rbuf,iproc-1,mpl%tag,status)
896 jproc = glb_to_proc(i_glb)
897 if (iproc==jproc)
then 898 i_loc = glb_to_loc(i_glb)
900 glb(i_glb,il) = rbuf((il-1)*n_loc_tmp+i_loc)
910 call mpl%f_comm%send(sbuf,mpl%ioproc-1,mpl%tag)
912 call mpl%update_tag(1)
915 if (bcast)
call mpl%f_comm%broadcast(glb,mpl%ioproc-1)
928 class(mpl_type),
intent(inout) :: mpl
929 integer,
intent(in) :: nl
930 integer,
intent(in) :: n_loc
931 logical,
intent(in) :: loc(n_loc,nl)
932 integer,
intent(in) :: n_glb
933 integer,
intent(in) :: glb_to_proc(n_glb)
934 integer,
intent(in) :: glb_to_loc(n_glb)
935 logical,
intent(in) :: bcast
936 logical,
intent(out) :: glb(:,:)
939 integer :: iproc,jproc,i_glb,i_loc,n_loc_tmp,il
940 logical,
allocatable :: rbuf(:),sbuf(:)
941 type(fckit_mpi_status) :: status
944 if (mpl%main.or.bcast)
then 945 if (
size(glb,1)/=n_glb)
call mpl%abort(
'wrong first dimension for the global array in mpl_loc_to_glb_real_2d')
946 if (
size(glb,2)/=nl)
call mpl%abort(
'wrong second dimension for the global array in mpl_loc_to_glb_real_1d')
950 allocate(sbuf(n_loc*nl))
955 sbuf((il-1)*n_loc+i_loc) = loc(i_loc,il)
962 n_loc_tmp = count(glb_to_proc==iproc)
963 allocate(rbuf(n_loc_tmp*nl))
965 if (iproc==mpl%ioproc)
then 970 call mpl%f_comm%receive(rbuf,iproc-1,mpl%tag,status)
975 jproc = glb_to_proc(i_glb)
976 if (iproc==jproc)
then 977 i_loc = glb_to_loc(i_glb)
979 glb(i_glb,il) = rbuf((il-1)*n_loc_tmp+i_loc)
989 call mpl%f_comm%send(sbuf,mpl%ioproc-1,mpl%tag)
991 call mpl%update_tag(1)
994 if (bcast)
call mpl%f_comm%broadcast(glb,mpl%ioproc-1)
subroutine mpl_newunit(mpl, lunit)
subroutine mpl_bcast_string_1d(mpl, var, root)
subroutine mpl_update_tag(mpl, add)
subroutine mpl_init_listing(mpl, prefix, model, colorlog, logpres, lunit)
subroutine mpl_prog_init(mpl, nprog)
subroutine mpl_ncerr(mpl, subr, info)
subroutine mpl_loc_to_glb_logical_2d(mpl, nl, n_loc, loc, n_glb, glb_to_proc, glb_to_loc, bcast, glb)
subroutine mpl_dot_prod_1d(mpl, fld1, fld2, dp)
subroutine mpl_loc_to_glb_real_2d(mpl, nl, n_loc, loc, n_glb, glb_to_proc, glb_to_loc, bcast, glb)
subroutine mpl_warning(mpl, message)
subroutine mpl_dot_prod_3d(mpl, fld1, fld2, dp)
subroutine mpl_prog_print(mpl, i)
subroutine mpl_dot_prod_2d(mpl, fld1, fld2, dp)
subroutine mpl_loc_to_glb_real_1d(mpl, n_loc, loc, n_glb, glb_to_proc, glb_to_loc, bcast, glb)
subroutine mpl_glb_to_loc_real_2d(mpl, nl, n_glb, glb_to_proc, glb_to_loc, glb, n_loc, loc)
subroutine, public dot_prod(fld1, fld2, zprod)
subroutine mpl_glb_to_loc_real_1d(mpl, n_glb, glb_to_proc, glb_to_loc, glb, n_loc, loc)
subroutine mpl_glb_to_loc_index(mpl, n_loc, loc_to_glb, n_glb, glb_to_loc)
subroutine mpl_split(mpl, n, i_s, i_e, n_loc)
integer, parameter, public kind_real
subroutine mpl_dot_prod_4d(mpl, fld1, fld2, dp)
integer, parameter lunit_max
subroutine mpl_final(mpl)
subroutine mpl_abort(mpl, message)
integer, parameter lunit_min