27 #if defined(use_libMPI)
28 #include <mpp_util_mpi.inc>
30 #include <mpp_util_nocomm.inc>
60 character(len=11) :: this_pe
82 if( pe.EQ.root_pe )
then
83 write(this_pe,
'(a,i6.6,a)')
'.',pe,
'.out'
84 inquire( file=trim(configfile)//this_pe, opened=opened )
88 open(newunit=log_unit, status=
'UNKNOWN', file=trim(configfile)//this_pe, position=
'APPEND', err=10 )
92 inquire(unit=etc_unit, opened=opened )
96 open(newunit=etc_unit, status=
'UNKNOWN', file=trim(etcfile), position=
'APPEND', err=11 )
101 10
call mpp_error( fatal,
'STDLOG: unable to open '//trim(configfile)//this_pe//
'.' )
102 11
call mpp_error( fatal,
'STDLOG: unable to open '//trim(etcfile)//
'.' )
106 subroutine mpp_init_logfile()
109 character(len=11) :: this_pe
110 if( pe.EQ.root_pe )
then
112 write(this_pe,
'(a,i6.6,a)')
'.',p,
'.out'
113 inquire( file=trim(configfile)//this_pe, exist=exist )
115 open(newunit=log_unit, file=trim(configfile)//this_pe, status=
'REPLACE' )
120 end subroutine mpp_init_logfile
125 character(len=11) :: this_pe
126 if( pe.EQ.root_pe )
then
127 write(this_pe,
'(a,i6.6,a)')
'.',pe,
'.out'
128 inquire( file=trim(warnfile)//this_pe, exist=exist )
130 open(newunit=warn_unit, file=trim(warnfile)//this_pe, status=
'REPLACE' )
132 open(newunit=warn_unit, file=trim(warnfile)//this_pe, status=
'NEW' )
141 if(.not. module_is_initialized)
call mpp_error(fatal,
"mpp_mod: warnlog cannot be called before mpp_init")
142 if(root_pe .eq. pe)
then
151 subroutine mpp_set_warn_level(flag)
152 integer,
intent(in) :: flag
154 if( flag.EQ.warning )
then
155 warnings_are_fatal = .false.
156 else if( flag.EQ.fatal )
then
157 warnings_are_fatal = .true.
159 call mpp_error( fatal,
'MPP_SET_WARN_LEVEL: warning flag must be set to WARNING or FATAL.' )
162 end subroutine mpp_set_warn_level
165 function mpp_error_state()
166 integer :: mpp_error_state
167 mpp_error_state = error_state
169 end function mpp_error_state
174 character(len=*),
intent(in) :: routine, errormsg
175 integer,
intent(in) :: errortype
177 call mpp_error( errortype, trim(routine)//
': '//trim(errormsg) )
182 subroutine mpp_error_noargs()
183 call mpp_error(fatal)
184 end subroutine mpp_error_noargs
187 subroutine mpp_error_is(errortype, errormsg1, mpp_ival, errormsg2)
188 integer,
intent(in) :: errortype
189 INTEGER,
intent(in) :: mpp_ival
190 character(len=*),
intent(in) :: errormsg1
191 character(len=*),
intent(in),
optional :: errormsg2
192 call mpp_error( errortype, errormsg1, (/mpp_ival/), errormsg2)
193 end subroutine mpp_error_is
195 subroutine mpp_error_rs(errortype, errormsg1, mpp_rval, errormsg2)
196 integer,
intent(in) :: errortype
197 REAL,
intent(in) :: mpp_rval
198 character(len=*),
intent(in) :: errormsg1
199 character(len=*),
intent(in),
optional :: errormsg2
200 call mpp_error( errortype, errormsg1, (/mpp_rval/), errormsg2)
201 end subroutine mpp_error_rs
203 subroutine mpp_error_ia(errortype, errormsg1, array, errormsg2)
204 integer,
intent(in) :: errortype
205 INTEGER,
dimension(:),
intent(in) :: array
206 character(len=*),
intent(in) :: errormsg1
207 character(len=*),
intent(in),
optional :: errormsg2
208 character(len=512) :: string
210 string = errormsg1//trim(array_to_char(array))
211 if(
present(errormsg2)) string = trim(string)//errormsg2
214 end subroutine mpp_error_ia
217 subroutine mpp_error_ra(errortype, errormsg1, array, errormsg2)
218 integer,
intent(in) :: errortype
219 REAL,
dimension(:),
intent(in) :: array
220 character(len=*),
intent(in) :: errormsg1
221 character(len=*),
intent(in),
optional :: errormsg2
222 character(len=512) :: string
224 string = errormsg1//trim(array_to_char(array))
225 if(
present(errormsg2)) string = trim(string)//errormsg2
228 end subroutine mpp_error_ra
231 #define _SUBNAME_ mpp_error_ia_ia
232 #define _ARRAY1TYPE_ integer
233 #define _ARRAY2TYPE_ integer
234 #include <mpp_error_a_a.fh>
239 #define _SUBNAME_ mpp_error_ia_ra
240 #define _ARRAY1TYPE_ integer
241 #define _ARRAY2TYPE_ real
242 #include <mpp_error_a_a.fh>
247 #define _SUBNAME_ mpp_error_ra_ia
248 #define _ARRAY1TYPE_ real
249 #define _ARRAY2TYPE_ integer
250 #include <mpp_error_a_a.fh>
255 #define _SUBNAME_ mpp_error_ra_ra
256 #define _ARRAY1TYPE_ real
257 #define _ARRAY2TYPE_ real
258 #include <mpp_error_a_a.fh>
263 #define _SUBNAME_ mpp_error_ia_is
264 #define _ARRAY1TYPE_ integer
265 #define _ARRAY2TYPE_ integer
266 #include <mpp_error_a_s.fh>
271 #define _SUBNAME_ mpp_error_ia_rs
272 #define _ARRAY1TYPE_ integer
273 #define _ARRAY2TYPE_ real
274 #include <mpp_error_a_s.fh>
279 #define _SUBNAME_ mpp_error_ra_is
280 #define _ARRAY1TYPE_ real
281 #define _ARRAY2TYPE_ integer
282 #include <mpp_error_a_s.fh>
287 #define _SUBNAME_ mpp_error_ra_rs
288 #define _ARRAY1TYPE_ real
289 #define _ARRAY2TYPE_ real
290 #include <mpp_error_a_s.fh>
295 #define _SUBNAME_ mpp_error_is_ia
296 #define _ARRAY1TYPE_ integer
297 #define _ARRAY2TYPE_ integer
298 #include <mpp_error_s_a.fh>
303 #define _SUBNAME_ mpp_error_is_ra
304 #define _ARRAY1TYPE_ integer
305 #define _ARRAY2TYPE_ real
306 #include <mpp_error_s_a.fh>
311 #define _SUBNAME_ mpp_error_rs_ia
312 #define _ARRAY1TYPE_ real
313 #define _ARRAY2TYPE_ integer
314 #include <mpp_error_s_a.fh>
319 #define _SUBNAME_ mpp_error_rs_ra
320 #define _ARRAY1TYPE_ real
321 #define _ARRAY2TYPE_ real
322 #include <mpp_error_s_a.fh>
327 #define _SUBNAME_ mpp_error_is_is
328 #define _ARRAY1TYPE_ integer
329 #define _ARRAY2TYPE_ integer
330 #include <mpp_error_s_s.fh>
335 #define _SUBNAME_ mpp_error_is_rs
336 #define _ARRAY1TYPE_ integer
337 #define _ARRAY2TYPE_ real
338 #include <mpp_error_s_s.fh>
343 #define _SUBNAME_ mpp_error_rs_is
344 #define _ARRAY1TYPE_ real
345 #define _ARRAY2TYPE_ integer
346 #include <mpp_error_s_s.fh>
351 #define _SUBNAME_ mpp_error_rs_rs
352 #define _ARRAY1TYPE_ real
353 #define _ARRAY2TYPE_ real
354 #include <mpp_error_s_s.fh>
359 function iarray_to_char(iarray)
result(string)
360 integer,
intent(in) :: iarray(:)
361 character(len=256) :: string
362 character(len=32) :: chtmp
363 integer :: i, len_tmp, len_string
367 write(chtmp,
'(i16)') iarray(i)
368 chtmp = adjustl(chtmp)
369 len_tmp = len_trim(chtmp)
370 len_string = len_trim(string)
371 string(len_string+1:len_string+len_tmp) = trim(chtmp)
372 string(len_string+len_tmp+1:len_string+len_tmp+1) =
','
374 len_string = len_trim(string)
375 string(len_string:len_string) =
' '
377 end function iarray_to_char
379 function rarray_to_char(rarray)
result(string)
380 real,
intent(in) :: rarray(:)
381 character(len=256) :: string
382 character(len=32) :: chtmp
383 integer :: i, len_tmp, len_string
387 write(chtmp,
'(G16.9)') rarray(i)
388 chtmp = adjustl(chtmp)
389 len_tmp = len_trim(chtmp)
390 len_string = len_trim(string)
391 string(len_string+1:len_string+len_tmp) = trim(chtmp)
392 string(len_string+len_tmp+1:len_string+len_tmp+1) =
','
394 len_string = len_trim(string)
395 string(len_string:len_string) =
' '
397 end function rarray_to_char
408 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_PE: You must first call mpp_init.' )
422 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_NPES: You must first call mpp_init.' )
423 mpp_npes =
size(peset(current_peset_num)%list(:))
428 function mpp_root_pe()
429 integer :: mpp_root_pe
431 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_ROOT_PE: You must first call mpp_init.' )
432 mpp_root_pe = root_pe
434 end function mpp_root_pe
437 type(mpi_comm) :: mpp_comm
439 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'mpp_comm: You must first call mpp_init.' )
440 mpp_comm = peset(current_peset_num)%comm
441 end function mpp_comm
443 function mpp_commid()
444 integer :: mpp_commid
446 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'mpp_commID: You must first call mpp_init.' )
447 call mpp_error(note,
"mpp_commID() is deprecated. Please use mpp_comm() instead.")
448 mpp_commid = peset(current_peset_num)%comm%mpi_val
449 end function mpp_commid
452 subroutine mpp_set_root_pe(num)
453 integer,
intent(in) :: num
455 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_ROOT_PE: You must first call mpp_init.' )
456 if( .NOT.(any(num.EQ.peset(current_peset_num)%list(:))) ) &
457 call mpp_error( fatal,
'MPP_SET_ROOT_PE: you cannot set a root PE outside the current pelist.' )
460 end subroutine mpp_set_root_pe
475 integer,
intent(in) :: pelist(:)
476 character(len=*),
intent(in),
optional :: name
477 type(mpi_comm),
intent(out),
optional :: comm
480 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_DECLARE_PELIST: You must first call mpp_init.' )
481 i = get_peset(pelist)
482 write( peset(i)%name,
'(a,i2.2)' )
'PElist', i
483 if(
PRESENT(name) ) peset(i)%name = name
484 if(
PRESENT(comm) )
then
489 subroutine mpp_declare_pelist_legacy( pelist, name, commID )
490 integer,
intent(in) :: pelist(:)
491 character(len=*),
intent(in),
optional :: name
492 integer,
intent(out) :: commID
493 type(mpi_comm) :: comm
496 commid = comm%mpi_val
497 end subroutine mpp_declare_pelist_legacy
521 integer,
intent(in),
optional :: pelist(:)
522 logical,
intent(in),
optional :: no_sync
524 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: You must first call mpp_init.' )
525 if(
PRESENT(pelist) )
then
526 if( .NOT.any(pe.EQ.pelist) )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: pe must be in pelist.' )
527 current_peset_num = get_peset(pelist)
529 current_peset_num = world_peset_num
531 call mpp_set_root_pe( minval(peset(current_peset_num)%list(:)) )
532 if(.not.
PRESENT(no_sync))
call mpp_sync()
538 function mpp_get_current_pelist_name()
540 character(len=len(peset(current_peset_num)%name)) :: mpp_get_current_pelist_name
542 mpp_get_current_pelist_name = peset(current_peset_num)%name
543 end function mpp_get_current_pelist_name
547 subroutine mpp_get_current_pelist_f08( pelist, name, comm )
548 integer,
intent(out) :: pelist(:)
549 character(len=*),
intent(out),
optional :: name
550 type(mpi_comm),
intent(out),
optional :: comm
552 if(
size(pelist(:)).NE.
size(peset(current_peset_num)%list(:)) ) &
553 call mpp_error( fatal,
'MPP_GET_CURRENT_PELIST: size(pelist) is wrong.' )
554 pelist(:) = peset(current_peset_num)%list(:)
555 if(
PRESENT(name) ) name = peset(current_peset_num)%name
556 if(
PRESENT(comm) )
then
557 comm = peset(current_peset_num)%comm
559 end subroutine mpp_get_current_pelist_f08
561 subroutine mpp_get_current_pelist_legacy( pelist, name, commID )
562 integer,
intent(out) :: pelist(:)
563 character(len=*),
intent(out),
optional :: name
564 integer,
intent(out) :: commID
565 type(mpi_comm) :: comm
567 call mpp_get_current_pelist_f08(pelist, name, comm)
568 commid = comm%mpi_val
569 end subroutine mpp_get_current_pelist_legacy
672 integer,
intent(in) :: grain
677 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_SET_GRAIN: You must first call mpp_init.' )
684 subroutine clock_init( id, name, flags, grain )
685 integer,
intent(in) :: id
686 character(len=*),
intent(in) :: name
687 integer,
intent(in),
optional :: flags, grain
690 clocks(id)%name = name
693 clocks(id)%total_ticks = 0
694 clocks(id)%sync_on_begin = .false.
695 clocks(id)%detailed = .false.
696 clocks(id)%peset_num = current_peset_num
697 if(
PRESENT(flags) )
then
698 if( btest(flags,0) )clocks(id)%sync_on_begin = .true.
699 if( btest(flags,1) )clocks(id)%detailed = .true.
702 if(
PRESENT(grain) )clocks(id)%grain = grain
703 if( clocks(id)%detailed )
then
704 allocate( clocks(id)%events(max_event_types) )
705 clocks(id)%events(event_allreduce)%name =
'ALLREDUCE'
706 clocks(id)%events(event_broadcast)%name =
'BROADCAST'
707 clocks(id)%events(event_recv)%name =
'RECV'
708 clocks(id)%events(event_send)%name =
'SEND'
709 clocks(id)%events(event_wait)%name =
'WAIT'
710 do i=1,max_event_types
711 clocks(id)%events(i)%ticks(:) = 0
712 clocks(id)%events(i)%bytes(:) = 0
713 clocks(id)%events(i)%calls = 0
715 clock_summary(id)%name = name
716 clock_summary(id)%event(event_allreduce)%name =
'ALLREDUCE'
717 clock_summary(id)%event(event_broadcast)%name =
'BROADCAST'
718 clock_summary(id)%event(event_recv)%name =
'RECV'
719 clock_summary(id)%event(event_send)%name =
'SEND'
720 clock_summary(id)%event(event_wait)%name =
'WAIT'
721 do i=1,max_event_types
722 clock_summary(id)%event(i)%msg_size_sums(:) = 0.0
723 clock_summary(id)%event(i)%msg_time_sums(:) = 0.0
724 clock_summary(id)%event(i)%total_data = 0.0
725 clock_summary(id)%event(i)%total_time = 0.0
726 clock_summary(id)%event(i)%msg_size_cnts(:) = 0
727 clock_summary(id)%event(i)%total_cnts = 0
731 end subroutine clock_init
737 character(len=*),
intent(in) :: name
738 integer,
intent(in),
optional :: flags, grain
740 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_ID: You must first call mpp_init.')
746 if(
PRESENT(grain) )
then
747 if( grain.GT.clock_grain )
then
754 if( clock_num.EQ.0 )
then
758 find_clock:
do while( trim(name).NE.trim(clocks(
mpp_clock_id)%name) )
762 call mpp_error( fatal,
'MPP_CLOCK_ID: too many clock requests, ' // &
763 'check your clock id request or increase MAX_CLOCKS.')
776 subroutine mpp_clock_begin(id)
777 integer,
intent(in) :: id
779 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: You must first call mpp_init.' )
780 if( .not. mpp_record_timing_data)
return
782 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
785 if( clocks(id)%peset_num.NE.current_peset_num ) &
786 call mpp_error( fatal,
'MPP_CLOCK_BEGIN: cannot change pelist context of a clock.' )
787 if( clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: mpp_clock_begin is called again '// &
788 'before calling mpp_clock_end for the clock '//trim(clocks(id)%name) )
789 if( clocks(id)%sync_on_begin .OR. sync_all_clocks )
then
797 num_clock_ids = num_clock_ids+1
798 if(num_clock_ids > max_clocks)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: max num previous_clock exceeded.' )
799 previous_clock(num_clock_ids) = current_clock
802 call system_clock( clocks(id)%tick )
803 clocks(id)%hits = clocks(id)%hits + 1
804 clocks(id)%is_on = .true.
807 end subroutine mpp_clock_begin
810 subroutine mpp_clock_end(id)
811 integer,
intent(in) :: id
812 integer(i8_kind) :: delta
815 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_END: You must first call mpp_init.' )
816 if( .not. mpp_record_timing_data)
return
818 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
820 if( .NOT. clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_END: mpp_clock_end is called '// &
821 'before calling mpp_clock_begin for the clock '//trim(clocks(id)%name) )
823 call system_clock(end_tick)
824 if( clocks(id)%peset_num.NE.current_peset_num ) &
825 call mpp_error( fatal,
'MPP_CLOCK_END: cannot change pelist context of a clock.' )
826 delta = end_tick - clocks(id)%tick
829 write( errunit,* )
'pe, id, start_tick, end_tick, delta, max_ticks=', pe, id, clocks(id)%tick, end_tick, &
831 delta = delta + max_ticks + 1
832 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
834 clocks(id)%total_ticks = clocks(id)%total_ticks + delta
836 if(num_clock_ids < 1)
call mpp_error(note,
'MPP_CLOCK_END: min num previous_clock < 1.' )
837 current_clock = previous_clock(num_clock_ids)
838 num_clock_ids = num_clock_ids-1
840 clocks(id)%is_on = .false.
843 end subroutine mpp_clock_end
846 subroutine mpp_record_time_start()
848 mpp_record_timing_data = .true.
850 end subroutine mpp_record_time_start
853 subroutine mpp_record_time_end()
855 mpp_record_timing_data = .false.
857 end subroutine mpp_record_time_end
861 subroutine increment_current_clock( event_id, bytes )
862 integer,
intent(in) :: event_id
863 integer,
intent(in),
optional :: bytes
865 integer(i8_kind) :: delta
868 if( .not. mpp_record_timing_data )
return
869 if( .not.debug .or. (current_clock.EQ.0) )
return
870 if( current_clock.LT.0 .OR. current_clock.GT.clock_num )
call mpp_error( fatal, &
871 &
'MPP_CLOCK_BEGIN: invalid current_clock.' )
872 if( .NOT.clocks(current_clock)%detailed )
return
873 call system_clock(end_tick)
874 n = clocks(current_clock)%events(event_id)%calls + 1
876 if( n.EQ.max_events )
call mpp_error( warning, &
877 'MPP_CLOCK: events exceed MAX_EVENTS, ignore detailed profiling data for clock '// &
878 & trim(clocks(current_clock)%name) )
879 if( n.GT.max_events )
return
881 clocks(current_clock)%events(event_id)%calls = n
882 delta = end_tick - start_tick
885 write( errunit,* )
'pe, event_id, start_tick, end_tick, delta, max_ticks=', &
886 pe, event_id, start_tick, end_tick, delta, max_ticks
887 delta = delta + max_ticks + 1
888 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
890 clocks(current_clock)%events(event_id)%ticks(n) = delta
891 if(
PRESENT(bytes) )clocks(current_clock)%events(event_id)%bytes(n) = bytes
893 end subroutine increment_current_clock
897 subroutine dump_clock_summary()
899 real :: total_time,total_time_all,total_data
900 real :: msg_size,eff_bw,s
901 integer :: sd_unit, total_calls
902 integer :: j,k,ct, msg_cnt
903 character(len=2) :: u
904 character(len=FMS_FILE_LEN) :: filename
905 character(len=20),
dimension(MAX_BINS),
save :: bin
907 data bin( 1) /
' 0 - 8 B: '/
908 data bin( 2) /
' 8 - 16 B: '/
909 data bin( 3) /
' 16 - 32 B: '/
910 data bin( 4) /
' 32 - 64 B: '/
911 data bin( 5) /
' 64 - 128 B: '/
912 data bin( 6) /
'128 - 256 B: '/
913 data bin( 7) /
'256 - 512 B: '/
914 data bin( 8) /
'512 - 1024 B: '/
915 data bin( 9) /
' 1.0 - 2.1 KB: '/
916 data bin(10) /
' 2.1 - 4.1 KB: '/
917 data bin(11) /
' 4.1 - 8.2 KB: '/
918 data bin(12) /
' 8.2 - 16.4 KB: '/
919 data bin(13) /
' 16.4 - 32.8 KB: '/
920 data bin(14) /
' 32.8 - 65.5 KB: '/
921 data bin(15) /
' 65.5 - 131.1 KB: '/
922 data bin(16) /
'131.1 - 262.1 KB: '/
923 data bin(17) /
'262.1 - 524.3 KB: '/
924 data bin(18) /
'524.3 - 1048.6 KB: '/
925 data bin(19) /
' 1.0 - 2.1 MB: '/
926 data bin(20) /
' >2.1 MB: '/
928 if( .NOT.any(clocks(1:clock_num)%detailed) )
return
929 write( filename,
'(a,i6.6)' )
'mpp_clock.out.', pe
931 open(newunit=sd_unit,file=trim(filename),form=
'formatted')
933 comm_type:
do ct = 1,clock_num
935 if( .NOT.clocks(ct)%detailed )cycle
937 clock_summary(ct)%name(1:15),
' Communication Data for PE ',pe
943 event_type:
do k = 1,max_event_types-1
945 if(clock_summary(ct)%event(k)%total_time == 0.0)cycle
947 total_time = clock_summary(ct)%event(k)%total_time
948 total_time_all = total_time_all + total_time
949 total_data = clock_summary(ct)%event(k)%total_data
950 total_calls = int(clock_summary(ct)%event(k)%total_cnts)
952 write(sd_unit,1000) clock_summary(ct)%event(k)%name(1:9) //
':'
954 write(sd_unit,1001)
'Total Data: ',total_data*1.0e-6, &
955 'MB; Total Time: ', total_time, &
956 'secs; Total Calls: ',total_calls
959 write(sd_unit,1002)
' Bin Counts Avg Size Eff B/W'
962 bin_loop:
do j=1,max_bins
964 if(clock_summary(ct)%event(k)%msg_size_cnts(j)==0)cycle
977 msg_cnt = int(clock_summary(ct)%event(k)%msg_size_cnts(j))
979 s*(clock_summary(ct)%event(k)%msg_size_sums(j)/real(msg_cnt))
980 eff_bw = (1.0e-6)*( clock_summary(ct)%event(k)%msg_size_sums(j) / &
981 clock_summary(ct)%event(k)%msg_time_sums(j) )
983 write(sd_unit,1003) bin(j),msg_cnt,msg_size,u,eff_bw
993 if(clock_summary(ct)%event(max_event_types)%total_time>0.0)
then
995 total_time = clock_summary(ct)%event(max_event_types)%total_time
996 total_time_all = total_time_all + total_time
997 total_calls = int(clock_summary(ct)%event(max_event_types)%total_cnts)
999 write(sd_unit,1000) clock_summary(ct)%event(max_event_types)%name(1:9) //
':'
1001 write(sd_unit,1004)
'Total Calls: ',total_calls,
'; Total Time: ', &
1006 write(sd_unit,*)
' '
1007 write(sd_unit,1005)
'Total communication time spent for ' // &
1008 clock_summary(ct)%name(1:9) //
': ',total_time_all,
'secs'
1009 write(sd_unit,*)
' '
1010 write(sd_unit,*)
' '
1011 write(sd_unit,*)
' '
1018 1001
format(a,f8.2,a,f8.2,a,i6)
1020 1003
format(a,i6,
' ',
' ',f9.1,a,
' ',f9.2,
'MB/sec')
1021 1004
format(a,i8,a,f9.2,a)
1022 1005
format(a,f9.2,a)
1024 end subroutine dump_clock_summary
1028 integer function get_unit()
1033 if (pe == root_pe)
call mpp_error(warning, &
1034 'get_unit is deprecated and will be removed in a future release, please use the Fortran intrinsic newunit')
1036 inquire(unit=i,opened=l_open)
1041 call mpp_error(fatal,
'Unable to get I/O unit')
1047 end function get_unit
1051 subroutine sum_clock_data()
1053 integer :: i,j,k,ct,event_size,event_cnt
1056 clock_type:
do ct=1,clock_num
1057 if( .NOT.clocks(ct)%detailed )cycle
1058 event_type:
do j=1,max_event_types-1
1059 event_cnt = clocks(ct)%events(j)%calls
1060 event_summary:
do i=1,event_cnt
1062 clock_summary(ct)%event(j)%total_cnts = &
1063 clock_summary(ct)%event(j)%total_cnts + 1
1065 event_size = int(clocks(ct)%events(j)%bytes(i))
1067 k = find_bin(event_size)
1069 clock_summary(ct)%event(j)%msg_size_cnts(k) = &
1070 clock_summary(ct)%event(j)%msg_size_cnts(k) + 1
1072 clock_summary(ct)%event(j)%msg_size_sums(k) = &
1073 clock_summary(ct)%event(j)%msg_size_sums(k) &
1074 + clocks(ct)%events(j)%bytes(i)
1076 clock_summary(ct)%event(j)%total_data = &
1077 clock_summary(ct)%event(j)%total_data &
1078 + clocks(ct)%events(j)%bytes(i)
1080 msg_time = clocks(ct)%events(j)%ticks(i)
1081 msg_time = tick_rate * real( clocks(ct)%events(j)%ticks(i) )
1083 clock_summary(ct)%event(j)%msg_time_sums(k) = &
1084 clock_summary(ct)%event(j)%msg_time_sums(k) + msg_time
1086 clock_summary(ct)%event(j)%total_time = &
1087 clock_summary(ct)%event(j)%total_time + msg_time
1089 end do event_summary
1096 event_cnt = clocks(ct)%events(j)%calls
1097 clock_summary(ct)%event(j)%msg_size_cnts(1) = event_cnt
1098 clock_summary(ct)%event(j)%total_cnts = event_cnt
1100 msg_time = tick_rate * real( sum( clocks(ct)%events(j)%ticks(1:event_cnt) ) )
1101 clock_summary(ct)%event(j)%msg_time_sums(1) = &
1102 clock_summary(ct)%event(j)%msg_time_sums(1) + msg_time
1104 clock_summary(ct)%event(j)%total_time = clock_summary(ct)%event(j)%msg_time_sums(1)
1110 integer function find_bin(event_size)
1112 integer,
intent(in) :: event_size
1113 integer :: k,msg_size
1117 do while(event_size>msg_size .and. k<max_bins)
1119 msg_size = msg_size*2
1123 end function find_bin
1125 end subroutine sum_clock_data
1131 integer :: old_peset_max,n
1132 type(communicator),
allocatable :: peset_old(:)
1134 old_peset_max = current_peset_max
1135 if(old_peset_max .GE. peset_max)
call mpp_error(fatal, &
1136 "mpp_mod(expand_peset): the number of peset reached PESET_MAX, increase PESET_MAX or contact developer")
1139 allocate(peset_old(0:old_peset_max))
1140 do n = 0, old_peset_max
1141 peset_old(n)%count = peset(n)%count
1142 peset_old(n)%comm = peset(n)%comm
1143 peset_old(n)%group = peset(n)%group
1144 peset_old(n)%name = peset(n)%name
1145 peset_old(n)%start = peset(n)%start
1146 peset_old(n)%log2stride = peset(n)%log2stride
1148 if(
ASSOCIATED(peset(n)%list) )
then
1149 allocate(peset_old(n)%list(
size(peset(n)%list(:))) )
1150 peset_old(n)%list(:) = peset(n)%list(:)
1151 deallocate(peset(n)%list)
1157 current_peset_max = min(peset_max, 2*old_peset_max)
1158 allocate(peset(0:current_peset_max))
1160 peset(:)%comm = mpi_comm_null
1161 peset(:)%group = mpi_group_null
1163 peset(:)%log2stride = -1
1165 do n = 0, old_peset_max
1166 peset(n)%count = peset_old(n)%count
1167 peset(n)%comm = peset_old(n)%comm
1168 peset(n)%group = peset_old(n)%group
1169 peset(n)%name = peset_old(n)%name
1170 peset(n)%start = peset_old(n)%start
1171 peset(n)%log2stride = peset_old(n)%log2stride
1173 if(
ASSOCIATED(peset_old(n)%list) )
then
1174 allocate(peset(n)%list(
size(peset_old(n)%list(:))) )
1175 peset(n)%list(:) = peset_old(n)%list(:)
1176 deallocate(peset_old(n)%list)
1179 deallocate(peset_old)
1181 call mpp_error(note,
"mpp_mod(expand_peset): size of peset is expanded to ", current_peset_max)
1186 function uppercase (cs)
1187 character(len=*),
intent(in) :: cs
1188 character(len=len(cs)),
target :: uppercase
1190 character,
pointer :: ca
1191 integer,
parameter :: co=iachar(
'A')-iachar(
'a')
1197 uppercase = cs(1:tlen)
1199 ca => uppercase(k:k)
1200 if(ca >=
"a" .and. ca <=
"z") ca = achar(ichar(ca)+co)
1203 end function uppercase
1207 function lowercase (cs)
1208 character(len=*),
intent(in) :: cs
1209 character(len=len(cs)),
target :: lowercase
1210 integer,
parameter :: co=iachar(
'a')-iachar(
'A')
1212 character,
pointer :: ca
1218 lowercase = cs(1:tlen)
1220 ca => lowercase(k:k)
1221 if(ca >=
"A" .and. ca <=
"Z") ca = achar(ichar(ca)+co)
1224 end function lowercase
1252 #include<file_version.h>
1254 character(len=*),
intent(in),
optional :: pelist_name_in
1255 character(len=*),
intent(in),
optional :: alt_input_nml_path
1259 integer,
dimension(2) :: lines_and_length
1260 logical :: file_exist
1261 character(len=len(peset(current_peset_num)%name)) :: pelist_name
1262 character(len=FMS_PATH_LEN) :: filename
1265 if (
allocated(input_nml_file) )
then
1266 deallocate(input_nml_file)
1270 if (
PRESENT(pelist_name_in))
then
1272 if (len(pelist_name_in) > len(pelist_name))
then
1273 call mpp_error(fatal, &
1274 "mpp_util.inc: read_input_nml optional argument pelist_name_in has size greater than local pelist_name")
1276 pelist_name = pelist_name_in
1279 pelist_name = mpp_get_current_pelist_name()
1281 filename=
'input_'//trim(pelist_name)//
'.nml'
1282 inquire(file=filename, exist=file_exist)
1283 if (.not. file_exist )
then
1284 if (
present(alt_input_nml_path))
then
1285 filename = alt_input_nml_path
1287 filename =
'input.nml'
1291 allocate(
character(len=lines_and_length(2))::input_nml_file(lines_and_length(1)))
1295 if (pe == root_pe)
then
1297 write(log_unit,
'(a)')
'========================================================================'
1298 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(version)
1299 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(filename)//
' '
1300 do i = 1, lines_and_length(1)
1301 write(log_unit,*) trim(input_nml_file(i))
1309 function get_ascii_file_num_lines(FILENAME, LENGTH, PELIST)
1310 character(len=*),
intent(in) :: FILENAME
1311 integer,
intent(in) :: LENGTH
1312 integer,
intent(in),
optional,
dimension(:) :: PELIST
1314 integer :: num_lines, get_ascii_file_num_lines
1315 character(len=LENGTH) :: str_tmp
1316 character(len=5) :: text
1317 integer :: status, f_unit, from_pe
1318 logical :: file_exist
1320 if( read_ascii_file_on)
then
1321 call mpp_error(fatal, &
1322 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1324 read_ascii_file_on = .true.
1327 get_ascii_file_num_lines = -1
1329 if ( pe == root_pe )
then
1330 inquire(file=filename, exist=file_exist)
1332 if ( file_exist )
then
1333 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1335 if ( status .ne. 0 )
then
1336 write (unit=text, fmt=
'(I5)') status
1337 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1338 '. (IOSTAT = '//trim(text)//
')')
1342 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1343 if ( status .lt. 0 )
then
1345 num_lines = max(num_lines - 1, 1)
1348 if ( status .gt. 0 )
then
1349 write (unit=text, fmt=
'(I5)') num_lines
1350 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1351 ' in file '//trim(filename)//
'.')
1353 if ( len_trim(str_tmp) == length )
then
1354 write(unit=text, fmt=
'(I5)') length
1355 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1356 &
' is too small. Increase the LENGTH value.')
1358 num_lines = num_lines + 1
1363 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1368 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1369 get_ascii_file_num_lines = num_lines
1371 end function get_ascii_file_num_lines
1376 character(len=*),
intent(in) :: filename
1377 integer,
intent(in),
optional,
dimension(:) :: pelist
1381 integer :: num_lines, max_length
1382 integer,
parameter :: length=1024
1383 character(len=LENGTH) :: str_tmp
1384 character(len=5) :: text
1385 integer :: status, f_unit, from_pe
1386 logical :: file_exist
1388 if( read_ascii_file_on)
then
1389 call mpp_error(fatal, &
1390 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1392 read_ascii_file_on = .true.
1398 if ( pe == root_pe )
then
1399 inquire(file=filename, exist=file_exist)
1401 if ( file_exist )
then
1402 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1404 if ( status .ne. 0 )
then
1405 write (unit=text, fmt=
'(I5)') status
1406 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1407 '. (IOSTAT = '//trim(text)//
')')
1412 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1413 if ( status .lt. 0 )
then
1415 num_lines = max(num_lines - 1, 1)
1418 if ( status .gt. 0 )
then
1419 write (unit=text, fmt=
'(I5)') num_lines
1420 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1421 ' in file '//trim(filename)//
'.')
1423 if ( len_trim(str_tmp) == length)
then
1424 write(unit=text, fmt=
'(I5)') length
1425 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1426 &
' is too small. Increase the LENGTH value.')
1428 if (len_trim(str_tmp) > max_length) max_length = len_trim(str_tmp)
1429 num_lines = num_lines + 1
1434 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1436 max_length = max_length+1
1440 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1441 call mpp_broadcast(max_length, from_pe, pelist=pelist)
1469 character(len=*),
intent(in) :: FILENAME
1470 integer,
intent(in) :: LENGTH
1471 character(len=*),
intent(inout),
dimension(:) :: Content
1472 integer,
intent(in),
optional,
dimension(:) :: PELIST
1475 #include<file_version.h>
1477 character(len=5) :: text
1478 logical :: file_exist
1479 integer :: status, f_unit, log_unit
1481 integer :: pnum_lines, num_lines
1482 character(len=LENGTH) :: str_tmp
1484 if( .NOT. read_ascii_file_on)
then
1485 call mpp_error(fatal, &
1486 "mpp_util.inc: get_ascii_file_num_lines needs to be called before calling read_ascii_file")
1488 read_ascii_file_on = .false.
1491 num_lines =
size(content(:))
1493 if ( pe == root_pe )
then
1496 write(log_unit,
'(a)')
'========================================================================'
1497 write(log_unit,
'(a)')
'READ_ASCII_FILE: '//trim(version)
1498 write(log_unit,
'(a)')
'READ_ASCII_FILE: File: '//trim(filename)
1500 inquire(file=filename, exist=file_exist)
1502 if ( file_exist )
then
1503 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1505 if ( status .ne. 0 )
then
1506 write (unit=text, fmt=
'(I5)') status
1507 call mpp_error(fatal,
'READ_ASCII_FILE: Error opening file: '// &
1508 & trim(filename)//
'. (IOSTAT = '//trim(text)//
')')
1511 if ( num_lines .gt. 0 )
then
1514 rewind(unit=f_unit, iostat=status)
1515 if ( status .ne. 0 )
then
1516 write (unit=text, fmt=
'(I5)') status
1517 call mpp_error(fatal,
'READ_ASCII_FILE: Unable to re-read file '//trim(filename)//
'. (IOSTAT = '&
1524 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1526 if ( status .lt. 0 )
then
1528 pnum_lines = max(pnum_lines - 1, 1)
1531 if ( status .gt. 0 )
then
1532 write (unit=text, fmt=
'(I5)') pnum_lines
1533 call mpp_error(fatal,
'READ_ASCII_FILE: Error reading line '// &
1534 & trim(text)//
' in file '//trim(filename)//
'.')
1536 if(pnum_lines > num_lines)
then
1537 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1538 ' is greater than size(Content(:)). ')
1540 if ( len_trim(str_tmp) == length )
then
1541 write(unit=text, fmt=
'(I5)') length
1542 call mpp_error(fatal,
'READ_ASCII_FILE: Length of output string ('//trim(text)// &
1543 &
' is too small. Increase the LENGTH value.')
1545 content(pnum_lines) = str_tmp
1546 pnum_lines = pnum_lines + 1
1548 if(num_lines .NE. pnum_lines)
then
1549 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1550 ' does not equal to size(Content(:)) ' )
1557 call mpp_error(fatal,
'READ_ASCII_FILE: File '//trim(filename)//
' does not exist.')
1562 call mpp_broadcast(content, length, from_pe, pelist=pelist)
1574 integer,
intent(in) :: x(:)
1575 integer,
intent(out) :: y(size(x))
1582 if (x(i).ge.1 .and. x(i).le.n)
then
1586 character(2) :: nstr
1588 write (nstr,
"(I0)") n
1589 call mpp_error(fatal,
"inverse_permutation: Invalid dimension map. &
1590 Values must be in the range from 1 to " // trim(nstr) //
".")
1595 if (any(y.eq.0))
then
1596 call mpp_error(fatal,
"inverse_permutation: Invalid dim_order. Values must be non-repeating.")
subroutine mpp_error_basic(errortype, errormsg)
A very basic error handler uses ABORT and FLUSH calls, may need to use cpp to rename.
integer function stdout()
This function returns the current standard fortran unit numbers for output.
subroutine read_ascii_file(FILENAME, LENGTH, Content, PELIST)
Reads any ascii file into a character array and broadcasts it to the non-root mpi-tasks....
subroutine mpp_init_warninglog()
Opens the warning log file, called during mpp_init.
subroutine mpp_error_mesg(routine, errormsg, errortype)
overloads to mpp_error_basic, support for error_mesg routine in FMS
subroutine mpp_set_current_pelist(pelist, no_sync)
Set context pelist.
integer function stderr()
This function returns the current standard fortran unit numbers for error messages.
subroutine read_input_nml(pelist_name_in, alt_input_nml_path)
Reads an existing input nml file into a character array and broadcasts it to the non-root mpi-tasks....
subroutine inverse_permutation(x, y)
Produce an inverse permutation. For example, transform [2, 3, 1, 4] to [3, 1, 2, 4].
subroutine mpp_clock_set_grain(grain)
Set the level of granularity of timing measurements.
integer function stdlog()
This function returns the current standard fortran unit numbers for log messages. Log messages,...
integer function mpp_npes()
Returns processor count for current pelist.
integer function, dimension(2) get_ascii_file_num_lines_and_length(FILENAME, PELIST)
Function to determine the maximum line length and number of lines from an ascii file.
integer function mpp_pe()
Returns processor ID.
subroutine mpp_sync(pelist, do_self)
Synchronize PEs in list.
integer function mpp_clock_id(name, flags, grain)
Return an ID for a new or existing clock.
integer function warnlog()
This function returns unit number for the warning log if on the root pe, otherwise returns the etc_un...
integer function stdin()
This function returns the current standard fortran unit numbers for input.
subroutine mpp_declare_pelist_f08(pelist, name, comm)
Declare a pelist.
subroutine expand_peset()
This routine will double the size of peset and copy the original peset data into the expanded one....