28 #if defined(use_libMPI)
29 #include <mpp_util_mpi.inc>
31 #include <mpp_util_nocomm.inc>
61 character(len=11) :: this_pe
83 if( pe.EQ.root_pe )
then
84 write(this_pe,
'(a,i6.6,a)')
'.',pe,
'.out'
85 inquire( file=trim(configfile)//this_pe, opened=opened )
89 open(newunit=log_unit, status=
'UNKNOWN', file=trim(configfile)//this_pe, position=
'APPEND', err=10 )
93 inquire(unit=etc_unit, opened=opened )
97 open(newunit=etc_unit, status=
'UNKNOWN', file=trim(etcfile), position=
'APPEND', err=11 )
102 10
call mpp_error( fatal,
'STDLOG: unable to open '//trim(configfile)//this_pe//
'.' )
103 11
call mpp_error( fatal,
'STDLOG: unable to open '//trim(etcfile)//
'.' )
107 subroutine mpp_init_logfile()
110 character(len=11) :: this_pe
111 if( pe.EQ.root_pe )
then
113 write(this_pe,
'(a,i6.6,a)')
'.',p,
'.out'
114 inquire( file=trim(configfile)//this_pe, exist=exist )
116 open(newunit=log_unit, file=trim(configfile)//this_pe, status=
'REPLACE' )
121 end subroutine mpp_init_logfile
126 character(len=11) :: this_pe
127 if( pe.EQ.root_pe )
then
128 write(this_pe,
'(a,i6.6,a)')
'.',pe,
'.out'
129 inquire( file=trim(warnfile)//this_pe, exist=exist )
131 open(newunit=warn_unit, file=trim(warnfile)//this_pe, status=
'REPLACE' )
133 open(newunit=warn_unit, file=trim(warnfile)//this_pe, status=
'NEW' )
142 if(.not. module_is_initialized)
call mpp_error(fatal,
"mpp_mod: warnlog cannot be called before mpp_init")
143 if(root_pe .eq. pe)
then
152 subroutine mpp_set_warn_level(flag)
153 integer,
intent(in) :: flag
155 if( flag.EQ.warning )
then
156 warnings_are_fatal = .false.
157 else if( flag.EQ.fatal )
then
158 warnings_are_fatal = .true.
160 call mpp_error( fatal,
'MPP_SET_WARN_LEVEL: warning flag must be set to WARNING or FATAL.' )
163 end subroutine mpp_set_warn_level
166 function mpp_error_state()
167 integer :: mpp_error_state
168 mpp_error_state = error_state
170 end function mpp_error_state
175 character(len=*),
intent(in) :: routine, errormsg
176 integer,
intent(in) :: errortype
178 call mpp_error( errortype, trim(routine)//
': '//trim(errormsg) )
183 subroutine mpp_error_noargs()
184 call mpp_error(fatal)
185 end subroutine mpp_error_noargs
188 subroutine mpp_error_is(errortype, errormsg1, mpp_ival, errormsg2)
189 integer,
intent(in) :: errortype
190 INTEGER,
intent(in) :: mpp_ival
191 character(len=*),
intent(in) :: errormsg1
192 character(len=*),
intent(in),
optional :: errormsg2
193 call mpp_error( errortype, errormsg1, (/mpp_ival/), errormsg2)
194 end subroutine mpp_error_is
196 subroutine mpp_error_rs(errortype, errormsg1, mpp_rval, errormsg2)
197 integer,
intent(in) :: errortype
198 REAL,
intent(in) :: mpp_rval
199 character(len=*),
intent(in) :: errormsg1
200 character(len=*),
intent(in),
optional :: errormsg2
201 call mpp_error( errortype, errormsg1, (/mpp_rval/), errormsg2)
202 end subroutine mpp_error_rs
204 subroutine mpp_error_ia(errortype, errormsg1, array, errormsg2)
205 integer,
intent(in) :: errortype
206 INTEGER,
dimension(:),
intent(in) :: array
207 character(len=*),
intent(in) :: errormsg1
208 character(len=*),
intent(in),
optional :: errormsg2
209 character(len=512) :: string
211 string = errormsg1//trim(array_to_char(array))
212 if(
present(errormsg2)) string = trim(string)//errormsg2
215 end subroutine mpp_error_ia
218 subroutine mpp_error_ra(errortype, errormsg1, array, errormsg2)
219 integer,
intent(in) :: errortype
220 REAL,
dimension(:),
intent(in) :: array
221 character(len=*),
intent(in) :: errormsg1
222 character(len=*),
intent(in),
optional :: errormsg2
223 character(len=512) :: string
225 string = errormsg1//trim(array_to_char(array))
226 if(
present(errormsg2)) string = trim(string)//errormsg2
229 end subroutine mpp_error_ra
232 #define _SUBNAME_ mpp_error_ia_ia
233 #define _ARRAY1TYPE_ integer
234 #define _ARRAY2TYPE_ integer
235 #include <mpp_error_a_a.fh>
240 #define _SUBNAME_ mpp_error_ia_ra
241 #define _ARRAY1TYPE_ integer
242 #define _ARRAY2TYPE_ real
243 #include <mpp_error_a_a.fh>
248 #define _SUBNAME_ mpp_error_ra_ia
249 #define _ARRAY1TYPE_ real
250 #define _ARRAY2TYPE_ integer
251 #include <mpp_error_a_a.fh>
256 #define _SUBNAME_ mpp_error_ra_ra
257 #define _ARRAY1TYPE_ real
258 #define _ARRAY2TYPE_ real
259 #include <mpp_error_a_a.fh>
264 #define _SUBNAME_ mpp_error_ia_is
265 #define _ARRAY1TYPE_ integer
266 #define _ARRAY2TYPE_ integer
267 #include <mpp_error_a_s.fh>
272 #define _SUBNAME_ mpp_error_ia_rs
273 #define _ARRAY1TYPE_ integer
274 #define _ARRAY2TYPE_ real
275 #include <mpp_error_a_s.fh>
280 #define _SUBNAME_ mpp_error_ra_is
281 #define _ARRAY1TYPE_ real
282 #define _ARRAY2TYPE_ integer
283 #include <mpp_error_a_s.fh>
288 #define _SUBNAME_ mpp_error_ra_rs
289 #define _ARRAY1TYPE_ real
290 #define _ARRAY2TYPE_ real
291 #include <mpp_error_a_s.fh>
296 #define _SUBNAME_ mpp_error_is_ia
297 #define _ARRAY1TYPE_ integer
298 #define _ARRAY2TYPE_ integer
299 #include <mpp_error_s_a.fh>
304 #define _SUBNAME_ mpp_error_is_ra
305 #define _ARRAY1TYPE_ integer
306 #define _ARRAY2TYPE_ real
307 #include <mpp_error_s_a.fh>
312 #define _SUBNAME_ mpp_error_rs_ia
313 #define _ARRAY1TYPE_ real
314 #define _ARRAY2TYPE_ integer
315 #include <mpp_error_s_a.fh>
320 #define _SUBNAME_ mpp_error_rs_ra
321 #define _ARRAY1TYPE_ real
322 #define _ARRAY2TYPE_ real
323 #include <mpp_error_s_a.fh>
328 #define _SUBNAME_ mpp_error_is_is
329 #define _ARRAY1TYPE_ integer
330 #define _ARRAY2TYPE_ integer
331 #include <mpp_error_s_s.fh>
336 #define _SUBNAME_ mpp_error_is_rs
337 #define _ARRAY1TYPE_ integer
338 #define _ARRAY2TYPE_ real
339 #include <mpp_error_s_s.fh>
344 #define _SUBNAME_ mpp_error_rs_is
345 #define _ARRAY1TYPE_ real
346 #define _ARRAY2TYPE_ integer
347 #include <mpp_error_s_s.fh>
352 #define _SUBNAME_ mpp_error_rs_rs
353 #define _ARRAY1TYPE_ real
354 #define _ARRAY2TYPE_ real
355 #include <mpp_error_s_s.fh>
360 function iarray_to_char(iarray)
result(string)
361 integer,
intent(in) :: iarray(:)
362 character(len=256) :: string
363 character(len=32) :: chtmp
364 integer :: i, len_tmp, len_string
368 write(chtmp,
'(i16)') iarray(i)
369 chtmp = adjustl(chtmp)
370 len_tmp = len_trim(chtmp)
371 len_string = len_trim(string)
372 string(len_string+1:len_string+len_tmp) = trim(chtmp)
373 string(len_string+len_tmp+1:len_string+len_tmp+1) =
','
375 len_string = len_trim(string)
376 string(len_string:len_string) =
' '
378 end function iarray_to_char
380 function rarray_to_char(rarray)
result(string)
381 real,
intent(in) :: rarray(:)
382 character(len=256) :: string
383 character(len=32) :: chtmp
384 integer :: i, len_tmp, len_string
388 write(chtmp,
'(G16.9)') rarray(i)
389 chtmp = adjustl(chtmp)
390 len_tmp = len_trim(chtmp)
391 len_string = len_trim(string)
392 string(len_string+1:len_string+len_tmp) = trim(chtmp)
393 string(len_string+len_tmp+1:len_string+len_tmp+1) =
','
395 len_string = len_trim(string)
396 string(len_string:len_string) =
' '
398 end function rarray_to_char
409 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_PE: You must first call mpp_init.' )
423 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_NPES: You must first call mpp_init.' )
424 mpp_npes =
size(peset(current_peset_num)%list(:))
429 function mpp_root_pe()
430 integer :: mpp_root_pe
432 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_ROOT_PE: You must first call mpp_init.' )
433 mpp_root_pe = root_pe
435 end function mpp_root_pe
438 subroutine mpp_set_root_pe(num)
439 integer,
intent(in) :: num
441 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_ROOT_PE: You must first call mpp_init.' )
442 if( .NOT.(any(num.EQ.peset(current_peset_num)%list(:))) ) &
443 call mpp_error( fatal,
'MPP_SET_ROOT_PE: you cannot set a root PE outside the current pelist.' )
446 end subroutine mpp_set_root_pe
461 integer,
intent(in) :: pelist(:)
462 character(len=*),
intent(in),
optional :: name
463 integer,
intent(out),
optional :: commID
466 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_DECLARE_PELIST: You must first call mpp_init.' )
467 i = get_peset(pelist)
468 write( peset(i)%name,
'(a,i2.2)' )
'PElist', i
469 if(
PRESENT(name) )peset(i)%name = name
470 if(
PRESENT(commid) )commid = peset(i)%id
497 integer,
intent(in),
optional :: pelist(:)
498 logical,
intent(in),
optional :: no_sync
500 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: You must first call mpp_init.' )
501 if(
PRESENT(pelist) )
then
502 if( .NOT.any(pe.EQ.pelist) )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: pe must be in pelist.' )
503 current_peset_num = get_peset(pelist)
505 current_peset_num = world_peset_num
507 call mpp_set_root_pe( minval(peset(current_peset_num)%list(:)) )
508 if(.not.
PRESENT(no_sync))
call mpp_sync()
514 function mpp_get_current_pelist_name()
516 character(len=len(peset(current_peset_num)%name)) :: mpp_get_current_pelist_name
518 mpp_get_current_pelist_name = peset(current_peset_num)%name
519 end function mpp_get_current_pelist_name
524 subroutine mpp_get_current_pelist( pelist, name, commID )
525 integer,
intent(out) :: pelist(:)
526 character(len=*),
intent(out),
optional :: name
527 integer,
intent(out),
optional :: commID
529 if(
size(pelist(:)).NE.
size(peset(current_peset_num)%list(:)) ) &
530 call mpp_error( fatal,
'MPP_GET_CURRENT_PELIST: size(pelist) is wrong.' )
531 pelist(:) = peset(current_peset_num)%list(:)
532 if(
PRESENT(name) )name = peset(current_peset_num)%name
534 if(
PRESENT(commid) )commid = peset(current_peset_num)%id
538 end subroutine mpp_get_current_pelist
641 integer,
intent(in) :: grain
646 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_SET_GRAIN: You must first call mpp_init.' )
653 subroutine clock_init( id, name, flags, grain )
654 integer,
intent(in) :: id
655 character(len=*),
intent(in) :: name
656 integer,
intent(in),
optional :: flags, grain
659 clocks(id)%name = name
662 clocks(id)%total_ticks = 0
663 clocks(id)%sync_on_begin = .false.
664 clocks(id)%detailed = .false.
665 clocks(id)%peset_num = current_peset_num
666 if(
PRESENT(flags) )
then
667 if( btest(flags,0) )clocks(id)%sync_on_begin = .true.
668 if( btest(flags,1) )clocks(id)%detailed = .true.
671 if(
PRESENT(grain) )clocks(id)%grain = grain
672 if( clocks(id)%detailed )
then
673 allocate( clocks(id)%events(max_event_types) )
674 clocks(id)%events(event_allreduce)%name =
'ALLREDUCE'
675 clocks(id)%events(event_broadcast)%name =
'BROADCAST'
676 clocks(id)%events(event_recv)%name =
'RECV'
677 clocks(id)%events(event_send)%name =
'SEND'
678 clocks(id)%events(event_wait)%name =
'WAIT'
679 do i=1,max_event_types
680 clocks(id)%events(i)%ticks(:) = 0
681 clocks(id)%events(i)%bytes(:) = 0
682 clocks(id)%events(i)%calls = 0
684 clock_summary(id)%name = name
685 clock_summary(id)%event(event_allreduce)%name =
'ALLREDUCE'
686 clock_summary(id)%event(event_broadcast)%name =
'BROADCAST'
687 clock_summary(id)%event(event_recv)%name =
'RECV'
688 clock_summary(id)%event(event_send)%name =
'SEND'
689 clock_summary(id)%event(event_wait)%name =
'WAIT'
690 do i=1,max_event_types
691 clock_summary(id)%event(i)%msg_size_sums(:) = 0.0
692 clock_summary(id)%event(i)%msg_time_sums(:) = 0.0
693 clock_summary(id)%event(i)%total_data = 0.0
694 clock_summary(id)%event(i)%total_time = 0.0
695 clock_summary(id)%event(i)%msg_size_cnts(:) = 0
696 clock_summary(id)%event(i)%total_cnts = 0
700 end subroutine clock_init
706 character(len=*),
intent(in) :: name
707 integer,
intent(in),
optional :: flags, grain
709 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_ID: You must first call mpp_init.')
715 if(
PRESENT(grain) )
then
716 if( grain.GT.clock_grain )
then
723 if( clock_num.EQ.0 )
then
727 find_clock:
do while( trim(name).NE.trim(clocks(
mpp_clock_id)%name) )
731 call mpp_error( fatal,
'MPP_CLOCK_ID: too many clock requests, ' // &
732 'check your clock id request or increase MAX_CLOCKS.')
745 subroutine mpp_clock_begin(id)
746 integer,
intent(in) :: id
748 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: You must first call mpp_init.' )
749 if( .not. mpp_record_timing_data)
return
751 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
754 if( clocks(id)%peset_num.NE.current_peset_num ) &
755 call mpp_error( fatal,
'MPP_CLOCK_BEGIN: cannot change pelist context of a clock.' )
756 if( clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: mpp_clock_begin is called again '// &
757 'before calling mpp_clock_end for the clock '//trim(clocks(id)%name) )
758 if( clocks(id)%sync_on_begin .OR. sync_all_clocks )
then
766 num_clock_ids = num_clock_ids+1
767 if(num_clock_ids > max_clocks)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: max num previous_clock exceeded.' )
768 previous_clock(num_clock_ids) = current_clock
771 call system_clock( clocks(id)%tick )
772 clocks(id)%hits = clocks(id)%hits + 1
773 clocks(id)%is_on = .true.
776 end subroutine mpp_clock_begin
779 subroutine mpp_clock_end(id)
780 integer,
intent(in) :: id
781 integer(i8_kind) :: delta
784 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_END: You must first call mpp_init.' )
785 if( .not. mpp_record_timing_data)
return
787 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
789 if( .NOT. clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_END: mpp_clock_end is called '// &
790 'before calling mpp_clock_begin for the clock '//trim(clocks(id)%name) )
792 call system_clock(end_tick)
793 if( clocks(id)%peset_num.NE.current_peset_num ) &
794 call mpp_error( fatal,
'MPP_CLOCK_END: cannot change pelist context of a clock.' )
795 delta = end_tick - clocks(id)%tick
798 write( errunit,* )
'pe, id, start_tick, end_tick, delta, max_ticks=', pe, id, clocks(id)%tick, end_tick, &
800 delta = delta + max_ticks + 1
801 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
803 clocks(id)%total_ticks = clocks(id)%total_ticks + delta
805 if(num_clock_ids < 1)
call mpp_error(note,
'MPP_CLOCK_END: min num previous_clock < 1.' )
806 current_clock = previous_clock(num_clock_ids)
807 num_clock_ids = num_clock_ids-1
809 clocks(id)%is_on = .false.
812 end subroutine mpp_clock_end
815 subroutine mpp_record_time_start()
817 mpp_record_timing_data = .true.
819 end subroutine mpp_record_time_start
822 subroutine mpp_record_time_end()
824 mpp_record_timing_data = .false.
826 end subroutine mpp_record_time_end
830 subroutine increment_current_clock( event_id, bytes )
831 integer,
intent(in) :: event_id
832 integer,
intent(in),
optional :: bytes
834 integer(i8_kind) :: delta
837 if( .not. mpp_record_timing_data )
return
838 if( .not.debug .or. (current_clock.EQ.0) )
return
839 if( current_clock.LT.0 .OR. current_clock.GT.clock_num )
call mpp_error( fatal, &
840 &
'MPP_CLOCK_BEGIN: invalid current_clock.' )
841 if( .NOT.clocks(current_clock)%detailed )
return
842 call system_clock(end_tick)
843 n = clocks(current_clock)%events(event_id)%calls + 1
845 if( n.EQ.max_events )
call mpp_error( warning, &
846 'MPP_CLOCK: events exceed MAX_EVENTS, ignore detailed profiling data for clock '// &
847 & trim(clocks(current_clock)%name) )
848 if( n.GT.max_events )
return
850 clocks(current_clock)%events(event_id)%calls = n
851 delta = end_tick - start_tick
854 write( errunit,* )
'pe, event_id, start_tick, end_tick, delta, max_ticks=', &
855 pe, event_id, start_tick, end_tick, delta, max_ticks
856 delta = delta + max_ticks + 1
857 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
859 clocks(current_clock)%events(event_id)%ticks(n) = delta
860 if(
PRESENT(bytes) )clocks(current_clock)%events(event_id)%bytes(n) = bytes
862 end subroutine increment_current_clock
866 subroutine dump_clock_summary()
868 real :: total_time,total_time_all,total_data
869 real :: msg_size,eff_bw,s
870 integer :: sd_unit, total_calls
871 integer :: j,k,ct, msg_cnt
872 character(len=2) :: u
873 character(len=FMS_FILE_LEN) :: filename
874 character(len=20),
dimension(MAX_BINS),
save :: bin
876 data bin( 1) /
' 0 - 8 B: '/
877 data bin( 2) /
' 8 - 16 B: '/
878 data bin( 3) /
' 16 - 32 B: '/
879 data bin( 4) /
' 32 - 64 B: '/
880 data bin( 5) /
' 64 - 128 B: '/
881 data bin( 6) /
'128 - 256 B: '/
882 data bin( 7) /
'256 - 512 B: '/
883 data bin( 8) /
'512 - 1024 B: '/
884 data bin( 9) /
' 1.0 - 2.1 KB: '/
885 data bin(10) /
' 2.1 - 4.1 KB: '/
886 data bin(11) /
' 4.1 - 8.2 KB: '/
887 data bin(12) /
' 8.2 - 16.4 KB: '/
888 data bin(13) /
' 16.4 - 32.8 KB: '/
889 data bin(14) /
' 32.8 - 65.5 KB: '/
890 data bin(15) /
' 65.5 - 131.1 KB: '/
891 data bin(16) /
'131.1 - 262.1 KB: '/
892 data bin(17) /
'262.1 - 524.3 KB: '/
893 data bin(18) /
'524.3 - 1048.6 KB: '/
894 data bin(19) /
' 1.0 - 2.1 MB: '/
895 data bin(20) /
' >2.1 MB: '/
897 if( .NOT.any(clocks(1:clock_num)%detailed) )
return
898 write( filename,
'(a,i6.6)' )
'mpp_clock.out.', pe
900 open(newunit=sd_unit,file=trim(filename),form=
'formatted')
902 comm_type:
do ct = 1,clock_num
904 if( .NOT.clocks(ct)%detailed )cycle
906 clock_summary(ct)%name(1:15),
' Communication Data for PE ',pe
912 event_type:
do k = 1,max_event_types-1
914 if(clock_summary(ct)%event(k)%total_time == 0.0)cycle
916 total_time = clock_summary(ct)%event(k)%total_time
917 total_time_all = total_time_all + total_time
918 total_data = clock_summary(ct)%event(k)%total_data
919 total_calls = int(clock_summary(ct)%event(k)%total_cnts)
921 write(sd_unit,1000) clock_summary(ct)%event(k)%name(1:9) //
':'
923 write(sd_unit,1001)
'Total Data: ',total_data*1.0e-6, &
924 'MB; Total Time: ', total_time, &
925 'secs; Total Calls: ',total_calls
928 write(sd_unit,1002)
' Bin Counts Avg Size Eff B/W'
931 bin_loop:
do j=1,max_bins
933 if(clock_summary(ct)%event(k)%msg_size_cnts(j)==0)cycle
946 msg_cnt = int(clock_summary(ct)%event(k)%msg_size_cnts(j))
948 s*(clock_summary(ct)%event(k)%msg_size_sums(j)/real(msg_cnt))
949 eff_bw = (1.0e-6)*( clock_summary(ct)%event(k)%msg_size_sums(j) / &
950 clock_summary(ct)%event(k)%msg_time_sums(j) )
952 write(sd_unit,1003) bin(j),msg_cnt,msg_size,u,eff_bw
962 if(clock_summary(ct)%event(max_event_types)%total_time>0.0)
then
964 total_time = clock_summary(ct)%event(max_event_types)%total_time
965 total_time_all = total_time_all + total_time
966 total_calls = int(clock_summary(ct)%event(max_event_types)%total_cnts)
968 write(sd_unit,1000) clock_summary(ct)%event(max_event_types)%name(1:9) //
':'
970 write(sd_unit,1004)
'Total Calls: ',total_calls,
'; Total Time: ', &
976 write(sd_unit,1005)
'Total communication time spent for ' // &
977 clock_summary(ct)%name(1:9) //
': ',total_time_all,
'secs'
987 1001
format(a,f8.2,a,f8.2,a,i6)
989 1003
format(a,i6,
' ',
' ',f9.1,a,
' ',f9.2,
'MB/sec')
990 1004
format(a,i8,a,f9.2,a)
991 1005
format(a,f9.2,a)
993 end subroutine dump_clock_summary
997 integer function get_unit()
1002 if (pe == root_pe)
call mpp_error(warning, &
1003 'get_unit is deprecated and will be removed in a future release, please use the Fortran intrinsic newunit')
1005 inquire(unit=i,opened=l_open)
1010 call mpp_error(fatal,
'Unable to get I/O unit')
1016 end function get_unit
1020 subroutine sum_clock_data()
1022 integer :: i,j,k,ct,event_size,event_cnt
1025 clock_type:
do ct=1,clock_num
1026 if( .NOT.clocks(ct)%detailed )cycle
1027 event_type:
do j=1,max_event_types-1
1028 event_cnt = clocks(ct)%events(j)%calls
1029 event_summary:
do i=1,event_cnt
1031 clock_summary(ct)%event(j)%total_cnts = &
1032 clock_summary(ct)%event(j)%total_cnts + 1
1034 event_size = int(clocks(ct)%events(j)%bytes(i))
1036 k = find_bin(event_size)
1038 clock_summary(ct)%event(j)%msg_size_cnts(k) = &
1039 clock_summary(ct)%event(j)%msg_size_cnts(k) + 1
1041 clock_summary(ct)%event(j)%msg_size_sums(k) = &
1042 clock_summary(ct)%event(j)%msg_size_sums(k) &
1043 + clocks(ct)%events(j)%bytes(i)
1045 clock_summary(ct)%event(j)%total_data = &
1046 clock_summary(ct)%event(j)%total_data &
1047 + clocks(ct)%events(j)%bytes(i)
1049 msg_time = clocks(ct)%events(j)%ticks(i)
1050 msg_time = tick_rate * real( clocks(ct)%events(j)%ticks(i) )
1052 clock_summary(ct)%event(j)%msg_time_sums(k) = &
1053 clock_summary(ct)%event(j)%msg_time_sums(k) + msg_time
1055 clock_summary(ct)%event(j)%total_time = &
1056 clock_summary(ct)%event(j)%total_time + msg_time
1058 end do event_summary
1065 event_cnt = clocks(ct)%events(j)%calls
1066 clock_summary(ct)%event(j)%msg_size_cnts(1) = event_cnt
1067 clock_summary(ct)%event(j)%total_cnts = event_cnt
1069 msg_time = tick_rate * real( sum( clocks(ct)%events(j)%ticks(1:event_cnt) ) )
1070 clock_summary(ct)%event(j)%msg_time_sums(1) = &
1071 clock_summary(ct)%event(j)%msg_time_sums(1) + msg_time
1073 clock_summary(ct)%event(j)%total_time = clock_summary(ct)%event(j)%msg_time_sums(1)
1079 integer function find_bin(event_size)
1081 integer,
intent(in) :: event_size
1082 integer :: k,msg_size
1086 do while(event_size>msg_size .and. k<max_bins)
1088 msg_size = msg_size*2
1092 end function find_bin
1094 end subroutine sum_clock_data
1100 integer :: old_peset_max,n
1101 type(communicator),
allocatable :: peset_old(:)
1103 old_peset_max = current_peset_max
1104 if(old_peset_max .GE. peset_max)
call mpp_error(fatal, &
1105 "mpp_mod(expand_peset): the number of peset reached PESET_MAX, increase PESET_MAX or contact developer")
1108 allocate(peset_old(0:old_peset_max))
1109 do n = 0, old_peset_max
1110 peset_old(n)%count = peset(n)%count
1111 peset_old(n)%id = peset(n)%id
1112 peset_old(n)%group = peset(n)%group
1113 peset_old(n)%name = peset(n)%name
1114 peset_old(n)%start = peset(n)%start
1115 peset_old(n)%log2stride = peset(n)%log2stride
1117 if(
ASSOCIATED(peset(n)%list) )
then
1118 allocate(peset_old(n)%list(
size(peset(n)%list(:))) )
1119 peset_old(n)%list(:) = peset(n)%list(:)
1120 deallocate(peset(n)%list)
1126 current_peset_max = min(peset_max, 2*old_peset_max)
1127 allocate(peset(0:current_peset_max))
1132 peset(:)%log2stride = -1
1134 do n = 0, old_peset_max
1135 peset(n)%count = peset_old(n)%count
1136 peset(n)%id = peset_old(n)%id
1137 peset(n)%group = peset_old(n)%group
1138 peset(n)%name = peset_old(n)%name
1139 peset(n)%start = peset_old(n)%start
1140 peset(n)%log2stride = peset_old(n)%log2stride
1142 if(
ASSOCIATED(peset_old(n)%list) )
then
1143 allocate(peset(n)%list(
size(peset_old(n)%list(:))) )
1144 peset(n)%list(:) = peset_old(n)%list(:)
1145 deallocate(peset_old(n)%list)
1148 deallocate(peset_old)
1150 call mpp_error(note,
"mpp_mod(expand_peset): size of peset is expanded to ", current_peset_max)
1155 function uppercase (cs)
1156 character(len=*),
intent(in) :: cs
1157 character(len=len(cs)),
target :: uppercase
1159 character,
pointer :: ca
1160 integer,
parameter :: co=iachar(
'A')-iachar(
'a')
1166 uppercase = cs(1:tlen)
1168 ca => uppercase(k:k)
1169 if(ca >=
"a" .and. ca <=
"z") ca = achar(ichar(ca)+co)
1172 end function uppercase
1176 function lowercase (cs)
1177 character(len=*),
intent(in) :: cs
1178 character(len=len(cs)),
target :: lowercase
1179 integer,
parameter :: co=iachar(
'a')-iachar(
'A')
1181 character,
pointer :: ca
1187 lowercase = cs(1:tlen)
1189 ca => lowercase(k:k)
1190 if(ca >=
"A" .and. ca <=
"Z") ca = achar(ichar(ca)+co)
1193 end function lowercase
1221 #include<file_version.h>
1223 character(len=*),
intent(in),
optional :: pelist_name_in
1224 character(len=*),
intent(in),
optional :: alt_input_nml_path
1228 integer,
dimension(2) :: lines_and_length
1229 logical :: file_exist
1230 character(len=len(peset(current_peset_num)%name)) :: pelist_name
1231 character(len=FMS_PATH_LEN) :: filename
1234 if (
allocated(input_nml_file) )
then
1235 deallocate(input_nml_file)
1239 if (
PRESENT(pelist_name_in))
then
1241 if (len(pelist_name_in) > len(pelist_name))
then
1242 call mpp_error(fatal, &
1243 "mpp_util.inc: read_input_nml optional argument pelist_name_in has size greater than local pelist_name")
1245 pelist_name = pelist_name_in
1248 pelist_name = mpp_get_current_pelist_name()
1250 filename=
'input_'//trim(pelist_name)//
'.nml'
1251 inquire(file=filename, exist=file_exist)
1252 if (.not. file_exist )
then
1253 if (
present(alt_input_nml_path))
then
1254 filename = alt_input_nml_path
1256 filename =
'input.nml'
1260 allocate(
character(len=lines_and_length(2))::input_nml_file(lines_and_length(1)))
1264 if (pe == root_pe)
then
1266 write(log_unit,
'(a)')
'========================================================================'
1267 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(version)
1268 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(filename)//
' '
1269 do i = 1, lines_and_length(1)
1270 write(log_unit,*) trim(input_nml_file(i))
1278 function get_ascii_file_num_lines(FILENAME, LENGTH, PELIST)
1279 character(len=*),
intent(in) :: FILENAME
1280 integer,
intent(in) :: LENGTH
1281 integer,
intent(in),
optional,
dimension(:) :: PELIST
1283 integer :: num_lines, get_ascii_file_num_lines
1284 character(len=LENGTH) :: str_tmp
1285 character(len=5) :: text
1286 integer :: status, f_unit, from_pe
1287 logical :: file_exist
1289 if( read_ascii_file_on)
then
1290 call mpp_error(fatal, &
1291 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1293 read_ascii_file_on = .true.
1296 get_ascii_file_num_lines = -1
1298 if ( pe == root_pe )
then
1299 inquire(file=filename, exist=file_exist)
1301 if ( file_exist )
then
1302 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1304 if ( status .ne. 0 )
then
1305 write (unit=text, fmt=
'(I5)') status
1306 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1307 '. (IOSTAT = '//trim(text)//
')')
1311 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1312 if ( status .lt. 0 )
then
1314 num_lines = max(num_lines - 1, 1)
1317 if ( status .gt. 0 )
then
1318 write (unit=text, fmt=
'(I5)') num_lines
1319 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1320 ' in file '//trim(filename)//
'.')
1322 if ( len_trim(str_tmp) == length )
then
1323 write(unit=text, fmt=
'(I5)') length
1324 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1325 &
' is too small. Increase the LENGTH value.')
1327 num_lines = num_lines + 1
1332 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1337 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1338 get_ascii_file_num_lines = num_lines
1340 end function get_ascii_file_num_lines
1345 character(len=*),
intent(in) :: filename
1346 integer,
intent(in),
optional,
dimension(:) :: pelist
1350 integer :: num_lines, max_length
1351 integer,
parameter :: length=1024
1352 character(len=LENGTH) :: str_tmp
1353 character(len=5) :: text
1354 integer :: status, f_unit, from_pe
1355 logical :: file_exist
1357 if( read_ascii_file_on)
then
1358 call mpp_error(fatal, &
1359 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1361 read_ascii_file_on = .true.
1367 if ( pe == root_pe )
then
1368 inquire(file=filename, exist=file_exist)
1370 if ( file_exist )
then
1371 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1373 if ( status .ne. 0 )
then
1374 write (unit=text, fmt=
'(I5)') status
1375 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1376 '. (IOSTAT = '//trim(text)//
')')
1381 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1382 if ( status .lt. 0 )
then
1384 num_lines = max(num_lines - 1, 1)
1387 if ( status .gt. 0 )
then
1388 write (unit=text, fmt=
'(I5)') num_lines
1389 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1390 ' in file '//trim(filename)//
'.')
1392 if ( len_trim(str_tmp) == length)
then
1393 write(unit=text, fmt=
'(I5)') length
1394 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1395 &
' is too small. Increase the LENGTH value.')
1397 if (len_trim(str_tmp) > max_length) max_length = len_trim(str_tmp)
1398 num_lines = num_lines + 1
1403 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1405 max_length = max_length+1
1409 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1410 call mpp_broadcast(max_length, from_pe, pelist=pelist)
1438 character(len=*),
intent(in) :: FILENAME
1439 integer,
intent(in) :: LENGTH
1440 character(len=*),
intent(inout),
dimension(:) :: Content
1441 integer,
intent(in),
optional,
dimension(:) :: PELIST
1444 #include<file_version.h>
1446 character(len=5) :: text
1447 logical :: file_exist
1448 integer :: status, f_unit, log_unit
1450 integer :: pnum_lines, num_lines
1451 character(len=LENGTH) :: str_tmp
1453 if( .NOT. read_ascii_file_on)
then
1454 call mpp_error(fatal, &
1455 "mpp_util.inc: get_ascii_file_num_lines needs to be called before calling read_ascii_file")
1457 read_ascii_file_on = .false.
1460 num_lines =
size(content(:))
1462 if ( pe == root_pe )
then
1465 write(log_unit,
'(a)')
'========================================================================'
1466 write(log_unit,
'(a)')
'READ_ASCII_FILE: '//trim(version)
1467 write(log_unit,
'(a)')
'READ_ASCII_FILE: File: '//trim(filename)
1469 inquire(file=filename, exist=file_exist)
1471 if ( file_exist )
then
1472 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1474 if ( status .ne. 0 )
then
1475 write (unit=text, fmt=
'(I5)') status
1476 call mpp_error(fatal,
'READ_ASCII_FILE: Error opening file: '// &
1477 & trim(filename)//
'. (IOSTAT = '//trim(text)//
')')
1480 if ( num_lines .gt. 0 )
then
1483 rewind(unit=f_unit, iostat=status)
1484 if ( status .ne. 0 )
then
1485 write (unit=text, fmt=
'(I5)') status
1486 call mpp_error(fatal,
'READ_ASCII_FILE: Unable to re-read file '//trim(filename)//
'. (IOSTAT = '&
1493 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1495 if ( status .lt. 0 )
then
1497 pnum_lines = max(pnum_lines - 1, 1)
1500 if ( status .gt. 0 )
then
1501 write (unit=text, fmt=
'(I5)') pnum_lines
1502 call mpp_error(fatal,
'READ_ASCII_FILE: Error reading line '// &
1503 & trim(text)//
' in file '//trim(filename)//
'.')
1505 if(pnum_lines > num_lines)
then
1506 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1507 ' is greater than size(Content(:)). ')
1509 if ( len_trim(str_tmp) == length )
then
1510 write(unit=text, fmt=
'(I5)') length
1511 call mpp_error(fatal,
'READ_ASCII_FILE: Length of output string ('//trim(text)// &
1512 &
' is too small. Increase the LENGTH value.')
1514 content(pnum_lines) = str_tmp
1515 pnum_lines = pnum_lines + 1
1517 if(num_lines .NE. pnum_lines)
then
1518 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1519 ' does not equal to size(Content(:)) ' )
1526 call mpp_error(fatal,
'READ_ASCII_FILE: File '//trim(filename)//
' does not exist.')
1531 call mpp_broadcast(content, length, from_pe, pelist=pelist)
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 mpp_clock_set_grain(grain)
Set the level of granularity of timing measurements.
subroutine mpp_declare_pelist(pelist, name, commID)
Declare a pelist.
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 expand_peset()
This routine will double the size of peset and copy the original peset data into the expanded one....