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
277 call mpi_finalize(ierr)
295 NUM_DOMAIN, & ! [in ]
296 PRC_DOMAINS, & ! [in ]
297 CONF_FILES, & ! [in ]
299 bulk_split, & ! [in ]
300 color_reorder, & ! [in ]
301 INTRA_COMM, & ! [out]
302 inter_parent, & ! [out]
303 inter_child, & ! [out]
307 integer,
intent(in) :: ORG_COMM
308 integer,
intent(in) :: NUM_DOMAIN
309 integer,
intent(in) :: PRC_DOMAINS(:)
310 character(len=H_LONG),
intent(in) :: CONF_FILES(:)
311 logical,
intent(in) :: LOG_SPLIT
312 logical,
intent(in) :: bulk_split
313 logical,
intent(in) :: color_reorder
315 integer,
intent(out) :: intra_comm
316 integer,
intent(out) :: inter_parent
317 integer,
intent(out) :: inter_child
318 character(len=H_LONG),
intent(out) :: fname_local
323 integer,
allocatable :: COLOR_LIST(:)
324 integer,
allocatable :: KEY_LIST(:)
326 integer :: total_nmax
327 integer :: ORG_myrank
332 logical :: reordering
335 character(len=4) :: col_num
338 integer :: itag, ierr
341 intra_comm = org_comm
342 inter_parent = mpi_comm_null
343 inter_child = mpi_comm_null
344 fname_local = conf_files(1)
346 if ( num_domain > 1 )
then 347 call mpi_comm_rank(org_comm,org_myrank,ierr)
348 call mpi_comm_size(org_comm,org_nmax, ierr)
349 allocate ( color_list(0:org_nmax-1) )
350 allocate ( key_list(0:org_nmax-1) )
354 total_nmax = total_nmax + prc_domains(i)
356 if ( total_nmax /= org_nmax )
then 359 if (
prc_universal_ismaster )
write (*,*)
"REQUESTED NPROCS = ", total_nmax,
" LAUNCHED NPROCS = ", org_nmax
363 reordering = color_reorder
364 if ( bulk_split )
then 367 call prc_mpicoloring( org_comm, &
382 call mpi_comm_split(org_comm, &
383 color_list(org_myrank), &
384 key_list(org_myrank), &
386 if ( bulk_split )
then 387 write(col_num,
'(I4.4)') color_list(org_myrank)
388 fname_local = col_num
391 fname_local = col_file(color_list(org_myrank))
395 do_create_p(:) = .false.
396 do_create_c(:) = .false.
397 if ( .NOT. bulk_split )
then 398 do i = 1, num_domain-1
401 "--- parent color = ", parent_col(i),
" child color = ", child_col(i)
402 if ( color_list(org_myrank) == parent_col(i) )
then 403 do_create_p(i) = .true.
404 elseif ( color_list(org_myrank) == child_col(i) )
then 405 do_create_c(i) = .true.
411 inter_parent = mpi_comm_null
412 inter_child = mpi_comm_null
413 if ( .NOT. bulk_split )
then 414 do i = 1, num_domain-1
416 if ( do_create_p(i) )
then 418 org_comm, prc_root(child_col(i)), &
419 itag, inter_child, ierr)
420 elseif ( do_create_c(i) )
then 422 org_comm, prc_root(parent_col(i)), &
423 itag, inter_parent, ierr)
425 call mpi_barrier(org_comm, ierr)
429 deallocate ( color_list, key_list )
431 elseif ( num_domain == 1 )
then 452 integer,
intent(in) :: ORG_COMM
453 integer,
intent(in) :: mem_np
454 integer,
intent(in) :: nitmax
455 integer,
intent(in) :: nprocs
456 integer,
intent(in) :: proc2mem(2,nitmax,nprocs)
457 integer,
intent(out) :: intra_comm
459 integer :: ORG_myrank
460 integer :: color, key
464 call mpi_comm_rank( org_comm, org_myrank, ierr)
466 if ( proc2mem(1,1,org_myrank+1) >= 1 )
then 467 color = proc2mem(1,1,org_myrank+1) - 1
468 key = proc2mem(2,1,org_myrank+1)
470 color = mpi_undefined
474 call mpi_comm_split( org_comm, &
484 subroutine prc_mpicoloring( &
486 NUM_DOMAIN, & ! [in ]
487 PRC_DOMAINS, & ! [in ]
488 CONF_FILES, & ! [in ]
489 color_reorder, & ! [in ]
491 COLOR_LIST, & ! [out]
494 PARENT_COL, & ! [out]
499 integer,
intent(in) :: ORG_COMM
500 integer,
intent(in) :: NUM_DOMAIN
501 integer,
intent(in) :: PRC_DOMAINS(:)
502 character(len=H_LONG),
intent(in) :: CONF_FILES(:)
503 logical,
intent(in) :: color_reorder
504 logical,
intent(in) :: LOG_SPLIT
505 integer,
intent(out) :: COLOR_LIST(:)
507 integer,
intent(out) :: KEY_LIST(:)
508 integer,
intent(out) :: PARENT_COL(:)
509 integer,
intent(out) :: CHILD_COL(:)
527 integer :: dnum, nprc, order, key
532 call mpi_comm_size(org_comm,org_nmax, ierr)
534 if ( color_reorder )
then 539 prc_order(:) = prc_domains(:)
540 call prc_sort_ascd( prc_order(1:num_domain), 1, num_domain )
544 if ( prc_domains(i) == prc_order(j) .AND. touch(j) < 0 )
then 546 col2dom(dom2col(i)) = i
559 if ( 1 <= id_parent .AND. id_parent <= num_domain )
then 560 parent_col(i) = dom2col(id_parent)
562 if ( 1 <= id_child .AND. id_child <= num_domain )
then 563 child_col(i) = dom2col(id_child)
567 write( *,
'(1X,A,I2,1X,A,I2,2(2X,A,I2))' ) &
568 "DOMAIN: ", i,
"MY_COL: ", dom2col(i), &
569 "PARENT: COL= ", parent_col(i),
"CHILD: COL= ", child_col(i)
578 ro_prc_domains(i) = prc_domains(dnum)
579 ro_dom2col(dnum) = dom2col(dnum)
580 ro_conf_files(i) = conf_files(dnum)
581 ro_parent_col(i) = parent_col(dnum)
582 ro_child_col(i) = child_col(dnum)
588 do i = 1, num_domain-1
589 parent_col(i) = ro_parent_col( dom2order(i+1) )
590 child_col(i) = ro_child_col( dom2order(i) )
596 if (
prc_universal_ismaster )
write ( *,
'(1X,A,I1,A,I5)' )
"NUM PRC_DOMAINS(",i,
") = ", ro_prc_domains(i)
597 if (
prc_universal_ismaster )
write ( *,
'(1X,A,I1,A,I3)' )
"MY COLOR(",i,
") = ", ro_dom2col(order2dom(i))
605 col_file(i-1) = ro_conf_files(i)
611 ro_prc_domains(:) = -1
612 ro_prc_domains(:) = -1
613 ro_parent_col(:) = -1
619 ro_prc_domains(i) = prc_domains(i)
620 ro_conf_files(i) = conf_files(i)
627 if ( 1 <= id_parent .AND. id_parent <= num_domain )
then 628 ro_parent_col(i) = ro_dom2col(id_parent)
630 if ( 1 <= id_child .AND. id_child <= num_domain )
then 631 ro_child_col(i) = ro_dom2col(id_child)
636 do i = 1, num_domain-1
637 parent_col(i) = ro_parent_col(i+1)
638 child_col(i) = ro_child_col(i )
646 nprc = ro_prc_domains(order)
650 color_list(i+1) = ro_dom2col(order2dom(order))
653 prc_root(color_list(i+1)) = i
654 col_file(color_list(i+1)) = ro_conf_files(order)
657 write ( *,
'(1X,4(A,I5))' )
"PE:", i,
" COLOR:", color_list(i+1), &
658 " KEY:", key_list(i+1),
" PRC_ROOT:", prc_root(color_list(i+1))
661 if ( key >= nprc )
then 664 nprc = ro_prc_domains(order)
669 end subroutine prc_mpicoloring
674 recursive subroutine prc_sort_ascd(a, top, bottom)
676 integer,
intent(inout) :: a(:)
677 integer,
intent(in) :: top, bottom
678 integer :: i, j, cnt, trg
680 cnt = a( (top+bottom) / 2 )
683 do while ( a(i) > cnt )
686 do while ( cnt > a(j) )
690 trg = a(i); a(i) = a(j); a(j) = trg
694 if ( top < i-1 )
call prc_sort_ascd( a, top, i-1 )
695 if ( j+1 < bottom )
call prc_sort_ascd( a, j+1, bottom )
697 end subroutine prc_sort_ascd
724 time =
real(MPI_WTIME(), kind=
dp)
742 real(DP),
intent(out) :: avgvar(:)
743 real(DP),
intent(out) :: maxvar(:)
744 real(DP),
intent(out) :: minvar(:)
745 integer,
intent(out) :: maxidx(:)
746 integer,
intent(out) :: minidx(:)
747 real(DP),
intent(in) :: var(:)
749 real(DP),
allocatable :: statval(:,:)
760 statval(:,:) = 0.0_dp
768 call mpi_bcast( statval(1,p), &
770 mpi_double_precision, &
779 totalvar = totalvar + statval(v,p)
783 maxvar(v) = maxval(statval(v,:))
784 minvar(v) = minval(statval(v,:))
785 maxidx(v:v) = maxloc(statval(v,:))
786 minidx(v:v) = minloc(statval(v,:))
789 deallocate( statval )
796 subroutine prc_mpi_errorhandler( &
805 character(len=MPI_MAX_ERROR_STRING) :: msg
828 if ( errcode == prc_abort_code )
then 829 elseif ( errcode <= mpi_err_lastcode )
then 830 call mpi_error_string(errcode, msg, len, ierr)
832 write(*,*)
'++++++ ', errcode, trim(msg)
834 if (
io_l )
write(
io_fid_log,*)
'++++++ Unexpected error code', errcode
835 write(*,*)
'++++++ Unexpected error code', errcode
840 write(*,*)
'++++++ Unexpected communicator' 861 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.