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 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
460 subroutine mpp_declare_pelist( pelist, name, commID )
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.' )
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
473 end subroutine mpp_declare_pelist
489 subroutine mpp_set_current_pelist( pelist, no_sync )
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.' )
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()
511 end subroutine mpp_set_current_pelist
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
640 subroutine mpp_clock_set_grain( grain )
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.' )
650 end subroutine mpp_clock_set_grain
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
704 function mpp_clock_id( name, flags, grain )
705 integer :: mpp_clock_id
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
724 clock_num = mpp_clock_id
725 call clock_init(mpp_clock_id,name,flags)
727 find_clock:
do while( trim(name).NE.trim(clocks(mpp_clock_id)%name) )
728 mpp_clock_id = mpp_clock_id + 1
729 if( mpp_clock_id.GT.clock_num )
then
730 if( mpp_clock_id.GT.max_clocks )
then
731 call mpp_error( fatal,
'MPP_CLOCK_ID: too many clock requests, ' // &
732 'check your clock id request or increase MAX_CLOCKS.')
734 clock_num = mpp_clock_id
735 call clock_init(mpp_clock_id,name,flags,grain)
742 end function mpp_clock_id
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'
9871001
format(a,f8.2,a,f8.2,a,i6)
9891003
format(a,i6,
' ',
' ',f9.1,a,
' ',f9.2,
'MB/sec')
9901004
format(a,i8,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
1099 subroutine expand_peset()
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)
1152 end subroutine expand_peset
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
1218 subroutine read_input_nml(pelist_name_in, alt_input_nml_path)
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'
1259 lines_and_length = get_ascii_file_num_lines_and_length(filename)
1260 allocate(
character(len=lines_and_length(2))::input_nml_file(lines_and_length(1)))
1261 call read_ascii_file(filename, lines_and_length(2), input_nml_file)
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))
1273 end subroutine read_input_nml
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
1344 function get_ascii_file_num_lines_and_length(FILENAME, PELIST)
1345 character(len=*),
intent(in) :: FILENAME
1346 integer,
intent(in),
optional,
dimension(:) :: PELIST
1348 integer,
dimension(2) :: get_ascii_file_num_lines_and_length
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.
1364 get_ascii_file_num_lines_and_length = -1
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)
1411 get_ascii_file_num_lines_and_length(1) = num_lines
1412 get_ascii_file_num_lines_and_length(2) = max_length
1414 end function get_ascii_file_num_lines_and_length
1437 subroutine read_ascii_file(FILENAME, LENGTH, Content, 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)
1533 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.