91 private :: prc_mpicoloring
92 private :: prc_sort_ascd
98 integer,
private,
parameter :: prc_abort_code = -1
110 integer,
intent(out) :: comm
121 comm = mpi_comm_world
134 integer,
intent(in) :: comm
135 integer,
intent(out) :: nprocs
136 logical,
intent(out) :: ismaster
172 logical,
intent(in) :: abortall
173 integer,
intent(in) :: comm
207 integer,
intent(in) :: comm
208 integer,
intent(out) :: myrank
209 logical,
intent(out) :: ismaster
276 call mpi_finalize(ierr)
277 if(
io_l )
write(
io_fid_log,*)
'++++++ MPI is peacefully finalized' 293 NUM_DOMAIN, & ! [in ]
294 PRC_DOMAINS, & ! [in ]
295 CONF_FILES, & ! [in ]
297 bulk_split, & ! [in ]
298 color_reorder, & ! [in ]
299 INTRA_COMM, & ! [out]
300 inter_parent, & ! [out]
301 inter_child, & ! [out]
305 integer,
intent(in) :: ORG_COMM
306 integer,
intent(in) :: NUM_DOMAIN
307 integer,
intent(in) :: PRC_DOMAINS(:)
308 character(len=H_LONG),
intent(in) :: CONF_FILES(:)
309 logical,
intent(in) :: LOG_SPLIT
310 logical,
intent(in) :: bulk_split
311 logical,
intent(in) :: color_reorder
313 integer,
intent(out) :: intra_comm
314 integer,
intent(out) :: inter_parent
315 integer,
intent(out) :: inter_child
316 character(len=H_LONG),
intent(out) :: fname_local
321 integer,
allocatable :: COLOR_LIST(:)
322 integer,
allocatable :: KEY_LIST(:)
324 integer :: total_nmax
325 integer :: ORG_myrank
330 logical :: reordering
333 character(len=4) :: col_num
336 integer :: itag, ierr
339 intra_comm = org_comm
340 inter_parent = mpi_comm_null
341 inter_child = mpi_comm_null
342 fname_local = conf_files(1)
344 if ( num_domain > 1 )
then 345 call mpi_comm_rank(org_comm,org_myrank,ierr)
346 call mpi_comm_size(org_comm,org_nmax, ierr)
347 allocate( color_list(0:org_nmax-1) )
348 allocate( key_list(0:org_nmax-1) )
352 total_nmax = total_nmax + prc_domains(i)
354 if ( total_nmax /= org_nmax )
then 357 if(
prc_universal_ismaster )
write(*,*)
"REQUESTED NPROCS = ", total_nmax,
" LAUNCHED NPROCS = ", org_nmax
361 reordering = color_reorder
362 if ( bulk_split )
then 365 call prc_mpicoloring( org_comm, &
380 call mpi_comm_split(org_comm, &
381 color_list(org_myrank), &
382 key_list(org_myrank), &
384 if ( bulk_split )
then 385 write(col_num,
'(I4.4)') color_list(org_myrank)
386 fname_local = col_num
389 fname_local = col_file(color_list(org_myrank))
393 do_create_p(:) = .false.
394 do_create_c(:) = .false.
395 if ( .NOT. bulk_split )
then 396 do i = 1, num_domain-1
399 "--- parent color = ", parent_col(i),
" child color = ", child_col(i)
400 if ( color_list(org_myrank) == parent_col(i) )
then 401 do_create_p(i) = .true.
402 elseif ( color_list(org_myrank) == child_col(i) )
then 403 do_create_c(i) = .true.
409 inter_parent = mpi_comm_null
410 inter_child = mpi_comm_null
411 if ( .NOT. bulk_split )
then 412 do i = 1, num_domain-1
414 if ( do_create_p(i) )
then 416 org_comm, prc_root(child_col(i)), &
417 itag, inter_child, ierr )
418 elseif( do_create_c(i) )
then 420 org_comm, prc_root(parent_col(i)), &
421 itag, inter_parent, ierr )
423 call mpi_barrier(org_comm, ierr)
427 deallocate( color_list, key_list )
429 elseif ( num_domain == 1 )
then 450 integer,
intent(in) :: ORG_COMM
451 integer,
intent(in) :: mem_np
452 integer,
intent(in) :: nitmax
453 integer,
intent(in) :: nprocs
454 integer,
intent(in) :: proc2mem(2,nitmax,nprocs)
455 integer,
intent(out) :: intra_comm
457 integer :: ORG_myrank
458 integer :: color, key
462 call mpi_comm_rank( org_comm, org_myrank, ierr )
464 if ( proc2mem(1,1,org_myrank+1) >= 1 )
then 465 color = proc2mem(1,1,org_myrank+1) - 1
466 key = proc2mem(2,1,org_myrank+1)
468 color = mpi_undefined
472 call mpi_comm_split( org_comm, &
483 subroutine prc_mpicoloring( &
485 NUM_DOMAIN, & ! [in ]
486 PRC_DOMAINS, & ! [in ]
487 CONF_FILES, & ! [in ]
488 color_reorder, & ! [in ]
490 COLOR_LIST, & ! [out]
493 PARENT_COL, & ! [out]
498 integer,
intent(in) :: ORG_COMM
499 integer,
intent(in) :: NUM_DOMAIN
500 integer,
intent(in) :: PRC_DOMAINS(:)
501 character(len=H_LONG),
intent(in) :: CONF_FILES(:)
502 logical,
intent(in) :: color_reorder
503 logical,
intent(in) :: LOG_SPLIT
504 integer,
intent(out) :: COLOR_LIST(:)
506 integer,
intent(out) :: KEY_LIST(:)
507 integer,
intent(out) :: PARENT_COL(:)
508 integer,
intent(out) :: CHILD_COL(:)
526 integer :: dnum, nprc, order, key
531 call mpi_comm_size(org_comm,org_nmax, ierr)
533 if ( color_reorder )
then 538 prc_order(:) = prc_domains(:)
539 call prc_sort_ascd( prc_order(1:num_domain), 1, num_domain )
543 if ( prc_domains(i) == prc_order(j) .AND. touch(j) < 0 )
then 545 col2dom(dom2col(i)) = i
558 if ( 1 <= id_parent .AND. id_parent <= num_domain )
then 559 parent_col(i) = dom2col(id_parent)
561 if ( 1 <= id_child .AND. id_child <= num_domain )
then 562 child_col(i) = dom2col(id_child)
566 write( *,
'(1X,A,I2,1X,A,I2,2(2X,A,I2))' ) &
567 "DOMAIN: ", i,
"MY_COL: ", dom2col(i), &
568 "PARENT: COL= ", parent_col(i),
"CHILD: COL= ", child_col(i)
577 ro_prc_domains(i) = prc_domains(dnum)
578 ro_dom2col(dnum) = dom2col(dnum)
579 ro_conf_files(i) = conf_files(dnum)
580 ro_parent_col(i) = parent_col(dnum)
581 ro_child_col(i) = child_col(dnum)
587 do i = 1, num_domain-1
588 parent_col(i) = ro_parent_col( dom2order(i+1) )
589 child_col(i) = ro_child_col( dom2order(i) )
604 col_file(i-1) = ro_conf_files(i)
610 ro_prc_domains(:) = -1
611 ro_prc_domains(:) = -1
612 ro_parent_col(:) = -1
618 ro_prc_domains(i) = prc_domains(i)
619 ro_conf_files(i) = conf_files(i)
626 if ( 1 <= id_parent .AND. id_parent <= num_domain )
then 627 ro_parent_col(i) = ro_dom2col(id_parent)
629 if ( 1 <= id_child .AND. id_child <= num_domain )
then 630 ro_child_col(i) = ro_dom2col(id_child)
635 do i = 1, num_domain-1
636 parent_col(i) = ro_parent_col(i+1)
637 child_col(i) = ro_child_col(i )
645 nprc = ro_prc_domains(order)
649 color_list(i+1) = ro_dom2col(order2dom(order))
652 prc_root(color_list(i+1)) = i
653 col_file(color_list(i+1)) = ro_conf_files(order)
656 write ( *,
'(1X,4(A,I5))' )
"PE:", i,
" COLOR:", color_list(i+1), &
657 " KEY:", key_list(i+1),
" PRC_ROOT:", prc_root(color_list(i+1))
660 if ( key >= nprc )
then 663 nprc = ro_prc_domains(order)
668 end subroutine prc_mpicoloring
672 recursive subroutine prc_sort_ascd(a, top, bottom)
674 integer,
intent(inout) :: a(:)
675 integer,
intent(in) :: top, bottom
676 integer :: i, j, cnt, trg
678 cnt = a( (top+bottom) / 2 )
681 do while ( a(i) > cnt )
684 do while ( cnt > a(j) )
688 trg = a(i); a(i) = a(j); a(j) = trg
692 if ( top < i-1 )
call prc_sort_ascd( a, top, i-1 )
693 if ( j+1 < bottom )
call prc_sort_ascd( a, j+1, bottom )
695 end subroutine prc_sort_ascd
721 time =
real(MPI_WTIME(), kind=
dp)
739 real(DP),
intent(out) :: avgvar(:)
740 real(DP),
intent(out) :: maxvar(:)
741 real(DP),
intent(out) :: minvar(:)
742 integer,
intent(out) :: maxidx(:)
743 integer,
intent(out) :: minidx(:)
744 real(DP),
intent(in) :: var(:)
746 real(DP),
allocatable :: statval(:,:)
757 statval(:,:) = 0.0_dp
765 call mpi_bcast( statval(1,p), &
767 mpi_double_precision, &
776 totalvar = totalvar + statval(v,p)
780 maxvar(v) = maxval(statval(v,:))
781 minvar(v) = minval(statval(v,:))
782 maxidx(v:v) = maxloc(statval(v,:))
783 minidx(v:v) = minloc(statval(v,:))
786 deallocate( statval )
793 subroutine prc_mpi_errorhandler( &
802 character(len=MPI_MAX_ERROR_STRING) :: msg
825 if ( errcode == prc_abort_code )
then 827 elseif( errcode <= mpi_err_lastcode )
then 828 call mpi_error_string(errcode, msg, len, ierr)
830 write(*,*)
'++++++ ', errcode, trim(msg)
832 if(
io_l )
write(
io_fid_log,*)
'++++++ Unexpected error code', errcode
833 write(*,*)
'++++++ Unexpected error code', errcode
838 write(*,*)
'++++++ Unexpected communicator' 859 end subroutine prc_mpi_errorhandler
logical, public prc_ismaster
master process in local communicator?
integer, public prc_local_comm_world
local communicator
subroutine, public prc_mpistop
Abort MPI.
logical, public prc_mpi_alive
MPI is alive?
logical, public prc_global_ismaster
master process in global communicator?
logical, public io_l
output log or not? (this process)
integer, public prc_universal_nprocs
process num in universal communicator
integer, parameter, public io_fid_stdout
subroutine, public prc_universal_setup(comm, nprocs, ismaster)
setup MPI in universal communicator
subroutine, public prc_mpisplit(ORG_COMM, NUM_DOMAIN, PRC_DOMAINS, CONF_FILES, LOG_SPLIT, bulk_split, color_reorder, INTRA_COMM, inter_parent, inter_child, fname_local)
MPI Communicator Split.
integer, public prc_universal_comm_world
original communicator
integer, public prc_universal_handler
error handler in universal communicator
logical, public prc_universal_ismaster
master process in universal communicator?
subroutine, public prc_mpitimestat(avgvar, maxvar, minvar, maxidx, minidx, var)
Calc global statistics for timer.
integer, parameter, public dp
subroutine, public prc_mpisplit_letkf(ORG_COMM, mem_np, nitmax, nprocs, proc2mem, INTRA_COMM)
MPI Communicator Split for SCALE-LETKF ensemble.
integer, public prc_global_comm_world
global communicator
real(dp) function, public prc_mpitime()
Get MPI time.
subroutine, public prc_global_setup(abortall, comm)
setup MPI in global communicator
integer, public prc_global_myrank
myrank in global communicator
subroutine, public prc_mpistart(comm)
Start MPI.
integer, parameter, public prc_masterrank
master process in each communicator
integer, public prc_myrank
process num in local communicator
integer, public prc_abort_handler
error handler communicator for aborting
integer, public prc_global_nprocs
process num in global communicator
integer, public prc_abort_comm_world
communicator for aborting
integer, parameter, public prc_domain_nlim
max depth of domains
integer, public prc_universal_jobid
my job ID in universal communicator
subroutine, public prc_local_setup(comm, myrank, ismaster)
Setup MPI.
integer, public io_fid_conf
Config file ID.
integer, public prc_global_domainid
my domain ID in global communicator
integer, public prc_universal_myrank
myrank in universal communicator
subroutine, public prc_mpibarrier
Barrier MPI.
integer, public io_fid_log
Log file ID.
integer, public prc_nprocs
myrank in local communicator
subroutine, public prc_mpifinish
Stop MPI peacefully.