Go to the documentation of this file.
50 subroutine closer( skip_abort )
51 logical,
intent(in),
optional :: skip_abort
109 private :: prc_mpicoloring
110 private :: prc_sort_ascd
116 integer,
private,
parameter :: prc_abort_code = -1
120 procedure(closer),
pointer :: prc_file_closer => null()
130 integer,
intent(out) :: comm
141 comm = mpi_comm_world
156 integer,
intent(in) :: comm
157 integer,
intent(out) :: nprocs
158 integer,
intent(out) :: myrank
159 logical,
intent(out) :: ismaster
196 logical,
intent(in) :: abortall
197 integer,
intent(in) :: comm
231 integer,
intent(in) :: comm
232 integer,
intent(out) :: myrank
233 logical,
intent(out) :: ismaster
265 integer,
intent(in) :: comm
266 integer,
intent(out) :: nprocs
267 integer,
intent(out) :: myrank
268 logical,
intent(out) :: ismaster
273 call mpi_comm_size(comm,nprocs,ierr)
274 call mpi_comm_rank(comm,myrank,ierr)
315 logical,
intent(in) :: use_fpm
316 logical,
intent(in) :: master
369 logical :: sign_status
381 sign_status = .false.
383 do while ( .NOT. sign_exit )
404 call mpi_finalize(ierr)
421 integer,
intent(in) :: org_comm_world
422 integer,
intent(in) :: num_bulkjob
423 integer,
intent(in) :: prc_bulkjob(:)
424 logical,
intent(in) :: debug
425 integer,
intent(out) :: sub_comm_world
426 integer,
intent(out) :: id_bulkjob
428 integer :: org_myrank
432 integer,
allocatable :: prc2color (:)
433 integer,
allocatable :: prc2key (:)
439 logical :: color_reorder = .false.
442 integer :: itag, ierr
446 if ( num_bulkjob == 1 )
then
448 sub_comm_world = org_comm_world
452 elseif( num_bulkjob > 1 )
then
454 call mpi_comm_rank(org_comm_world,org_myrank,ierr)
455 call mpi_comm_size(org_comm_world,org_nrank ,ierr)
457 sum_nrank = sum(prc_bulkjob(1:num_bulkjob))
459 if ( sum_nrank /= org_nrank )
then
461 log_error(
"PRC_MPIsplit",*)
"MPI PROCESS NUMBER is INCONSISTENT"
462 log_error_cont(*)
" REQUESTED NPROCS = ", sum_nrank,
" LAUNCHED NPROCS = ", org_nrank
467 allocate( prc2color(0:org_nrank-1) )
468 allocate( prc2key(0:org_nrank-1) )
470 call prc_mpicoloring( org_comm_world, &
485 call mpi_comm_split( org_comm_world, &
486 prc2color(org_myrank), &
487 prc2key(org_myrank), &
491 do i = 1, num_bulkjob
496 id_bulkjob = prc2color(org_myrank)
499 deallocate( prc2color )
500 deallocate( prc2key )
504 log_error(
"PRC_MPIsplit",*)
"REQUESTED DOMAIN NUMBER IS NOT ACCEPTABLE"
524 integer,
intent(in) :: org_comm_world
525 integer,
intent(in) :: num_domain
526 integer,
intent(in) :: prc_domain(:)
527 logical,
intent(in) :: debug
528 logical,
intent(in) :: color_reorder
529 integer,
intent(out) :: sub_comm_world
530 integer,
intent(out) :: id_domain
532 integer :: org_myrank
536 integer,
allocatable :: prc2color (:)
537 integer,
allocatable :: prc2key (:)
544 integer :: itag, ierr
547 if ( num_domain == 1 )
then
549 sub_comm_world = org_comm_world
553 elseif( num_domain > 1 )
then
555 call mpi_comm_rank(org_comm_world,org_myrank,ierr)
556 call mpi_comm_size(org_comm_world,org_nrank ,ierr)
558 sum_nrank = sum(prc_domain(1:num_domain))
560 if ( sum_nrank /= org_nrank )
then
562 log_error(
"PRC_MPIsplit",*)
"MPI PROCESS NUMBER is INCONSISTENT"
563 log_error_cont(*)
" REQUESTED NPROCS = ", sum_nrank,
" LAUNCHED NPROCS = ", org_nrank
568 allocate( prc2color(0:org_nrank-1) )
569 allocate( prc2key(0:org_nrank-1) )
571 call prc_mpicoloring( org_comm_world, &
586 call mpi_comm_split( org_comm_world, &
587 prc2color(org_myrank), &
588 prc2key(org_myrank), &
592 id_domain = col_domain(prc2color(org_myrank))
597 write(*,*)
"INFO [PRC_MPIsplit] Inter-domain relationship information"
600 if ( col_parent(color) >= 0 )
then
601 write(*,
'(5x,A,I2.2)')
"Relationship No.", i
602 write(*,
'(5x,A,I2.2,A,A,I2.2)')
"Parent color: ", col_parent(color),
" <=> ", &
603 "Child color: ", color
611 if ( col_parent(color) >= 0 )
then
614 if ( prc2color(org_myrank) == col_parent(color) )
then
617 org_comm_world, col_master(color), &
620 elseif( prc2color(org_myrank) == color )
then
623 org_comm_world, col_master(col_parent(color)), &
628 call mpi_barrier(org_comm_world,ierr)
632 deallocate( prc2color )
633 deallocate( prc2key )
637 write(*,*)
"ERROR [RPC_MPIsplit] REQUESTED DOMAIN NUMBER IS NOT ACCEPTABLE"
647 subroutine prc_mpicoloring( &
663 integer,
intent(in) :: org_comm_world
664 integer,
intent(in) :: org_nrank
665 integer,
intent(in) :: num_subgroup
666 integer,
intent(in) :: prc_subgroup(:)
667 logical,
intent(in) :: color_reorder
668 logical,
intent(in) :: bulkjob
669 logical,
intent(in) :: debug
670 integer,
intent(out) :: prc2color (0:org_nrank-1)
671 integer,
intent(out) :: prc2key (0:org_nrank-1)
677 integer :: prc_reorder( num_subgroup)
678 integer :: dom2col ( num_subgroup)
679 integer :: col2dom (0:num_subgroup-1)
680 logical :: touch (0:num_subgroup-1)
685 integer :: i, domain, color, p
689 if ( color_reorder .AND. .NOT. bulkjob )
then
691 prc_reorder(1:num_subgroup) = prc_subgroup(1:num_subgroup)
692 call prc_sort_ascd( prc_reorder(1:num_subgroup), 1, num_subgroup )
695 do domain = 1, num_subgroup
696 do i = num_subgroup, 1, -1
698 if ( prc_subgroup(domain) == prc_reorder(i) .AND. ( .NOT. touch(color) ) )
then
699 dom2col(domain) = color
700 col2dom(color) = domain
701 touch(color) = .true.
709 do domain = 1, num_subgroup
711 dom2col(domain) = color
712 col2dom(color) = domain
720 if ( .NOT. bulkjob )
then
721 do i = 1, num_subgroup
725 if ( id_parent >= 1 .AND. id_parent <= num_subgroup )
then
726 col_parent(dom2col(i)) = dom2col(id_parent)
728 if ( id_child >= 1 .AND. id_child <= num_subgroup )
then
729 col_child(dom2col(i)) = dom2col(id_child)
733 write(*,
'(4(A,I2))') &
734 "DOMAIN: ", i,
", MY COL: ", dom2col(i),
", PARENT COL:", col_parent(i),
", CHILD COL:", col_child(i)
741 write(*,*)
'INFO [PRC_MPIcoloring] Domain information'
742 write(*,
'(5x,A,L2)')
'Reordering? : ', color_reorder
743 do i = 1, num_subgroup
745 domain = col2dom(color)
747 write(*,
'(5x,2(A,I2.2))')
"Order No. ", i,
" -> Domain No. ", domain
748 write(*,
'(5x,A,I5)')
"Number of process = ", prc_subgroup(domain)
749 write(*,
'(5x,A,I5)')
"Color of this domain = ", color
750 if ( col_parent(color) >= 0 )
then
751 write(*,
'(5x,A,I5)')
"Color of parent domain = ", col_parent(color)
753 write(*,
'(5x,A)' )
"Color of parent domain = no parent"
755 if ( col_child(color) >= 0 )
then
756 write(*,
'(5x,A,I5)')
"Color of child domain = ", col_child(color)
758 write(*,
'(5x,A)' )
"Color of child domain = no child"
766 domain = col2dom(color)
767 nprc = prc_subgroup(domain)
770 do p = 0, org_nrank-1
775 col_domain(color) = domain
776 col_master(color) = p
780 write(*,
'(5x,4(A,I5))') &
781 "PE:", p,
" COLOR:", prc2color(p),
" KEY:", prc2key(p),
" COL_master:", col_master(color)
785 if ( key >= nprc )
then
788 if ( color < num_subgroup )
then
789 domain = col2dom(color)
790 nprc = prc_subgroup(domain)
796 end subroutine prc_mpicoloring
800 recursive subroutine prc_sort_ascd(a, top, bottom)
802 integer,
intent(inout) :: a(:)
803 integer,
intent(in) :: top, bottom
804 integer :: i, j, cnt, trg
806 cnt = a( (top+bottom) / 2 )
809 do while ( a(i) > cnt )
812 do while ( cnt > a(j) )
816 trg = a(i); a(i) = a(j); a(j) = trg
820 if ( top < i-1 )
call prc_sort_ascd( a, top, i-1 )
821 if ( j+1 < bottom )
call prc_sort_ascd( a, j+1, bottom )
823 end subroutine prc_sort_ascd
849 time = real(mpi_wtime(), kind=
dp)
867 real(
dp),
intent(out) :: avgvar(:)
868 real(
dp),
intent(out) :: maxvar(:)
869 real(
dp),
intent(out) :: minvar(:)
870 integer,
intent(out) :: maxidx(:)
871 integer,
intent(out) :: minidx(:)
872 real(
dp),
intent(in) :: var(:)
874 real(
dp),
allocatable :: statval(:,:)
885 statval(:,:) = 0.0_dp
893 call mpi_bcast( statval(1,p), &
895 mpi_double_precision, &
904 totalvar = totalvar + statval(v,p)
908 maxvar(v) = maxval(statval(v,:))
909 minvar(v) = minval(statval(v,:))
910 maxidx(v:v) = maxloc(statval(v,:))
911 minidx(v:v) = minloc(statval(v,:))
914 deallocate( statval )
927 integer,
intent(in) :: rapnlimit
928 integer,
intent(inout) :: rapnmax
929 real(
dp),
intent(inout) :: rapttot(rapnlimit)
930 character(len=H_SHORT),
intent(in) :: rapname(rapnlimit)
933 character(len=H_SHORT) :: rapname0
934 real(
dp) :: rapttot0(rapnlimit)
947 if ( rapname(j) == rapname0 )
then
948 rapttot0(i) = rapttot(j)
952 if ( j > rapnmax )
then
960 rapttot(i) = rapttot0(i)
967 subroutine prc_mpi_errorhandler( &
976 character(len=MPI_MAX_ERROR_STRING) :: msg
979 logical :: sign_status
987 sign_status = .false.
989 do while ( .NOT. sign_exit )
998 log_progress(*)
'abort MPI'
1011 if ( errcode == prc_abort_code )
then
1013 elseif( errcode <= mpi_err_lastcode )
then
1014 call mpi_error_string(errcode, msg, len, ierr)
1016 write(*,*)
'+++++ ', errcode, trim(msg)
1018 if(
io_l )
write(
io_fid_log,*)
'+++++ Unexpected error code', errcode
1019 write(*,*)
'+++++ Unexpected error code', errcode
1024 write(*,*)
'+++++ Unexpected communicator'
1030 if (
associated( prc_file_closer ) )
call prc_file_closer( .true. )
1045 end subroutine prc_mpi_errorhandler
1048 procedure(closer) :: routine
1050 prc_file_closer => routine
logical, public prc_universal_ismaster
master process in universal communicator?
subroutine, public prc_abort
Abort Process.
subroutine, public prc_universal_setup(comm, nprocs, myrank, ismaster)
setup MPI in universal communicator
integer, public prc_abort_handler
error handler communicator for aborting
subroutine, public prc_mpisplit_bulk(ORG_COMM_WORLD, NUM_BULKJOB, PRC_BULKJOB, debug, SUB_COMM_WORLD, ID_BULKJOB)
MPI Communicator Split (bulk job)
subroutine, public prc_global_setup(abortall, comm)
setup MPI in global communicator
subroutine, public prc_set_file_closer(routine)
integer, public prc_local_comm_world
local communicator
subroutine, public prc_mpisplit_nest(ORG_COMM_WORLD, NUM_DOMAIN, PRC_DOMAIN, debug, color_reorder, SUB_COMM_WORLD, ID_DOMAIN)
MPI Communicator Split (nesting)
subroutine, public prc_mpistart(comm)
Start MPI.
integer, public prc_myrank
process num in local communicator
subroutine, public fpm_polling(run_stat, stop_signal)
Main system of FPM.
logical, public prc_mpi_alive
MPI is alive?
integer, public prc_universal_myrank
myrank in universal communicator
subroutine, public prc_local_setup(comm, myrank, ismaster)
Setup MPI in local communicator.
integer, public prc_universal_jobid
my job ID in universal communicator
subroutine, public prc_mpibarrier
Barrier MPI.
integer, parameter, public prc_comm_null
integer, parameter, public prc_masterrank
master process in each communicator
logical, public prc_global_ismaster
master process in global communicator?
subroutine, public prc_errhandler_setup(use_fpm, master)
Setup MPI error handler.
integer, public io_fid_log
Log file ID.
integer, dimension(prc_domain_nlim), public prc_global_root
root processes in global members
integer, parameter, public h_short
Character length (short=16)
subroutine, public prc_timereorder(rapnlimit, rapnmax, rapttot, rapname)
reorder rap time
integer, public prc_global_myrank
myrank in global communicator
integer, parameter, public prc_domain_nlim
max depth of domains
integer, public prc_universal_comm_world
original communicator
integer, parameter, public dp
integer, public prc_global_domainid
my domain ID in global communicator
integer, public prc_abort_comm_world
communicator for aborting
logical, public fpm_alive
integer, public prc_intercomm_child
communicator between this rank and child domain
integer, public prc_nprocs
myrank in local communicator
integer, public prc_intercomm_parent
communicator between this rank and parent domain
integer, public prc_universal_handler
error handler in universal communicator
logical, public io_l
output log or not? (this process)
subroutine, public prc_mpitimestat(avgvar, maxvar, minvar, maxidx, minidx, var)
Calc global statistics for timer.
subroutine, public prc_singlecom_setup(comm, nprocs, myrank, ismaster)
Setup MPI single communicator (not use universal-global-local setting)
integer, parameter, public io_fid_stdout
integer, public prc_global_comm_world
global communicator
subroutine, public sigvars_get_all(master)
Get signal values.
real(dp) function, public prc_mpitime()
Get MPI time.
subroutine, public prc_mpifinish
Stop MPI peacefully.
integer, public prc_universal_nprocs
process num in universal communicator
integer, public prc_global_nprocs
process num in global communicator
integer(c_int), public sigint
integer, public io_fid_conf
Config file ID.
logical, public prc_ismaster
master process in local communicator?