27 #if defined(use_libMPI)
28 #include <mpp_util_mpi.inc>
30 #include <mpp_util_nocomm.inc>
60 character(len=11) :: this_pe
82 if( pe.EQ.root_pe )
then
83 write(this_pe,
'(a,i6.6,a)')
'.',pe,
'.out'
84 inquire( file=trim(configfile)//this_pe, opened=opened )
88 open(newunit=log_unit, status=
'UNKNOWN', file=trim(configfile)//this_pe, position=
'APPEND', err=10 )
92 inquire(unit=etc_unit, opened=opened )
96 open(newunit=etc_unit, status=
'UNKNOWN', file=trim(etcfile), position=
'APPEND', err=11 )
101 10
call mpp_error( fatal,
'STDLOG: unable to open '//trim(configfile)//this_pe//
'.' )
102 11
call mpp_error( fatal,
'STDLOG: unable to open '//trim(etcfile)//
'.' )
106 subroutine mpp_init_logfile()
109 character(len=11) :: this_pe
110 if( pe.EQ.root_pe )
then
112 write(this_pe,
'(a,i6.6,a)')
'.',p,
'.out'
113 inquire( file=trim(configfile)//this_pe, exist=exist )
115 open(newunit=log_unit, file=trim(configfile)//this_pe, status=
'REPLACE' )
120 end subroutine mpp_init_logfile
125 character(len=11) :: this_pe
126 if( pe.EQ.root_pe )
then
127 write(this_pe,
'(a,i6.6,a)')
'.',pe,
'.out'
128 inquire( file=trim(warnfile)//this_pe, exist=exist )
130 open(newunit=warn_unit, file=trim(warnfile)//this_pe, status=
'REPLACE' )
132 open(newunit=warn_unit, file=trim(warnfile)//this_pe, status=
'NEW' )
141 if(.not. module_is_initialized)
call mpp_error(fatal,
"mpp_mod: warnlog cannot be called before mpp_init")
142 if(root_pe .eq. pe)
then
151 subroutine mpp_set_warn_level(flag)
152 integer,
intent(in) :: flag
154 if( flag.EQ.warning )
then
155 warnings_are_fatal = .false.
156 else if( flag.EQ.fatal )
then
157 warnings_are_fatal = .true.
159 call mpp_error( fatal,
'MPP_SET_WARN_LEVEL: warning flag must be set to WARNING or FATAL.' )
162 end subroutine mpp_set_warn_level
165 function mpp_error_state()
166 integer :: mpp_error_state
167 mpp_error_state = error_state
169 end function mpp_error_state
174 character(len=*),
intent(in) :: routine, errormsg
175 integer,
intent(in) :: errortype
177 call mpp_error( errortype, trim(routine)//
': '//trim(errormsg) )
182 subroutine mpp_error_noargs()
183 call mpp_error(fatal)
184 end subroutine mpp_error_noargs
187 subroutine mpp_error_is(errortype, errormsg1, mpp_ival, errormsg2)
188 integer,
intent(in) :: errortype
189 INTEGER,
intent(in) :: mpp_ival
190 character(len=*),
intent(in) :: errormsg1
191 character(len=*),
intent(in),
optional :: errormsg2
192 call mpp_error( errortype, errormsg1, (/mpp_ival/), errormsg2)
193 end subroutine mpp_error_is
195 subroutine mpp_error_rs(errortype, errormsg1, mpp_rval, errormsg2)
196 integer,
intent(in) :: errortype
197 REAL,
intent(in) :: mpp_rval
198 character(len=*),
intent(in) :: errormsg1
199 character(len=*),
intent(in),
optional :: errormsg2
200 call mpp_error( errortype, errormsg1, (/mpp_rval/), errormsg2)
201 end subroutine mpp_error_rs
203 subroutine mpp_error_ia(errortype, errormsg1, array, errormsg2)
204 integer,
intent(in) :: errortype
205 INTEGER,
dimension(:),
intent(in) :: array
206 character(len=*),
intent(in) :: errormsg1
207 character(len=*),
intent(in),
optional :: errormsg2
208 character(len=512) :: string
210 string = errormsg1//trim(array_to_char(array))
211 if(
present(errormsg2)) string = trim(string)//errormsg2
214 end subroutine mpp_error_ia
217 subroutine mpp_error_ra(errortype, errormsg1, array, errormsg2)
218 integer,
intent(in) :: errortype
219 REAL,
dimension(:),
intent(in) :: array
220 character(len=*),
intent(in) :: errormsg1
221 character(len=*),
intent(in),
optional :: errormsg2
222 character(len=512) :: string
224 string = errormsg1//trim(array_to_char(array))
225 if(
present(errormsg2)) string = trim(string)//errormsg2
228 end subroutine mpp_error_ra
231 #define _SUBNAME_ mpp_error_ia_ia
232 #define _ARRAY1TYPE_ integer
233 #define _ARRAY2TYPE_ integer
234 #include <mpp_error_a_a.fh>
239 #define _SUBNAME_ mpp_error_ia_ra
240 #define _ARRAY1TYPE_ integer
241 #define _ARRAY2TYPE_ real
242 #include <mpp_error_a_a.fh>
247 #define _SUBNAME_ mpp_error_ra_ia
248 #define _ARRAY1TYPE_ real
249 #define _ARRAY2TYPE_ integer
250 #include <mpp_error_a_a.fh>
255 #define _SUBNAME_ mpp_error_ra_ra
256 #define _ARRAY1TYPE_ real
257 #define _ARRAY2TYPE_ real
258 #include <mpp_error_a_a.fh>
263 #define _SUBNAME_ mpp_error_ia_is
264 #define _ARRAY1TYPE_ integer
265 #define _ARRAY2TYPE_ integer
266 #include <mpp_error_a_s.fh>
271 #define _SUBNAME_ mpp_error_ia_rs
272 #define _ARRAY1TYPE_ integer
273 #define _ARRAY2TYPE_ real
274 #include <mpp_error_a_s.fh>
279 #define _SUBNAME_ mpp_error_ra_is
280 #define _ARRAY1TYPE_ real
281 #define _ARRAY2TYPE_ integer
282 #include <mpp_error_a_s.fh>
287 #define _SUBNAME_ mpp_error_ra_rs
288 #define _ARRAY1TYPE_ real
289 #define _ARRAY2TYPE_ real
290 #include <mpp_error_a_s.fh>
295 #define _SUBNAME_ mpp_error_is_ia
296 #define _ARRAY1TYPE_ integer
297 #define _ARRAY2TYPE_ integer
298 #include <mpp_error_s_a.fh>
303 #define _SUBNAME_ mpp_error_is_ra
304 #define _ARRAY1TYPE_ integer
305 #define _ARRAY2TYPE_ real
306 #include <mpp_error_s_a.fh>
311 #define _SUBNAME_ mpp_error_rs_ia
312 #define _ARRAY1TYPE_ real
313 #define _ARRAY2TYPE_ integer
314 #include <mpp_error_s_a.fh>
319 #define _SUBNAME_ mpp_error_rs_ra
320 #define _ARRAY1TYPE_ real
321 #define _ARRAY2TYPE_ real
322 #include <mpp_error_s_a.fh>
327 #define _SUBNAME_ mpp_error_is_is
328 #define _ARRAY1TYPE_ integer
329 #define _ARRAY2TYPE_ integer
330 #include <mpp_error_s_s.fh>
335 #define _SUBNAME_ mpp_error_is_rs
336 #define _ARRAY1TYPE_ integer
337 #define _ARRAY2TYPE_ real
338 #include <mpp_error_s_s.fh>
343 #define _SUBNAME_ mpp_error_rs_is
344 #define _ARRAY1TYPE_ real
345 #define _ARRAY2TYPE_ integer
346 #include <mpp_error_s_s.fh>
351 #define _SUBNAME_ mpp_error_rs_rs
352 #define _ARRAY1TYPE_ real
353 #define _ARRAY2TYPE_ real
354 #include <mpp_error_s_s.fh>
359 function iarray_to_char(iarray)
result(string)
360 integer,
intent(in) :: iarray(:)
361 character(len=256) :: string
362 character(len=32) :: chtmp
363 integer :: i, len_tmp, len_string
367 write(chtmp,
'(i16)') iarray(i)
368 chtmp = adjustl(chtmp)
369 len_tmp = len_trim(chtmp)
370 len_string = len_trim(string)
371 string(len_string+1:len_string+len_tmp) = trim(chtmp)
372 string(len_string+len_tmp+1:len_string+len_tmp+1) =
','
374 len_string = len_trim(string)
375 string(len_string:len_string) =
' '
377 end function iarray_to_char
379 function rarray_to_char(rarray)
result(string)
380 real,
intent(in) :: rarray(:)
381 character(len=256) :: string
382 character(len=32) :: chtmp
383 integer :: i, len_tmp, len_string
387 write(chtmp,
'(G16.9)') rarray(i)
388 chtmp = adjustl(chtmp)
389 len_tmp = len_trim(chtmp)
390 len_string = len_trim(string)
391 string(len_string+1:len_string+len_tmp) = trim(chtmp)
392 string(len_string+len_tmp+1:len_string+len_tmp+1) =
','
394 len_string = len_trim(string)
395 string(len_string:len_string) =
' '
397 end function rarray_to_char
408 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_PE: You must first call mpp_init.' )
422 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_NPES: You must first call mpp_init.' )
423 mpp_npes =
size(peset(current_peset_num)%list(:))
428 function mpp_root_pe()
429 integer :: mpp_root_pe
431 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_ROOT_PE: You must first call mpp_init.' )
432 mpp_root_pe = root_pe
434 end function mpp_root_pe
437 function mpp_commid()
438 integer :: mpp_commid
440 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_COMMID: You must first call mpp_init.' )
441 mpp_commid = peset(current_peset_num)%id
443 end function mpp_commid
446 subroutine mpp_set_root_pe(num)
447 integer,
intent(in) :: num
449 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_ROOT_PE: You must first call mpp_init.' )
450 if( .NOT.(any(num.EQ.peset(current_peset_num)%list(:))) ) &
451 call mpp_error( fatal,
'MPP_SET_ROOT_PE: you cannot set a root PE outside the current pelist.' )
454 end subroutine mpp_set_root_pe
469 integer,
intent(in) :: pelist(:)
470 character(len=*),
intent(in),
optional :: name
471 integer,
intent(out),
optional :: commID
474 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_DECLARE_PELIST: You must first call mpp_init.' )
475 i = get_peset(pelist)
476 write( peset(i)%name,
'(a,i2.2)' )
'PElist', i
477 if(
PRESENT(name) )peset(i)%name = name
478 if(
PRESENT(commid) )commid = peset(i)%id
505 integer,
intent(in),
optional :: pelist(:)
506 logical,
intent(in),
optional :: no_sync
508 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: You must first call mpp_init.' )
509 if(
PRESENT(pelist) )
then
510 if( .NOT.any(pe.EQ.pelist) )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: pe must be in pelist.' )
511 current_peset_num = get_peset(pelist)
513 current_peset_num = world_peset_num
515 call mpp_set_root_pe( minval(peset(current_peset_num)%list(:)) )
516 if(.not.
PRESENT(no_sync))
call mpp_sync()
522 function mpp_get_current_pelist_name()
524 character(len=len(peset(current_peset_num)%name)) :: mpp_get_current_pelist_name
526 mpp_get_current_pelist_name = peset(current_peset_num)%name
527 end function mpp_get_current_pelist_name
532 subroutine mpp_get_current_pelist( pelist, name, commID )
533 integer,
intent(out) :: pelist(:)
534 character(len=*),
intent(out),
optional :: name
535 integer,
intent(out),
optional :: commID
537 if(
size(pelist(:)).NE.
size(peset(current_peset_num)%list(:)) ) &
538 call mpp_error( fatal,
'MPP_GET_CURRENT_PELIST: size(pelist) is wrong.' )
539 pelist(:) = peset(current_peset_num)%list(:)
540 if(
PRESENT(name) )name = peset(current_peset_num)%name
542 if(
PRESENT(commid) )commid = peset(current_peset_num)%id
546 end subroutine mpp_get_current_pelist
649 integer,
intent(in) :: grain
654 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_SET_GRAIN: You must first call mpp_init.' )
661 subroutine clock_init( id, name, flags, grain )
662 integer,
intent(in) :: id
663 character(len=*),
intent(in) :: name
664 integer,
intent(in),
optional :: flags, grain
667 clocks(id)%name = name
670 clocks(id)%total_ticks = 0
671 clocks(id)%sync_on_begin = .false.
672 clocks(id)%detailed = .false.
673 clocks(id)%peset_num = current_peset_num
674 if(
PRESENT(flags) )
then
675 if( btest(flags,0) )clocks(id)%sync_on_begin = .true.
676 if( btest(flags,1) )clocks(id)%detailed = .true.
679 if(
PRESENT(grain) )clocks(id)%grain = grain
680 if( clocks(id)%detailed )
then
681 allocate( clocks(id)%events(max_event_types) )
682 clocks(id)%events(event_allreduce)%name =
'ALLREDUCE'
683 clocks(id)%events(event_broadcast)%name =
'BROADCAST'
684 clocks(id)%events(event_recv)%name =
'RECV'
685 clocks(id)%events(event_send)%name =
'SEND'
686 clocks(id)%events(event_wait)%name =
'WAIT'
687 do i=1,max_event_types
688 clocks(id)%events(i)%ticks(:) = 0
689 clocks(id)%events(i)%bytes(:) = 0
690 clocks(id)%events(i)%calls = 0
692 clock_summary(id)%name = name
693 clock_summary(id)%event(event_allreduce)%name =
'ALLREDUCE'
694 clock_summary(id)%event(event_broadcast)%name =
'BROADCAST'
695 clock_summary(id)%event(event_recv)%name =
'RECV'
696 clock_summary(id)%event(event_send)%name =
'SEND'
697 clock_summary(id)%event(event_wait)%name =
'WAIT'
698 do i=1,max_event_types
699 clock_summary(id)%event(i)%msg_size_sums(:) = 0.0
700 clock_summary(id)%event(i)%msg_time_sums(:) = 0.0
701 clock_summary(id)%event(i)%total_data = 0.0
702 clock_summary(id)%event(i)%total_time = 0.0
703 clock_summary(id)%event(i)%msg_size_cnts(:) = 0
704 clock_summary(id)%event(i)%total_cnts = 0
708 end subroutine clock_init
714 character(len=*),
intent(in) :: name
715 integer,
intent(in),
optional :: flags, grain
717 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_ID: You must first call mpp_init.')
723 if(
PRESENT(grain) )
then
724 if( grain.GT.clock_grain )
then
731 if( clock_num.EQ.0 )
then
735 find_clock:
do while( trim(name).NE.trim(clocks(
mpp_clock_id)%name) )
739 call mpp_error( fatal,
'MPP_CLOCK_ID: too many clock requests, ' // &
740 'check your clock id request or increase MAX_CLOCKS.')
753 subroutine mpp_clock_begin(id)
754 integer,
intent(in) :: id
756 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: You must first call mpp_init.' )
757 if( .not. mpp_record_timing_data)
return
759 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
762 if( clocks(id)%peset_num.NE.current_peset_num ) &
763 call mpp_error( fatal,
'MPP_CLOCK_BEGIN: cannot change pelist context of a clock.' )
764 if( clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: mpp_clock_begin is called again '// &
765 'before calling mpp_clock_end for the clock '//trim(clocks(id)%name) )
766 if( clocks(id)%sync_on_begin .OR. sync_all_clocks )
then
774 num_clock_ids = num_clock_ids+1
775 if(num_clock_ids > max_clocks)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: max num previous_clock exceeded.' )
776 previous_clock(num_clock_ids) = current_clock
779 call system_clock( clocks(id)%tick )
780 clocks(id)%hits = clocks(id)%hits + 1
781 clocks(id)%is_on = .true.
784 end subroutine mpp_clock_begin
787 subroutine mpp_clock_end(id)
788 integer,
intent(in) :: id
789 integer(i8_kind) :: delta
792 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_END: You must first call mpp_init.' )
793 if( .not. mpp_record_timing_data)
return
795 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
797 if( .NOT. clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_END: mpp_clock_end is called '// &
798 'before calling mpp_clock_begin for the clock '//trim(clocks(id)%name) )
800 call system_clock(end_tick)
801 if( clocks(id)%peset_num.NE.current_peset_num ) &
802 call mpp_error( fatal,
'MPP_CLOCK_END: cannot change pelist context of a clock.' )
803 delta = end_tick - clocks(id)%tick
806 write( errunit,* )
'pe, id, start_tick, end_tick, delta, max_ticks=', pe, id, clocks(id)%tick, end_tick, &
808 delta = delta + max_ticks + 1
809 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
811 clocks(id)%total_ticks = clocks(id)%total_ticks + delta
813 if(num_clock_ids < 1)
call mpp_error(note,
'MPP_CLOCK_END: min num previous_clock < 1.' )
814 current_clock = previous_clock(num_clock_ids)
815 num_clock_ids = num_clock_ids-1
817 clocks(id)%is_on = .false.
820 end subroutine mpp_clock_end
823 subroutine mpp_record_time_start()
825 mpp_record_timing_data = .true.
827 end subroutine mpp_record_time_start
830 subroutine mpp_record_time_end()
832 mpp_record_timing_data = .false.
834 end subroutine mpp_record_time_end
838 subroutine increment_current_clock( event_id, bytes )
839 integer,
intent(in) :: event_id
840 integer,
intent(in),
optional :: bytes
842 integer(i8_kind) :: delta
845 if( .not. mpp_record_timing_data )
return
846 if( .not.debug .or. (current_clock.EQ.0) )
return
847 if( current_clock.LT.0 .OR. current_clock.GT.clock_num )
call mpp_error( fatal, &
848 &
'MPP_CLOCK_BEGIN: invalid current_clock.' )
849 if( .NOT.clocks(current_clock)%detailed )
return
850 call system_clock(end_tick)
851 n = clocks(current_clock)%events(event_id)%calls + 1
853 if( n.EQ.max_events )
call mpp_error( warning, &
854 'MPP_CLOCK: events exceed MAX_EVENTS, ignore detailed profiling data for clock '// &
855 & trim(clocks(current_clock)%name) )
856 if( n.GT.max_events )
return
858 clocks(current_clock)%events(event_id)%calls = n
859 delta = end_tick - start_tick
862 write( errunit,* )
'pe, event_id, start_tick, end_tick, delta, max_ticks=', &
863 pe, event_id, start_tick, end_tick, delta, max_ticks
864 delta = delta + max_ticks + 1
865 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
867 clocks(current_clock)%events(event_id)%ticks(n) = delta
868 if(
PRESENT(bytes) )clocks(current_clock)%events(event_id)%bytes(n) = bytes
870 end subroutine increment_current_clock
874 subroutine dump_clock_summary()
876 real :: total_time,total_time_all,total_data
877 real :: msg_size,eff_bw,s
878 integer :: sd_unit, total_calls
879 integer :: j,k,ct, msg_cnt
880 character(len=2) :: u
881 character(len=FMS_FILE_LEN) :: filename
882 character(len=20),
dimension(MAX_BINS),
save :: bin
884 data bin( 1) /
' 0 - 8 B: '/
885 data bin( 2) /
' 8 - 16 B: '/
886 data bin( 3) /
' 16 - 32 B: '/
887 data bin( 4) /
' 32 - 64 B: '/
888 data bin( 5) /
' 64 - 128 B: '/
889 data bin( 6) /
'128 - 256 B: '/
890 data bin( 7) /
'256 - 512 B: '/
891 data bin( 8) /
'512 - 1024 B: '/
892 data bin( 9) /
' 1.0 - 2.1 KB: '/
893 data bin(10) /
' 2.1 - 4.1 KB: '/
894 data bin(11) /
' 4.1 - 8.2 KB: '/
895 data bin(12) /
' 8.2 - 16.4 KB: '/
896 data bin(13) /
' 16.4 - 32.8 KB: '/
897 data bin(14) /
' 32.8 - 65.5 KB: '/
898 data bin(15) /
' 65.5 - 131.1 KB: '/
899 data bin(16) /
'131.1 - 262.1 KB: '/
900 data bin(17) /
'262.1 - 524.3 KB: '/
901 data bin(18) /
'524.3 - 1048.6 KB: '/
902 data bin(19) /
' 1.0 - 2.1 MB: '/
903 data bin(20) /
' >2.1 MB: '/
905 if( .NOT.any(clocks(1:clock_num)%detailed) )
return
906 write( filename,
'(a,i6.6)' )
'mpp_clock.out.', pe
908 open(newunit=sd_unit,file=trim(filename),form=
'formatted')
910 comm_type:
do ct = 1,clock_num
912 if( .NOT.clocks(ct)%detailed )cycle
914 clock_summary(ct)%name(1:15),
' Communication Data for PE ',pe
920 event_type:
do k = 1,max_event_types-1
922 if(clock_summary(ct)%event(k)%total_time == 0.0)cycle
924 total_time = clock_summary(ct)%event(k)%total_time
925 total_time_all = total_time_all + total_time
926 total_data = clock_summary(ct)%event(k)%total_data
927 total_calls = int(clock_summary(ct)%event(k)%total_cnts)
929 write(sd_unit,1000) clock_summary(ct)%event(k)%name(1:9) //
':'
931 write(sd_unit,1001)
'Total Data: ',total_data*1.0e-6, &
932 'MB; Total Time: ', total_time, &
933 'secs; Total Calls: ',total_calls
936 write(sd_unit,1002)
' Bin Counts Avg Size Eff B/W'
939 bin_loop:
do j=1,max_bins
941 if(clock_summary(ct)%event(k)%msg_size_cnts(j)==0)cycle
954 msg_cnt = int(clock_summary(ct)%event(k)%msg_size_cnts(j))
956 s*(clock_summary(ct)%event(k)%msg_size_sums(j)/real(msg_cnt))
957 eff_bw = (1.0e-6)*( clock_summary(ct)%event(k)%msg_size_sums(j) / &
958 clock_summary(ct)%event(k)%msg_time_sums(j) )
960 write(sd_unit,1003) bin(j),msg_cnt,msg_size,u,eff_bw
970 if(clock_summary(ct)%event(max_event_types)%total_time>0.0)
then
972 total_time = clock_summary(ct)%event(max_event_types)%total_time
973 total_time_all = total_time_all + total_time
974 total_calls = int(clock_summary(ct)%event(max_event_types)%total_cnts)
976 write(sd_unit,1000) clock_summary(ct)%event(max_event_types)%name(1:9) //
':'
978 write(sd_unit,1004)
'Total Calls: ',total_calls,
'; Total Time: ', &
984 write(sd_unit,1005)
'Total communication time spent for ' // &
985 clock_summary(ct)%name(1:9) //
': ',total_time_all,
'secs'
995 1001
format(a,f8.2,a,f8.2,a,i6)
997 1003
format(a,i6,
' ',
' ',f9.1,a,
' ',f9.2,
'MB/sec')
998 1004
format(a,i8,a,f9.2,a)
999 1005
format(a,f9.2,a)
1001 end subroutine dump_clock_summary
1005 integer function get_unit()
1010 if (pe == root_pe)
call mpp_error(warning, &
1011 'get_unit is deprecated and will be removed in a future release, please use the Fortran intrinsic newunit')
1013 inquire(unit=i,opened=l_open)
1018 call mpp_error(fatal,
'Unable to get I/O unit')
1024 end function get_unit
1028 subroutine sum_clock_data()
1030 integer :: i,j,k,ct,event_size,event_cnt
1033 clock_type:
do ct=1,clock_num
1034 if( .NOT.clocks(ct)%detailed )cycle
1035 event_type:
do j=1,max_event_types-1
1036 event_cnt = clocks(ct)%events(j)%calls
1037 event_summary:
do i=1,event_cnt
1039 clock_summary(ct)%event(j)%total_cnts = &
1040 clock_summary(ct)%event(j)%total_cnts + 1
1042 event_size = int(clocks(ct)%events(j)%bytes(i))
1044 k = find_bin(event_size)
1046 clock_summary(ct)%event(j)%msg_size_cnts(k) = &
1047 clock_summary(ct)%event(j)%msg_size_cnts(k) + 1
1049 clock_summary(ct)%event(j)%msg_size_sums(k) = &
1050 clock_summary(ct)%event(j)%msg_size_sums(k) &
1051 + clocks(ct)%events(j)%bytes(i)
1053 clock_summary(ct)%event(j)%total_data = &
1054 clock_summary(ct)%event(j)%total_data &
1055 + clocks(ct)%events(j)%bytes(i)
1057 msg_time = clocks(ct)%events(j)%ticks(i)
1058 msg_time = tick_rate * real( clocks(ct)%events(j)%ticks(i) )
1060 clock_summary(ct)%event(j)%msg_time_sums(k) = &
1061 clock_summary(ct)%event(j)%msg_time_sums(k) + msg_time
1063 clock_summary(ct)%event(j)%total_time = &
1064 clock_summary(ct)%event(j)%total_time + msg_time
1066 end do event_summary
1073 event_cnt = clocks(ct)%events(j)%calls
1074 clock_summary(ct)%event(j)%msg_size_cnts(1) = event_cnt
1075 clock_summary(ct)%event(j)%total_cnts = event_cnt
1077 msg_time = tick_rate * real( sum( clocks(ct)%events(j)%ticks(1:event_cnt) ) )
1078 clock_summary(ct)%event(j)%msg_time_sums(1) = &
1079 clock_summary(ct)%event(j)%msg_time_sums(1) + msg_time
1081 clock_summary(ct)%event(j)%total_time = clock_summary(ct)%event(j)%msg_time_sums(1)
1087 integer function find_bin(event_size)
1089 integer,
intent(in) :: event_size
1090 integer :: k,msg_size
1094 do while(event_size>msg_size .and. k<max_bins)
1096 msg_size = msg_size*2
1100 end function find_bin
1102 end subroutine sum_clock_data
1108 integer :: old_peset_max,n
1109 type(communicator),
allocatable :: peset_old(:)
1111 old_peset_max = current_peset_max
1112 if(old_peset_max .GE. peset_max)
call mpp_error(fatal, &
1113 "mpp_mod(expand_peset): the number of peset reached PESET_MAX, increase PESET_MAX or contact developer")
1116 allocate(peset_old(0:old_peset_max))
1117 do n = 0, old_peset_max
1118 peset_old(n)%count = peset(n)%count
1119 peset_old(n)%id = peset(n)%id
1120 peset_old(n)%group = peset(n)%group
1121 peset_old(n)%name = peset(n)%name
1122 peset_old(n)%start = peset(n)%start
1123 peset_old(n)%log2stride = peset(n)%log2stride
1125 if(
ASSOCIATED(peset(n)%list) )
then
1126 allocate(peset_old(n)%list(
size(peset(n)%list(:))) )
1127 peset_old(n)%list(:) = peset(n)%list(:)
1128 deallocate(peset(n)%list)
1134 current_peset_max = min(peset_max, 2*old_peset_max)
1135 allocate(peset(0:current_peset_max))
1140 peset(:)%log2stride = -1
1142 do n = 0, old_peset_max
1143 peset(n)%count = peset_old(n)%count
1144 peset(n)%id = peset_old(n)%id
1145 peset(n)%group = peset_old(n)%group
1146 peset(n)%name = peset_old(n)%name
1147 peset(n)%start = peset_old(n)%start
1148 peset(n)%log2stride = peset_old(n)%log2stride
1150 if(
ASSOCIATED(peset_old(n)%list) )
then
1151 allocate(peset(n)%list(
size(peset_old(n)%list(:))) )
1152 peset(n)%list(:) = peset_old(n)%list(:)
1153 deallocate(peset_old(n)%list)
1156 deallocate(peset_old)
1158 call mpp_error(note,
"mpp_mod(expand_peset): size of peset is expanded to ", current_peset_max)
1163 function uppercase (cs)
1164 character(len=*),
intent(in) :: cs
1165 character(len=len(cs)),
target :: uppercase
1167 character,
pointer :: ca
1168 integer,
parameter :: co=iachar(
'A')-iachar(
'a')
1174 uppercase = cs(1:tlen)
1176 ca => uppercase(k:k)
1177 if(ca >=
"a" .and. ca <=
"z") ca = achar(ichar(ca)+co)
1180 end function uppercase
1184 function lowercase (cs)
1185 character(len=*),
intent(in) :: cs
1186 character(len=len(cs)),
target :: lowercase
1187 integer,
parameter :: co=iachar(
'a')-iachar(
'A')
1189 character,
pointer :: ca
1195 lowercase = cs(1:tlen)
1197 ca => lowercase(k:k)
1198 if(ca >=
"A" .and. ca <=
"Z") ca = achar(ichar(ca)+co)
1201 end function lowercase
1229 #include<file_version.h>
1231 character(len=*),
intent(in),
optional :: pelist_name_in
1232 character(len=*),
intent(in),
optional :: alt_input_nml_path
1236 integer,
dimension(2) :: lines_and_length
1237 logical :: file_exist
1238 character(len=len(peset(current_peset_num)%name)) :: pelist_name
1239 character(len=FMS_PATH_LEN) :: filename
1242 if (
allocated(input_nml_file) )
then
1243 deallocate(input_nml_file)
1247 if (
PRESENT(pelist_name_in))
then
1249 if (len(pelist_name_in) > len(pelist_name))
then
1250 call mpp_error(fatal, &
1251 "mpp_util.inc: read_input_nml optional argument pelist_name_in has size greater than local pelist_name")
1253 pelist_name = pelist_name_in
1256 pelist_name = mpp_get_current_pelist_name()
1258 filename=
'input_'//trim(pelist_name)//
'.nml'
1259 inquire(file=filename, exist=file_exist)
1260 if (.not. file_exist )
then
1261 if (
present(alt_input_nml_path))
then
1262 filename = alt_input_nml_path
1264 filename =
'input.nml'
1268 allocate(
character(len=lines_and_length(2))::input_nml_file(lines_and_length(1)))
1272 if (pe == root_pe)
then
1274 write(log_unit,
'(a)')
'========================================================================'
1275 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(version)
1276 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(filename)//
' '
1277 do i = 1, lines_and_length(1)
1278 write(log_unit,*) trim(input_nml_file(i))
1286 function get_ascii_file_num_lines(FILENAME, LENGTH, PELIST)
1287 character(len=*),
intent(in) :: FILENAME
1288 integer,
intent(in) :: LENGTH
1289 integer,
intent(in),
optional,
dimension(:) :: PELIST
1291 integer :: num_lines, get_ascii_file_num_lines
1292 character(len=LENGTH) :: str_tmp
1293 character(len=5) :: text
1294 integer :: status, f_unit, from_pe
1295 logical :: file_exist
1297 if( read_ascii_file_on)
then
1298 call mpp_error(fatal, &
1299 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1301 read_ascii_file_on = .true.
1304 get_ascii_file_num_lines = -1
1306 if ( pe == root_pe )
then
1307 inquire(file=filename, exist=file_exist)
1309 if ( file_exist )
then
1310 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1312 if ( status .ne. 0 )
then
1313 write (unit=text, fmt=
'(I5)') status
1314 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1315 '. (IOSTAT = '//trim(text)//
')')
1319 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1320 if ( status .lt. 0 )
then
1322 num_lines = max(num_lines - 1, 1)
1325 if ( status .gt. 0 )
then
1326 write (unit=text, fmt=
'(I5)') num_lines
1327 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1328 ' in file '//trim(filename)//
'.')
1330 if ( len_trim(str_tmp) == length )
then
1331 write(unit=text, fmt=
'(I5)') length
1332 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1333 &
' is too small. Increase the LENGTH value.')
1335 num_lines = num_lines + 1
1340 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1345 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1346 get_ascii_file_num_lines = num_lines
1348 end function get_ascii_file_num_lines
1353 character(len=*),
intent(in) :: filename
1354 integer,
intent(in),
optional,
dimension(:) :: pelist
1358 integer :: num_lines, max_length
1359 integer,
parameter :: length=1024
1360 character(len=LENGTH) :: str_tmp
1361 character(len=5) :: text
1362 integer :: status, f_unit, from_pe
1363 logical :: file_exist
1365 if( read_ascii_file_on)
then
1366 call mpp_error(fatal, &
1367 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1369 read_ascii_file_on = .true.
1375 if ( pe == root_pe )
then
1376 inquire(file=filename, exist=file_exist)
1378 if ( file_exist )
then
1379 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1381 if ( status .ne. 0 )
then
1382 write (unit=text, fmt=
'(I5)') status
1383 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1384 '. (IOSTAT = '//trim(text)//
')')
1389 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1390 if ( status .lt. 0 )
then
1392 num_lines = max(num_lines - 1, 1)
1395 if ( status .gt. 0 )
then
1396 write (unit=text, fmt=
'(I5)') num_lines
1397 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1398 ' in file '//trim(filename)//
'.')
1400 if ( len_trim(str_tmp) == length)
then
1401 write(unit=text, fmt=
'(I5)') length
1402 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1403 &
' is too small. Increase the LENGTH value.')
1405 if (len_trim(str_tmp) > max_length) max_length = len_trim(str_tmp)
1406 num_lines = num_lines + 1
1411 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1413 max_length = max_length+1
1417 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1418 call mpp_broadcast(max_length, from_pe, pelist=pelist)
1446 character(len=*),
intent(in) :: FILENAME
1447 integer,
intent(in) :: LENGTH
1448 character(len=*),
intent(inout),
dimension(:) :: Content
1449 integer,
intent(in),
optional,
dimension(:) :: PELIST
1452 #include<file_version.h>
1454 character(len=5) :: text
1455 logical :: file_exist
1456 integer :: status, f_unit, log_unit
1458 integer :: pnum_lines, num_lines
1459 character(len=LENGTH) :: str_tmp
1461 if( .NOT. read_ascii_file_on)
then
1462 call mpp_error(fatal, &
1463 "mpp_util.inc: get_ascii_file_num_lines needs to be called before calling read_ascii_file")
1465 read_ascii_file_on = .false.
1468 num_lines =
size(content(:))
1470 if ( pe == root_pe )
then
1473 write(log_unit,
'(a)')
'========================================================================'
1474 write(log_unit,
'(a)')
'READ_ASCII_FILE: '//trim(version)
1475 write(log_unit,
'(a)')
'READ_ASCII_FILE: File: '//trim(filename)
1477 inquire(file=filename, exist=file_exist)
1479 if ( file_exist )
then
1480 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1482 if ( status .ne. 0 )
then
1483 write (unit=text, fmt=
'(I5)') status
1484 call mpp_error(fatal,
'READ_ASCII_FILE: Error opening file: '// &
1485 & trim(filename)//
'. (IOSTAT = '//trim(text)//
')')
1488 if ( num_lines .gt. 0 )
then
1491 rewind(unit=f_unit, iostat=status)
1492 if ( status .ne. 0 )
then
1493 write (unit=text, fmt=
'(I5)') status
1494 call mpp_error(fatal,
'READ_ASCII_FILE: Unable to re-read file '//trim(filename)//
'. (IOSTAT = '&
1501 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1503 if ( status .lt. 0 )
then
1505 pnum_lines = max(pnum_lines - 1, 1)
1508 if ( status .gt. 0 )
then
1509 write (unit=text, fmt=
'(I5)') pnum_lines
1510 call mpp_error(fatal,
'READ_ASCII_FILE: Error reading line '// &
1511 & trim(text)//
' in file '//trim(filename)//
'.')
1513 if(pnum_lines > num_lines)
then
1514 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1515 ' is greater than size(Content(:)). ')
1517 if ( len_trim(str_tmp) == length )
then
1518 write(unit=text, fmt=
'(I5)') length
1519 call mpp_error(fatal,
'READ_ASCII_FILE: Length of output string ('//trim(text)// &
1520 &
' is too small. Increase the LENGTH value.')
1522 content(pnum_lines) = str_tmp
1523 pnum_lines = pnum_lines + 1
1525 if(num_lines .NE. pnum_lines)
then
1526 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1527 ' does not equal to size(Content(:)) ' )
1534 call mpp_error(fatal,
'READ_ASCII_FILE: File '//trim(filename)//
' does not exist.')
1539 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....