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 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
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.' )
476 i = get_peset(pelist)
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
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.' )
512 current_peset_num = get_peset(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()
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
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.' )
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
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
736 find_clock:
do while( trim(name).NE.trim(clocks(
mpp_clock_id)%name) )
740 call mpp_error( fatal,
'MPP_CLOCK_ID: too many clock requests, ' // &
741 'check your clock id request or increase MAX_CLOCKS.')
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'
996 1001
format(a,f8.2,a,f8.2,a,i6)
998 1003
format(a,i6,
' ',
' ',f9.1,a,
' ',f9.2,
'MB/sec')
999 1004
format(a,i8,a,f9.2,a)
1000 1005
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
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)
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
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'
1269 allocate(
character(len=lines_and_length(2))::input_nml_file(lines_and_length(1)))
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))
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
1354 character(len=*),
intent(in) :: filename
1355 integer,
intent(in),
optional,
dimension(:) :: pelist
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.
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)
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)
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....