92 private :: prc_mpicoloring
93 private :: prc_sort_ascd
99 integer,
private,
parameter :: prc_abort_code = -1
111 integer,
intent(out) :: comm
122 comm = mpi_comm_world
134 integer,
intent(out) :: myrank
135 logical,
intent(out) :: ismaster
139 logical :: abortall = .false.
150 comm = mpi_comm_world
167 integer,
intent(in) :: comm
168 integer,
intent(out) :: nprocs
169 logical,
intent(out) :: ismaster
205 logical,
intent(in) :: abortall
206 integer,
intent(in) :: comm
240 integer,
intent(in) :: comm
241 integer,
intent(out) :: myrank
242 logical,
intent(out) :: ismaster
309 call mpi_finalize(ierr)
310 if(
io_l )
write(
io_fid_log,*)
'++++++ MPI is peacefully finalized' 326 NUM_DOMAIN, & ! [in ]
327 PRC_DOMAINS, & ! [in ]
328 CONF_FILES, & ! [in ]
330 bulk_split, & ! [in ]
331 color_reorder, & ! [in ]
332 INTRA_COMM, & ! [out]
333 inter_parent, & ! [out]
334 inter_child, & ! [out]
338 integer,
intent(in) :: org_comm
339 integer,
intent(in) :: num_domain
340 integer,
intent(in) :: prc_domains(:)
341 character(len=*),
intent(in) :: conf_files(:)
342 logical,
intent(in) :: log_split
343 logical,
intent(in) :: bulk_split
344 logical,
intent(in) :: color_reorder
345 integer,
intent(out) :: intra_comm
346 integer,
intent(out) :: inter_parent
347 integer,
intent(out) :: inter_child
348 character(len=H_LONG),
intent(out) :: fname_local
353 integer,
allocatable :: color_list(:)
354 integer,
allocatable :: key_list(:)
356 integer :: total_nmax
357 integer :: org_myrank
362 logical :: reordering
365 character(len=4) :: col_num
368 integer :: itag, ierr
371 intra_comm = org_comm
372 inter_parent = mpi_comm_null
373 inter_child = mpi_comm_null
374 fname_local = conf_files(1)
376 if ( num_domain > 1 )
then 377 call mpi_comm_rank(org_comm,org_myrank,ierr)
378 call mpi_comm_size(org_comm,org_nmax, ierr)
379 allocate( color_list(0:org_nmax-1) )
380 allocate( key_list(0:org_nmax-1) )
384 total_nmax = total_nmax + prc_domains(i)
386 if ( total_nmax /= org_nmax )
then 389 if(
prc_universal_ismaster )
write(*,*)
"REQUESTED NPROCS = ", total_nmax,
" LAUNCHED NPROCS = ", org_nmax
393 reordering = color_reorder
394 if ( bulk_split )
then 397 call prc_mpicoloring( org_comm, &
412 call mpi_comm_split(org_comm, &
413 color_list(org_myrank), &
414 key_list(org_myrank), &
416 if ( bulk_split )
then 417 write(col_num,
'(I4.4)') color_list(org_myrank)
418 fname_local = col_num
421 fname_local = col_file(color_list(org_myrank))
425 do_create_p(:) = .false.
426 do_create_c(:) = .false.
427 if ( .NOT. bulk_split )
then 428 do i = 1, num_domain-1
431 "--- parent color = ", parent_col(i),
" child color = ", child_col(i)
432 if ( color_list(org_myrank) == parent_col(i) )
then 433 do_create_p(i) = .true.
434 elseif ( color_list(org_myrank) == child_col(i) )
then 435 do_create_c(i) = .true.
441 inter_parent = mpi_comm_null
442 inter_child = mpi_comm_null
443 if ( .NOT. bulk_split )
then 444 do i = 1, num_domain-1
446 if ( do_create_p(i) )
then 448 org_comm, prc_root(child_col(i)), &
449 itag, inter_child, ierr )
450 elseif( do_create_c(i) )
then 452 org_comm, prc_root(parent_col(i)), &
453 itag, inter_parent, ierr )
455 call mpi_barrier(org_comm, ierr)
459 deallocate( color_list, key_list )
461 elseif ( num_domain == 1 )
then 482 integer,
intent(in) :: org_comm
483 integer,
intent(in) :: mem_np
484 integer,
intent(in) :: nitmax
485 integer,
intent(in) :: nprocs
486 integer,
intent(in) :: proc2mem(2,nitmax,nprocs)
487 integer,
intent(out) :: intra_comm
489 integer :: org_myrank
490 integer :: color, key
494 call mpi_comm_rank( org_comm, org_myrank, ierr )
496 if ( proc2mem(1,1,org_myrank+1) >= 1 )
then 497 color = proc2mem(1,1,org_myrank+1) - 1
498 key = proc2mem(2,1,org_myrank+1)
500 color = mpi_undefined
504 call mpi_comm_split( org_comm, &
515 subroutine prc_mpicoloring( &
517 NUM_DOMAIN, & ! [in ]
518 PRC_DOMAINS, & ! [in ]
519 CONF_FILES, & ! [in ]
520 color_reorder, & ! [in ]
522 COLOR_LIST, & ! [out]
525 PARENT_COL, & ! [out]
530 integer,
intent(in) :: org_comm
531 integer,
intent(in) :: num_domain
532 integer,
intent(in) :: prc_domains(:)
533 character(len=*),
intent(in) :: conf_files(:)
534 logical,
intent(in) :: color_reorder
535 logical,
intent(in) :: log_split
536 integer,
intent(out) :: color_list(:)
538 integer,
intent(out) :: key_list(:)
539 integer,
intent(out) :: parent_col(:)
540 integer,
intent(out) :: child_col(:)
558 integer :: dnum, nprc, order, key
563 call mpi_comm_size(org_comm,org_nmax, ierr)
565 if ( color_reorder )
then 570 prc_order(:) = prc_domains(:)
571 call prc_sort_ascd( prc_order(1:num_domain), 1, num_domain )
575 if ( prc_domains(i) == prc_order(j) .AND. touch(j) < 0 )
then 577 col2dom(dom2col(i)) = i
590 if ( 1 <= id_parent .AND. id_parent <= num_domain )
then 591 parent_col(i) = dom2col(id_parent)
593 if ( 1 <= id_child .AND. id_child <= num_domain )
then 594 child_col(i) = dom2col(id_child)
598 write( *,
'(1X,A,I2,1X,A,I2,2(2X,A,I2))' ) &
599 "DOMAIN: ", i,
"MY_COL: ", dom2col(i), &
600 "PARENT: COL= ", parent_col(i),
"CHILD: COL= ", child_col(i)
609 ro_prc_domains(i) = prc_domains(dnum)
610 ro_dom2col(dnum) = dom2col(dnum)
611 ro_conf_files(i) = conf_files(dnum)
612 ro_parent_col(i) = parent_col(dnum)
613 ro_child_col(i) = child_col(dnum)
619 do i = 1, num_domain-1
620 parent_col(i) = ro_parent_col( dom2order(i+1) )
621 child_col(i) = ro_child_col( dom2order(i) )
636 col_file(i-1) = ro_conf_files(i)
642 ro_prc_domains(:) = -1
643 ro_prc_domains(:) = -1
644 ro_parent_col(:) = -1
650 ro_prc_domains(i) = prc_domains(i)
651 ro_conf_files(i) = conf_files(i)
658 if ( 1 <= id_parent .AND. id_parent <= num_domain )
then 659 ro_parent_col(i) = ro_dom2col(id_parent)
661 if ( 1 <= id_child .AND. id_child <= num_domain )
then 662 ro_child_col(i) = ro_dom2col(id_child)
667 do i = 1, num_domain-1
668 parent_col(i) = ro_parent_col(i+1)
669 child_col(i) = ro_child_col(i )
677 nprc = ro_prc_domains(order)
681 color_list(i+1) = ro_dom2col(order2dom(order))
684 prc_root(color_list(i+1)) = i
685 col_file(color_list(i+1)) = ro_conf_files(order)
688 write ( *,
'(1X,4(A,I5))' )
"PE:", i,
" COLOR:", color_list(i+1), &
689 " KEY:", key_list(i+1),
" PRC_ROOT:", prc_root(color_list(i+1))
692 if ( key >= nprc )
then 695 nprc = ro_prc_domains(order)
700 end subroutine prc_mpicoloring
704 recursive subroutine prc_sort_ascd(a, top, bottom)
706 integer,
intent(inout) :: a(:)
707 integer,
intent(in) :: top, bottom
708 integer :: i, j, cnt, trg
710 cnt = a( (top+bottom) / 2 )
713 do while ( a(i) > cnt )
716 do while ( cnt > a(j) )
720 trg = a(i); a(i) = a(j); a(j) = trg
724 if ( top < i-1 )
call prc_sort_ascd( a, top, i-1 )
725 if ( j+1 < bottom )
call prc_sort_ascd( a, j+1, bottom )
727 end subroutine prc_sort_ascd
753 time =
real(MPI_WTIME(), kind=
dp)
771 real(DP),
intent(out) :: avgvar(:)
772 real(DP),
intent(out) :: maxvar(:)
773 real(DP),
intent(out) :: minvar(:)
774 integer,
intent(out) :: maxidx(:)
775 integer,
intent(out) :: minidx(:)
776 real(DP),
intent(in) :: var(:)
778 real(DP),
allocatable :: statval(:,:)
789 statval(:,:) = 0.0_dp
797 call mpi_bcast( statval(1,p), &
799 mpi_double_precision, &
808 totalvar = totalvar + statval(v,p)
812 maxvar(v) = maxval(statval(v,:))
813 minvar(v) = minval(statval(v,:))
814 maxidx(v:v) = maxloc(statval(v,:))
815 minidx(v:v) = minloc(statval(v,:))
818 deallocate( statval )
825 subroutine prc_mpi_errorhandler( &
834 character(len=MPI_MAX_ERROR_STRING) :: msg
857 if ( errcode == prc_abort_code )
then 859 elseif( errcode <= mpi_err_lastcode )
then 860 call mpi_error_string(errcode, msg, len, ierr)
862 write(*,*)
'++++++ ', errcode, trim(msg)
864 if(
io_l )
write(
io_fid_log,*)
'++++++ Unexpected error code', errcode
865 write(*,*)
'++++++ Unexpected error code', errcode
870 write(*,*)
'++++++ Unexpected communicator' 891 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.
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
subroutine, public prc_local_mpistart(myrank, ismaster)
Start MPI, without nesting, bulk job.
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
integer, parameter, public dp
subroutine, public prc_mpifinish
Stop MPI peacefully.