28#if defined(use_libMPI)
29#include <mpp_util_mpi.inc>
31#include <mpp_util_nocomm.inc>
45 if( pe.NE.root_pe )stdout = stdlog()
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 )
10210
call mpp_error( fatal,
'STDLOG: unable to open '//trim(configfile)//this_pe//
'.' )
10311
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
124 subroutine mpp_init_warninglog()
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' )
136 end subroutine mpp_init_warninglog
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
174subroutine mpp_error_mesg( routine, errormsg, errortype )
175 character(len=*),
intent(in) :: routine, errormsg
176 integer,
intent(in) :: errortype
178 call mpp_error( errortype, trim(routine)//
': '//trim(errormsg) )
180end subroutine mpp_error_mesg
183subroutine mpp_error_noargs()
184 call mpp_error(fatal)
185end subroutine mpp_error_noargs
188subroutine 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)
194end subroutine mpp_error_is
196subroutine 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)
202end subroutine mpp_error_rs
204subroutine 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
215end subroutine mpp_error_ia
218subroutine 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
229end 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>
360function iarray_to_char(iarray)
result(string)
361integer,
intent(in) :: iarray(:)
362character(len=256) :: string
363character(len=32) :: chtmp
364integer :: 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) =
' '
378end function iarray_to_char
380function rarray_to_char(rarray)
result(string)
381real,
intent(in) :: rarray(:)
382character(len=256) :: string
383character(len=32) :: chtmp
384integer :: 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) =
' '
398end 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(:))
426 end function mpp_npes
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 function mpp_commid()
439 integer :: mpp_commID
441 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_COMMID: You must first call mpp_init.' )
442 mpp_commid = peset(current_peset_num)%id
444 end function mpp_commid
447 subroutine mpp_set_root_pe(num)
448 integer,
intent(in) :: num
450 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_ROOT_PE: You must first call mpp_init.' )
451 if( .NOT.(any(num.EQ.peset(current_peset_num)%list(:))) ) &
452 call mpp_error( fatal,
'MPP_SET_ROOT_PE: you cannot set a root PE outside the current pelist.' )
455 end subroutine mpp_set_root_pe
469 subroutine mpp_declare_pelist( pelist, name, commID )
470 integer,
intent(in) :: pelist(:)
471 character(len=*),
intent(in),
optional :: name
472 integer,
intent(out),
optional :: commID
475 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_DECLARE_PELIST: You must first call mpp_init.' )
477 write( peset(i)%name,
'(a,i2.2)' )
'PElist', i
478 if(
PRESENT(name) )peset(i)%name = name
479 if(
PRESENT(commid) )commid = peset(i)%id
482 end subroutine mpp_declare_pelist
498 subroutine mpp_set_current_pelist( pelist, no_sync )
506 integer,
intent(in),
optional :: pelist(:)
507 logical,
intent(in),
optional :: no_sync
509 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: You must first call mpp_init.' )
510 if(
PRESENT(pelist) )
then
511 if( .NOT.any(pe.EQ.pelist) )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: pe must be in pelist.' )
514 current_peset_num = world_peset_num
516 call mpp_set_root_pe( minval(peset(current_peset_num)%list(:)) )
517 if(.not.
PRESENT(no_sync))
call mpp_sync()
520 end subroutine mpp_set_current_pelist
523 function mpp_get_current_pelist_name()
525 character(len=len(peset(current_peset_num)%name)) :: mpp_get_current_pelist_name
527 mpp_get_current_pelist_name = peset(current_peset_num)%name
528 end function mpp_get_current_pelist_name
533 subroutine mpp_get_current_pelist( pelist, name, commID )
534 integer,
intent(out) :: pelist(:)
535 character(len=*),
intent(out),
optional :: name
536 integer,
intent(out),
optional :: commID
538 if(
size(pelist(:)).NE.
size(peset(current_peset_num)%list(:)) ) &
539 call mpp_error( fatal,
'MPP_GET_CURRENT_PELIST: size(pelist) is wrong.' )
540 pelist(:) = peset(current_peset_num)%list(:)
541 if(
PRESENT(name) )name = peset(current_peset_num)%name
543 if(
PRESENT(commid) )commid = peset(current_peset_num)%id
547 end subroutine mpp_get_current_pelist
649 subroutine mpp_clock_set_grain( grain )
650 integer,
intent(in) :: grain
655 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_SET_GRAIN: You must first call mpp_init.' )
659 end subroutine mpp_clock_set_grain
662 subroutine clock_init( id, name, flags, grain )
663 integer,
intent(in) :: id
664 character(len=*),
intent(in) :: name
665 integer,
intent(in),
optional :: flags, grain
668 clocks(id)%name = name
671 clocks(id)%total_ticks = 0
672 clocks(id)%sync_on_begin = .false.
673 clocks(id)%detailed = .false.
674 clocks(id)%peset_num = current_peset_num
675 if(
PRESENT(flags) )
then
676 if( btest(flags,0) )clocks(id)%sync_on_begin = .true.
677 if( btest(flags,1) )clocks(id)%detailed = .true.
680 if(
PRESENT(grain) )clocks(id)%grain = grain
681 if( clocks(id)%detailed )
then
682 allocate( clocks(id)%events(max_event_types) )
683 clocks(id)%events(event_allreduce)%name =
'ALLREDUCE'
684 clocks(id)%events(event_broadcast)%name =
'BROADCAST'
685 clocks(id)%events(event_recv)%name =
'RECV'
686 clocks(id)%events(event_send)%name =
'SEND'
687 clocks(id)%events(event_wait)%name =
'WAIT'
688 do i=1,max_event_types
689 clocks(id)%events(i)%ticks(:) = 0
690 clocks(id)%events(i)%bytes(:) = 0
691 clocks(id)%events(i)%calls = 0
693 clock_summary(id)%name = name
694 clock_summary(id)%event(event_allreduce)%name =
'ALLREDUCE'
695 clock_summary(id)%event(event_broadcast)%name =
'BROADCAST'
696 clock_summary(id)%event(event_recv)%name =
'RECV'
697 clock_summary(id)%event(event_send)%name =
'SEND'
698 clock_summary(id)%event(event_wait)%name =
'WAIT'
699 do i=1,max_event_types
700 clock_summary(id)%event(i)%msg_size_sums(:) = 0.0
701 clock_summary(id)%event(i)%msg_time_sums(:) = 0.0
702 clock_summary(id)%event(i)%total_data = 0.0
703 clock_summary(id)%event(i)%total_time = 0.0
704 clock_summary(id)%event(i)%msg_size_cnts(:) = 0
705 clock_summary(id)%event(i)%total_cnts = 0
709 end subroutine clock_init
713 function mpp_clock_id( name, flags, grain )
714 integer :: mpp_clock_id
715 character(len=*),
intent(in) :: name
716 integer,
intent(in),
optional :: flags, grain
718 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_ID: You must first call mpp_init.')
724 if(
PRESENT(grain) )
then
725 if( grain.GT.clock_grain )
then
732 if( clock_num.EQ.0 )
then
733 clock_num = mpp_clock_id
734 call clock_init(mpp_clock_id,name,flags)
736 find_clock:
do while( trim(name).NE.trim(clocks(mpp_clock_id)%name) )
737 mpp_clock_id = mpp_clock_id + 1
738 if( mpp_clock_id.GT.clock_num )
then
739 if( mpp_clock_id.GT.max_clocks )
then
740 call mpp_error( fatal,
'MPP_CLOCK_ID: too many clock requests, ' // &
741 'check your clock id request or increase MAX_CLOCKS.')
743 clock_num = mpp_clock_id
744 call clock_init(mpp_clock_id,name,flags,grain)
751 end function mpp_clock_id
754 subroutine mpp_clock_begin(id)
755 integer,
intent(in) :: id
757 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: You must first call mpp_init.' )
758 if( .not. mpp_record_timing_data)
return
760 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
763 if( clocks(id)%peset_num.NE.current_peset_num ) &
764 call mpp_error( fatal,
'MPP_CLOCK_BEGIN: cannot change pelist context of a clock.' )
765 if( clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: mpp_clock_begin is called again '// &
766 'before calling mpp_clock_end for the clock '//trim(clocks(id)%name) )
767 if( clocks(id)%sync_on_begin .OR. sync_all_clocks )
then
775 num_clock_ids = num_clock_ids+1
776 if(num_clock_ids > max_clocks)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: max num previous_clock exceeded.' )
777 previous_clock(num_clock_ids) = current_clock
780 call system_clock( clocks(id)%tick )
781 clocks(id)%hits = clocks(id)%hits + 1
782 clocks(id)%is_on = .true.
785 end subroutine mpp_clock_begin
788 subroutine mpp_clock_end(id)
789 integer,
intent(in) :: id
790 integer(i8_kind) :: delta
793 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_END: You must first call mpp_init.' )
794 if( .not. mpp_record_timing_data)
return
796 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
798 if( .NOT. clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_END: mpp_clock_end is called '// &
799 'before calling mpp_clock_begin for the clock '//trim(clocks(id)%name) )
801 call system_clock(end_tick)
802 if( clocks(id)%peset_num.NE.current_peset_num ) &
803 call mpp_error( fatal,
'MPP_CLOCK_END: cannot change pelist context of a clock.' )
804 delta = end_tick - clocks(id)%tick
807 write( errunit,* )
'pe, id, start_tick, end_tick, delta, max_ticks=', pe, id, clocks(id)%tick, end_tick, &
809 delta = delta + max_ticks + 1
810 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
812 clocks(id)%total_ticks = clocks(id)%total_ticks + delta
814 if(num_clock_ids < 1)
call mpp_error(note,
'MPP_CLOCK_END: min num previous_clock < 1.' )
815 current_clock = previous_clock(num_clock_ids)
816 num_clock_ids = num_clock_ids-1
818 clocks(id)%is_on = .false.
821 end subroutine mpp_clock_end
824 subroutine mpp_record_time_start()
826 mpp_record_timing_data = .true.
828 end subroutine mpp_record_time_start
831 subroutine mpp_record_time_end()
833 mpp_record_timing_data = .false.
835 end subroutine mpp_record_time_end
839 subroutine increment_current_clock( event_id, bytes )
840 integer,
intent(in) :: event_id
841 integer,
intent(in),
optional :: bytes
843 integer(i8_kind) :: delta
846 if( .not. mpp_record_timing_data )
return
847 if( .not.debug .or. (current_clock.EQ.0) )
return
848 if( current_clock.LT.0 .OR. current_clock.GT.clock_num )
call mpp_error( fatal, &
849 &
'MPP_CLOCK_BEGIN: invalid current_clock.' )
850 if( .NOT.clocks(current_clock)%detailed )
return
851 call system_clock(end_tick)
852 n = clocks(current_clock)%events(event_id)%calls + 1
854 if( n.EQ.max_events )
call mpp_error( warning, &
855 'MPP_CLOCK: events exceed MAX_EVENTS, ignore detailed profiling data for clock '// &
856 & trim(clocks(current_clock)%name) )
857 if( n.GT.max_events )
return
859 clocks(current_clock)%events(event_id)%calls = n
860 delta = end_tick - start_tick
863 write( errunit,* )
'pe, event_id, start_tick, end_tick, delta, max_ticks=', &
864 pe, event_id, start_tick, end_tick, delta, max_ticks
865 delta = delta + max_ticks + 1
866 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
868 clocks(current_clock)%events(event_id)%ticks(n) = delta
869 if(
PRESENT(bytes) )clocks(current_clock)%events(event_id)%bytes(n) = bytes
871 end subroutine increment_current_clock
875 subroutine dump_clock_summary()
877 real :: total_time,total_time_all,total_data
878 real :: msg_size,eff_BW,s
879 integer :: SD_UNIT, total_calls
880 integer :: j,k,ct, msg_cnt
881 character(len=2) :: u
882 character(len=FMS_FILE_LEN) :: filename
883 character(len=20),
dimension(MAX_BINS),
save :: bin
885 data bin( 1) /
' 0 - 8 B: '/
886 data bin( 2) /
' 8 - 16 B: '/
887 data bin( 3) /
' 16 - 32 B: '/
888 data bin( 4) /
' 32 - 64 B: '/
889 data bin( 5) /
' 64 - 128 B: '/
890 data bin( 6) /
'128 - 256 B: '/
891 data bin( 7) /
'256 - 512 B: '/
892 data bin( 8) /
'512 - 1024 B: '/
893 data bin( 9) /
' 1.0 - 2.1 KB: '/
894 data bin(10) /
' 2.1 - 4.1 KB: '/
895 data bin(11) /
' 4.1 - 8.2 KB: '/
896 data bin(12) /
' 8.2 - 16.4 KB: '/
897 data bin(13) /
' 16.4 - 32.8 KB: '/
898 data bin(14) /
' 32.8 - 65.5 KB: '/
899 data bin(15) /
' 65.5 - 131.1 KB: '/
900 data bin(16) /
'131.1 - 262.1 KB: '/
901 data bin(17) /
'262.1 - 524.3 KB: '/
902 data bin(18) /
'524.3 - 1048.6 KB: '/
903 data bin(19) /
' 1.0 - 2.1 MB: '/
904 data bin(20) /
' >2.1 MB: '/
906 if( .NOT.any(clocks(1:clock_num)%detailed) )
return
907 write( filename,
'(a,i6.6)' )
'mpp_clock.out.', pe
909 open(newunit=sd_unit,file=trim(filename),form=
'formatted')
911 comm_type:
do ct = 1,clock_num
913 if( .NOT.clocks(ct)%detailed )cycle
915 clock_summary(ct)%name(1:15),
' Communication Data for PE ',pe
921 event_type:
do k = 1,max_event_types-1
923 if(clock_summary(ct)%event(k)%total_time == 0.0)cycle
925 total_time = clock_summary(ct)%event(k)%total_time
926 total_time_all = total_time_all + total_time
927 total_data = clock_summary(ct)%event(k)%total_data
928 total_calls = int(clock_summary(ct)%event(k)%total_cnts)
930 write(sd_unit,1000) clock_summary(ct)%event(k)%name(1:9) //
':'
932 write(sd_unit,1001)
'Total Data: ',total_data*1.0e-6, &
933 'MB; Total Time: ', total_time, &
934 'secs; Total Calls: ',total_calls
937 write(sd_unit,1002)
' Bin Counts Avg Size Eff B/W'
940 bin_loop:
do j=1,max_bins
942 if(clock_summary(ct)%event(k)%msg_size_cnts(j)==0)cycle
955 msg_cnt = int(clock_summary(ct)%event(k)%msg_size_cnts(j))
957 s*(clock_summary(ct)%event(k)%msg_size_sums(j)/real(msg_cnt))
958 eff_bw = (1.0e-6)*( clock_summary(ct)%event(k)%msg_size_sums(j) / &
959 clock_summary(ct)%event(k)%msg_time_sums(j) )
961 write(sd_unit,1003) bin(j),msg_cnt,msg_size,u,eff_bw
971 if(clock_summary(ct)%event(max_event_types)%total_time>0.0)
then
973 total_time = clock_summary(ct)%event(max_event_types)%total_time
974 total_time_all = total_time_all + total_time
975 total_calls = int(clock_summary(ct)%event(max_event_types)%total_cnts)
977 write(sd_unit,1000) clock_summary(ct)%event(max_event_types)%name(1:9) //
':'
979 write(sd_unit,1004)
'Total Calls: ',total_calls,
'; Total Time: ', &
985 write(sd_unit,1005)
'Total communication time spent for ' // &
986 clock_summary(ct)%name(1:9) //
': ',total_time_all,
'secs'
9961001
format(a,f8.2,a,f8.2,a,i6)
9981003
format(a,i6,
' ',
' ',f9.1,a,
' ',f9.2,
'MB/sec')
9991004
format(a,i8,a,f9.2,a)
10001005
format(a,f9.2,a)
1002 end subroutine dump_clock_summary
1006 integer function get_unit()
1011 if (pe == root_pe)
call mpp_error(warning, &
1012 'get_unit is deprecated and will be removed in a future release, please use the Fortran intrinsic newunit')
1014 inquire(unit=i,opened=l_open)
1019 call mpp_error(fatal,
'Unable to get I/O unit')
1025 end function get_unit
1029 subroutine sum_clock_data()
1031 integer :: i,j,k,ct,event_size,event_cnt
1034 clock_type:
do ct=1,clock_num
1035 if( .NOT.clocks(ct)%detailed )cycle
1036 event_type:
do j=1,max_event_types-1
1037 event_cnt = clocks(ct)%events(j)%calls
1038 event_summary:
do i=1,event_cnt
1040 clock_summary(ct)%event(j)%total_cnts = &
1041 clock_summary(ct)%event(j)%total_cnts + 1
1043 event_size = int(clocks(ct)%events(j)%bytes(i))
1045 k = find_bin(event_size)
1047 clock_summary(ct)%event(j)%msg_size_cnts(k) = &
1048 clock_summary(ct)%event(j)%msg_size_cnts(k) + 1
1050 clock_summary(ct)%event(j)%msg_size_sums(k) = &
1051 clock_summary(ct)%event(j)%msg_size_sums(k) &
1052 + clocks(ct)%events(j)%bytes(i)
1054 clock_summary(ct)%event(j)%total_data = &
1055 clock_summary(ct)%event(j)%total_data &
1056 + clocks(ct)%events(j)%bytes(i)
1058 msg_time = clocks(ct)%events(j)%ticks(i)
1059 msg_time = tick_rate * real( clocks(ct)%events(j)%ticks(i) )
1061 clock_summary(ct)%event(j)%msg_time_sums(k) = &
1062 clock_summary(ct)%event(j)%msg_time_sums(k) + msg_time
1064 clock_summary(ct)%event(j)%total_time = &
1065 clock_summary(ct)%event(j)%total_time + msg_time
1067 end do event_summary
1074 event_cnt = clocks(ct)%events(j)%calls
1075 clock_summary(ct)%event(j)%msg_size_cnts(1) = event_cnt
1076 clock_summary(ct)%event(j)%total_cnts = event_cnt
1078 msg_time = tick_rate * real( sum( clocks(ct)%events(j)%ticks(1:event_cnt) ) )
1079 clock_summary(ct)%event(j)%msg_time_sums(1) = &
1080 clock_summary(ct)%event(j)%msg_time_sums(1) + msg_time
1082 clock_summary(ct)%event(j)%total_time = clock_summary(ct)%event(j)%msg_time_sums(1)
1088 integer function find_bin(event_size)
1090 integer,
intent(in) :: event_size
1091 integer :: k,msg_size
1095 do while(event_size>msg_size .and. k<max_bins)
1097 msg_size = msg_size*2
1101 end function find_bin
1103 end subroutine sum_clock_data
1108 subroutine expand_peset()
1109 integer :: old_peset_max,n
1110 type(communicator),
allocatable :: peset_old(:)
1112 old_peset_max = current_peset_max
1113 if(old_peset_max .GE. peset_max)
call mpp_error(fatal, &
1114 "mpp_mod(expand_peset): the number of peset reached PESET_MAX, increase PESET_MAX or contact developer")
1117 allocate(peset_old(0:old_peset_max))
1118 do n = 0, old_peset_max
1119 peset_old(n)%count = peset(n)%count
1120 peset_old(n)%id = peset(n)%id
1121 peset_old(n)%group = peset(n)%group
1122 peset_old(n)%name = peset(n)%name
1123 peset_old(n)%start = peset(n)%start
1124 peset_old(n)%log2stride = peset(n)%log2stride
1126 if(
ASSOCIATED(peset(n)%list) )
then
1127 allocate(peset_old(n)%list(
size(peset(n)%list(:))) )
1128 peset_old(n)%list(:) = peset(n)%list(:)
1129 deallocate(peset(n)%list)
1135 current_peset_max = min(peset_max, 2*old_peset_max)
1136 allocate(peset(0:current_peset_max))
1141 peset(:)%log2stride = -1
1143 do n = 0, old_peset_max
1144 peset(n)%count = peset_old(n)%count
1145 peset(n)%id = peset_old(n)%id
1146 peset(n)%group = peset_old(n)%group
1147 peset(n)%name = peset_old(n)%name
1148 peset(n)%start = peset_old(n)%start
1149 peset(n)%log2stride = peset_old(n)%log2stride
1151 if(
ASSOCIATED(peset_old(n)%list) )
then
1152 allocate(peset(n)%list(
size(peset_old(n)%list(:))) )
1153 peset(n)%list(:) = peset_old(n)%list(:)
1154 deallocate(peset_old(n)%list)
1157 deallocate(peset_old)
1159 call mpp_error(note,
"mpp_mod(expand_peset): size of peset is expanded to ", current_peset_max)
1161 end subroutine expand_peset
1164 function uppercase (cs)
1165 character(len=*),
intent(in) :: cs
1166 character(len=len(cs)),
target :: uppercase
1168 character,
pointer :: ca
1169 integer,
parameter :: co=iachar(
'A')-iachar(
'a')
1175 uppercase = cs(1:tlen)
1177 ca => uppercase(k:k)
1178 if(ca >=
"a" .and. ca <=
"z") ca = achar(ichar(ca)+co)
1181 end function uppercase
1185 function lowercase (cs)
1186 character(len=*),
intent(in) :: cs
1187 character(len=len(cs)),
target :: lowercase
1188 integer,
parameter :: co=iachar(
'a')-iachar(
'A')
1190 character,
pointer :: ca
1196 lowercase = cs(1:tlen)
1198 ca => lowercase(k:k)
1199 if(ca >=
"A" .and. ca <=
"Z") ca = achar(ichar(ca)+co)
1202 end function lowercase
1227 subroutine read_input_nml(pelist_name_in, alt_input_nml_path)
1230#include<file_version.h>
1232 character(len=*),
intent(in),
optional :: pelist_name_in
1233 character(len=*),
intent(in),
optional :: alt_input_nml_path
1237 integer,
dimension(2) :: lines_and_length
1238 logical :: file_exist
1239 character(len=len(peset(current_peset_num)%name)) :: pelist_name
1240 character(len=FMS_PATH_LEN) :: filename
1243 if (
allocated(input_nml_file) )
then
1244 deallocate(input_nml_file)
1248 if (
PRESENT(pelist_name_in))
then
1250 if (len(pelist_name_in) > len(pelist_name))
then
1251 call mpp_error(fatal, &
1252 "mpp_util.inc: read_input_nml optional argument pelist_name_in has size greater than local pelist_name")
1254 pelist_name = pelist_name_in
1257 pelist_name = mpp_get_current_pelist_name()
1259 filename=
'input_'//trim(pelist_name)//
'.nml'
1260 inquire(file=filename, exist=file_exist)
1261 if (.not. file_exist )
then
1262 if (
present(alt_input_nml_path))
then
1263 filename = alt_input_nml_path
1265 filename =
'input.nml'
1268 lines_and_length = get_ascii_file_num_lines_and_length(filename)
1269 allocate(
character(len=lines_and_length(2))::input_nml_file(lines_and_length(1)))
1270 call read_ascii_file(filename, lines_and_length(2), input_nml_file)
1273 if (pe == root_pe)
then
1275 write(log_unit,
'(a)')
'========================================================================'
1276 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(version)
1277 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(filename)//
' '
1278 do i = 1, lines_and_length(1)
1279 write(log_unit,*) trim(input_nml_file(i))
1282 end subroutine read_input_nml
1287 function get_ascii_file_num_lines(FILENAME, LENGTH, PELIST)
1288 character(len=*),
intent(in) :: FILENAME
1289 integer,
intent(in) :: LENGTH
1290 integer,
intent(in),
optional,
dimension(:) :: PELIST
1292 integer :: num_lines, get_ascii_file_num_lines
1293 character(len=LENGTH) :: str_tmp
1294 character(len=5) :: text
1295 integer :: status, f_unit, from_pe
1296 logical :: file_exist
1298 if( read_ascii_file_on)
then
1299 call mpp_error(fatal, &
1300 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1302 read_ascii_file_on = .true.
1305 get_ascii_file_num_lines = -1
1307 if ( pe == root_pe )
then
1308 inquire(file=filename, exist=file_exist)
1310 if ( file_exist )
then
1311 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1313 if ( status .ne. 0 )
then
1314 write (unit=text, fmt=
'(I5)') status
1315 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1316 '. (IOSTAT = '//trim(text)//
')')
1320 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1321 if ( status .lt. 0 )
then
1323 num_lines = max(num_lines - 1, 1)
1326 if ( status .gt. 0 )
then
1327 write (unit=text, fmt=
'(I5)') num_lines
1328 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1329 ' in file '//trim(filename)//
'.')
1331 if ( len_trim(str_tmp) == length )
then
1332 write(unit=text, fmt=
'(I5)') length
1333 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1334 &
' is too small. Increase the LENGTH value.')
1336 num_lines = num_lines + 1
1341 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1346 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1347 get_ascii_file_num_lines = num_lines
1349 end function get_ascii_file_num_lines
1353 function get_ascii_file_num_lines_and_length(FILENAME, PELIST)
1354 character(len=*),
intent(in) :: FILENAME
1355 integer,
intent(in),
optional,
dimension(:) :: PELIST
1357 integer,
dimension(2) :: get_ascii_file_num_lines_and_length
1359 integer :: num_lines, max_length
1360 integer,
parameter :: LENGTH=1024
1361 character(len=LENGTH) :: str_tmp
1362 character(len=5) :: text
1363 integer :: status, f_unit, from_pe
1364 logical :: file_exist
1366 if( read_ascii_file_on)
then
1367 call mpp_error(fatal, &
1368 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1370 read_ascii_file_on = .true.
1373 get_ascii_file_num_lines_and_length = -1
1376 if ( pe == root_pe )
then
1377 inquire(file=filename, exist=file_exist)
1379 if ( file_exist )
then
1380 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1382 if ( status .ne. 0 )
then
1383 write (unit=text, fmt=
'(I5)') status
1384 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1385 '. (IOSTAT = '//trim(text)//
')')
1390 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1391 if ( status .lt. 0 )
then
1393 num_lines = max(num_lines - 1, 1)
1396 if ( status .gt. 0 )
then
1397 write (unit=text, fmt=
'(I5)') num_lines
1398 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1399 ' in file '//trim(filename)//
'.')
1401 if ( len_trim(str_tmp) == length)
then
1402 write(unit=text, fmt=
'(I5)') length
1403 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1404 &
' is too small. Increase the LENGTH value.')
1406 if (len_trim(str_tmp) > max_length) max_length = len_trim(str_tmp)
1407 num_lines = num_lines + 1
1412 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1414 max_length = max_length+1
1418 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1419 call mpp_broadcast(max_length, from_pe, pelist=pelist)
1420 get_ascii_file_num_lines_and_length(1) = num_lines
1421 get_ascii_file_num_lines_and_length(2) = max_length
1423 end function get_ascii_file_num_lines_and_length
1446 subroutine read_ascii_file(FILENAME, LENGTH, Content, PELIST)
1447 character(len=*),
intent(in) :: FILENAME
1448 integer,
intent(in) :: LENGTH
1449 character(len=*),
intent(inout),
dimension(:) :: Content
1450 integer,
intent(in),
optional,
dimension(:) :: PELIST
1453#include<file_version.h>
1455 character(len=5) :: text
1456 logical :: file_exist
1457 integer :: status, f_unit, log_unit
1459 integer :: pnum_lines, num_lines
1460 character(len=LENGTH) :: str_tmp
1462 if( .NOT. read_ascii_file_on)
then
1463 call mpp_error(fatal, &
1464 "mpp_util.inc: get_ascii_file_num_lines needs to be called before calling read_ascii_file")
1466 read_ascii_file_on = .false.
1469 num_lines =
size(content(:))
1471 if ( pe == root_pe )
then
1474 write(log_unit,
'(a)')
'========================================================================'
1475 write(log_unit,
'(a)')
'READ_ASCII_FILE: '//trim(version)
1476 write(log_unit,
'(a)')
'READ_ASCII_FILE: File: '//trim(filename)
1478 inquire(file=filename, exist=file_exist)
1480 if ( file_exist )
then
1481 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1483 if ( status .ne. 0 )
then
1484 write (unit=text, fmt=
'(I5)') status
1485 call mpp_error(fatal,
'READ_ASCII_FILE: Error opening file: '// &
1486 & trim(filename)//
'. (IOSTAT = '//trim(text)//
')')
1489 if ( num_lines .gt. 0 )
then
1492 rewind(unit=f_unit, iostat=status)
1493 if ( status .ne. 0 )
then
1494 write (unit=text, fmt=
'(I5)') status
1495 call mpp_error(fatal,
'READ_ASCII_FILE: Unable to re-read file '//trim(filename)//
'. (IOSTAT = '&
1502 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1504 if ( status .lt. 0 )
then
1506 pnum_lines = max(pnum_lines - 1, 1)
1509 if ( status .gt. 0 )
then
1510 write (unit=text, fmt=
'(I5)') pnum_lines
1511 call mpp_error(fatal,
'READ_ASCII_FILE: Error reading line '// &
1512 & trim(text)//
' in file '//trim(filename)//
'.')
1514 if(pnum_lines > num_lines)
then
1515 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1516 ' is greater than size(Content(:)). ')
1518 if ( len_trim(str_tmp) == length )
then
1519 write(unit=text, fmt=
'(I5)') length
1520 call mpp_error(fatal,
'READ_ASCII_FILE: Length of output string ('//trim(text)// &
1521 &
' is too small. Increase the LENGTH value.')
1523 content(pnum_lines) = str_tmp
1524 pnum_lines = pnum_lines + 1
1526 if(num_lines .NE. pnum_lines)
then
1527 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1528 ' does not equal to size(Content(:)) ' )
1535 call mpp_error(fatal,
'READ_ASCII_FILE: File '//trim(filename)//
' does not exist.')
1540 call mpp_broadcast(content, length, from_pe, pelist=pelist)
1542 end subroutine read_ascii_file
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 get_peset(pelist)
Makes a PE set out of a PE list. A PE list is an ordered list of PEs a PE set is a triad (start,...
subroutine mpp_sync(pelist, do_self)
Synchronize PEs in list.