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 type(mpi_comm) :: mpp_comm
439 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'mpp_comm: You must first call mpp_init.' )
440 mpp_comm = peset(current_peset_num)%comm
441 end function mpp_comm
443 function mpp_commid()
444 integer :: mpp_commid
446 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'mpp_commID: You must first call mpp_init.' )
447 call mpp_error(note,
"mpp_commID() is deprecated. Please use mpp_comm() instead.")
448 mpp_commid = peset(current_peset_num)%comm%mpi_val
449 end function mpp_commid
452 subroutine mpp_set_root_pe(num)
453 integer,
intent(in) :: num
455 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_ROOT_PE: You must first call mpp_init.' )
456 if( .NOT.(any(num.EQ.peset(current_peset_num)%list(:))) ) &
457 call mpp_error( fatal,
'MPP_SET_ROOT_PE: you cannot set a root PE outside the current pelist.' )
460 end subroutine mpp_set_root_pe
475 integer,
intent(in) :: pelist(:)
476 character(len=*),
intent(in),
optional :: name
477 integer,
intent(out),
optional :: commID
480 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_DECLARE_PELIST: You must first call mpp_init.' )
481 i = get_peset(pelist)
482 write( peset(i)%name,
'(a,i2.2)' )
'PElist', i
483 if(
PRESENT(name) ) peset(i)%name = name
484 if(
PRESENT(commid) )
then
485 commid = peset(i)%comm%mpi_val
511 integer,
intent(in),
optional :: pelist(:)
512 logical,
intent(in),
optional :: no_sync
514 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: You must first call mpp_init.' )
515 if(
PRESENT(pelist) )
then
516 if( .NOT.any(pe.EQ.pelist) )
call mpp_error( fatal,
'MPP_SET_CURRENT_PELIST: pe must be in pelist.' )
517 current_peset_num = get_peset(pelist)
519 current_peset_num = world_peset_num
521 call mpp_set_root_pe( minval(peset(current_peset_num)%list(:)) )
522 if(.not.
PRESENT(no_sync))
call mpp_sync()
528 function mpp_get_current_pelist_name()
530 character(len=len(peset(current_peset_num)%name)) :: mpp_get_current_pelist_name
532 mpp_get_current_pelist_name = peset(current_peset_num)%name
533 end function mpp_get_current_pelist_name
537 subroutine mpp_get_current_pelist( pelist, name, commID )
538 integer,
intent(out) :: pelist(:)
539 character(len=*),
intent(out),
optional :: name
540 integer,
intent(out),
optional :: commID
542 if(
size(pelist(:)).NE.
size(peset(current_peset_num)%list(:)) ) &
543 call mpp_error( fatal,
'MPP_GET_CURRENT_PELIST: size(pelist) is wrong.' )
544 pelist(:) = peset(current_peset_num)%list(:)
545 if(
PRESENT(name) ) name = peset(current_peset_num)%name
546 if(
PRESENT(commid) )
then
547 commid = peset(current_peset_num)%comm%mpi_val
549 end subroutine mpp_get_current_pelist
652 integer,
intent(in) :: grain
657 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_SET_GRAIN: You must first call mpp_init.' )
664 subroutine clock_init( id, name, flags, grain )
665 integer,
intent(in) :: id
666 character(len=*),
intent(in) :: name
667 integer,
intent(in),
optional :: flags, grain
670 clocks(id)%name = name
673 clocks(id)%total_ticks = 0
674 clocks(id)%sync_on_begin = .false.
675 clocks(id)%detailed = .false.
676 clocks(id)%peset_num = current_peset_num
677 if(
PRESENT(flags) )
then
678 if( btest(flags,0) )clocks(id)%sync_on_begin = .true.
679 if( btest(flags,1) )clocks(id)%detailed = .true.
682 if(
PRESENT(grain) )clocks(id)%grain = grain
683 if( clocks(id)%detailed )
then
684 allocate( clocks(id)%events(max_event_types) )
685 clocks(id)%events(event_allreduce)%name =
'ALLREDUCE'
686 clocks(id)%events(event_broadcast)%name =
'BROADCAST'
687 clocks(id)%events(event_recv)%name =
'RECV'
688 clocks(id)%events(event_send)%name =
'SEND'
689 clocks(id)%events(event_wait)%name =
'WAIT'
690 do i=1,max_event_types
691 clocks(id)%events(i)%ticks(:) = 0
692 clocks(id)%events(i)%bytes(:) = 0
693 clocks(id)%events(i)%calls = 0
695 clock_summary(id)%name = name
696 clock_summary(id)%event(event_allreduce)%name =
'ALLREDUCE'
697 clock_summary(id)%event(event_broadcast)%name =
'BROADCAST'
698 clock_summary(id)%event(event_recv)%name =
'RECV'
699 clock_summary(id)%event(event_send)%name =
'SEND'
700 clock_summary(id)%event(event_wait)%name =
'WAIT'
701 do i=1,max_event_types
702 clock_summary(id)%event(i)%msg_size_sums(:) = 0.0
703 clock_summary(id)%event(i)%msg_time_sums(:) = 0.0
704 clock_summary(id)%event(i)%total_data = 0.0
705 clock_summary(id)%event(i)%total_time = 0.0
706 clock_summary(id)%event(i)%msg_size_cnts(:) = 0
707 clock_summary(id)%event(i)%total_cnts = 0
711 end subroutine clock_init
717 character(len=*),
intent(in) :: name
718 integer,
intent(in),
optional :: flags, grain
720 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_ID: You must first call mpp_init.')
726 if(
PRESENT(grain) )
then
727 if( grain.GT.clock_grain )
then
734 if( clock_num.EQ.0 )
then
738 find_clock:
do while( trim(name).NE.trim(clocks(
mpp_clock_id)%name) )
742 call mpp_error( fatal,
'MPP_CLOCK_ID: too many clock requests, ' // &
743 'check your clock id request or increase MAX_CLOCKS.')
756 subroutine mpp_clock_begin(id)
757 integer,
intent(in) :: id
759 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: You must first call mpp_init.' )
760 if( .not. mpp_record_timing_data)
return
762 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
765 if( clocks(id)%peset_num.NE.current_peset_num ) &
766 call mpp_error( fatal,
'MPP_CLOCK_BEGIN: cannot change pelist context of a clock.' )
767 if( clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: mpp_clock_begin is called again '// &
768 'before calling mpp_clock_end for the clock '//trim(clocks(id)%name) )
769 if( clocks(id)%sync_on_begin .OR. sync_all_clocks )
then
777 num_clock_ids = num_clock_ids+1
778 if(num_clock_ids > max_clocks)
call mpp_error(fatal,
'MPP_CLOCK_BEGIN: max num previous_clock exceeded.' )
779 previous_clock(num_clock_ids) = current_clock
782 call system_clock( clocks(id)%tick )
783 clocks(id)%hits = clocks(id)%hits + 1
784 clocks(id)%is_on = .true.
787 end subroutine mpp_clock_begin
790 subroutine mpp_clock_end(id)
791 integer,
intent(in) :: id
792 integer(i8_kind) :: delta
795 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOCK_END: You must first call mpp_init.' )
796 if( .not. mpp_record_timing_data)
return
798 if( id.LT.0 .OR. id.GT.clock_num )
call mpp_error( fatal,
'MPP_CLOCK_BEGIN: invalid id.' )
800 if( .NOT. clocks(id)%is_on)
call mpp_error(fatal,
'MPP_CLOCK_END: mpp_clock_end is called '// &
801 'before calling mpp_clock_begin for the clock '//trim(clocks(id)%name) )
803 call system_clock(end_tick)
804 if( clocks(id)%peset_num.NE.current_peset_num ) &
805 call mpp_error( fatal,
'MPP_CLOCK_END: cannot change pelist context of a clock.' )
806 delta = end_tick - clocks(id)%tick
809 write( errunit,* )
'pe, id, start_tick, end_tick, delta, max_ticks=', pe, id, clocks(id)%tick, end_tick, &
811 delta = delta + max_ticks + 1
812 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
814 clocks(id)%total_ticks = clocks(id)%total_ticks + delta
816 if(num_clock_ids < 1)
call mpp_error(note,
'MPP_CLOCK_END: min num previous_clock < 1.' )
817 current_clock = previous_clock(num_clock_ids)
818 num_clock_ids = num_clock_ids-1
820 clocks(id)%is_on = .false.
823 end subroutine mpp_clock_end
826 subroutine mpp_record_time_start()
828 mpp_record_timing_data = .true.
830 end subroutine mpp_record_time_start
833 subroutine mpp_record_time_end()
835 mpp_record_timing_data = .false.
837 end subroutine mpp_record_time_end
841 subroutine increment_current_clock( event_id, bytes )
842 integer,
intent(in) :: event_id
843 integer,
intent(in),
optional :: bytes
845 integer(i8_kind) :: delta
848 if( .not. mpp_record_timing_data )
return
849 if( .not.debug .or. (current_clock.EQ.0) )
return
850 if( current_clock.LT.0 .OR. current_clock.GT.clock_num )
call mpp_error( fatal, &
851 &
'MPP_CLOCK_BEGIN: invalid current_clock.' )
852 if( .NOT.clocks(current_clock)%detailed )
return
853 call system_clock(end_tick)
854 n = clocks(current_clock)%events(event_id)%calls + 1
856 if( n.EQ.max_events )
call mpp_error( warning, &
857 'MPP_CLOCK: events exceed MAX_EVENTS, ignore detailed profiling data for clock '// &
858 & trim(clocks(current_clock)%name) )
859 if( n.GT.max_events )
return
861 clocks(current_clock)%events(event_id)%calls = n
862 delta = end_tick - start_tick
865 write( errunit,* )
'pe, event_id, start_tick, end_tick, delta, max_ticks=', &
866 pe, event_id, start_tick, end_tick, delta, max_ticks
867 delta = delta + max_ticks + 1
868 call mpp_error( warning,
'MPP_CLOCK_END: Clock rollover, assumed single roll.' )
870 clocks(current_clock)%events(event_id)%ticks(n) = delta
871 if(
PRESENT(bytes) )clocks(current_clock)%events(event_id)%bytes(n) = bytes
873 end subroutine increment_current_clock
877 subroutine dump_clock_summary()
879 real :: total_time,total_time_all,total_data
880 real :: msg_size,eff_bw,s
881 integer :: sd_unit, total_calls
882 integer :: j,k,ct, msg_cnt
883 character(len=2) :: u
884 character(len=FMS_FILE_LEN) :: filename
885 character(len=20),
dimension(MAX_BINS),
save :: bin
887 data bin( 1) /
' 0 - 8 B: '/
888 data bin( 2) /
' 8 - 16 B: '/
889 data bin( 3) /
' 16 - 32 B: '/
890 data bin( 4) /
' 32 - 64 B: '/
891 data bin( 5) /
' 64 - 128 B: '/
892 data bin( 6) /
'128 - 256 B: '/
893 data bin( 7) /
'256 - 512 B: '/
894 data bin( 8) /
'512 - 1024 B: '/
895 data bin( 9) /
' 1.0 - 2.1 KB: '/
896 data bin(10) /
' 2.1 - 4.1 KB: '/
897 data bin(11) /
' 4.1 - 8.2 KB: '/
898 data bin(12) /
' 8.2 - 16.4 KB: '/
899 data bin(13) /
' 16.4 - 32.8 KB: '/
900 data bin(14) /
' 32.8 - 65.5 KB: '/
901 data bin(15) /
' 65.5 - 131.1 KB: '/
902 data bin(16) /
'131.1 - 262.1 KB: '/
903 data bin(17) /
'262.1 - 524.3 KB: '/
904 data bin(18) /
'524.3 - 1048.6 KB: '/
905 data bin(19) /
' 1.0 - 2.1 MB: '/
906 data bin(20) /
' >2.1 MB: '/
908 if( .NOT.any(clocks(1:clock_num)%detailed) )
return
909 write( filename,
'(a,i6.6)' )
'mpp_clock.out.', pe
911 open(newunit=sd_unit,file=trim(filename),form=
'formatted')
913 comm_type:
do ct = 1,clock_num
915 if( .NOT.clocks(ct)%detailed )cycle
917 clock_summary(ct)%name(1:15),
' Communication Data for PE ',pe
923 event_type:
do k = 1,max_event_types-1
925 if(clock_summary(ct)%event(k)%total_time == 0.0)cycle
927 total_time = clock_summary(ct)%event(k)%total_time
928 total_time_all = total_time_all + total_time
929 total_data = clock_summary(ct)%event(k)%total_data
930 total_calls = int(clock_summary(ct)%event(k)%total_cnts)
932 write(sd_unit,1000) clock_summary(ct)%event(k)%name(1:9) //
':'
934 write(sd_unit,1001)
'Total Data: ',total_data*1.0e-6, &
935 'MB; Total Time: ', total_time, &
936 'secs; Total Calls: ',total_calls
939 write(sd_unit,1002)
' Bin Counts Avg Size Eff B/W'
942 bin_loop:
do j=1,max_bins
944 if(clock_summary(ct)%event(k)%msg_size_cnts(j)==0)cycle
957 msg_cnt = int(clock_summary(ct)%event(k)%msg_size_cnts(j))
959 s*(clock_summary(ct)%event(k)%msg_size_sums(j)/real(msg_cnt))
960 eff_bw = (1.0e-6)*( clock_summary(ct)%event(k)%msg_size_sums(j) / &
961 clock_summary(ct)%event(k)%msg_time_sums(j) )
963 write(sd_unit,1003) bin(j),msg_cnt,msg_size,u,eff_bw
973 if(clock_summary(ct)%event(max_event_types)%total_time>0.0)
then
975 total_time = clock_summary(ct)%event(max_event_types)%total_time
976 total_time_all = total_time_all + total_time
977 total_calls = int(clock_summary(ct)%event(max_event_types)%total_cnts)
979 write(sd_unit,1000) clock_summary(ct)%event(max_event_types)%name(1:9) //
':'
981 write(sd_unit,1004)
'Total Calls: ',total_calls,
'; Total Time: ', &
987 write(sd_unit,1005)
'Total communication time spent for ' // &
988 clock_summary(ct)%name(1:9) //
': ',total_time_all,
'secs'
998 1001
format(a,f8.2,a,f8.2,a,i6)
1000 1003
format(a,i6,
' ',
' ',f9.1,a,
' ',f9.2,
'MB/sec')
1001 1004
format(a,i8,a,f9.2,a)
1002 1005
format(a,f9.2,a)
1004 end subroutine dump_clock_summary
1008 integer function get_unit()
1013 if (pe == root_pe)
call mpp_error(warning, &
1014 'get_unit is deprecated and will be removed in a future release, please use the Fortran intrinsic newunit')
1016 inquire(unit=i,opened=l_open)
1021 call mpp_error(fatal,
'Unable to get I/O unit')
1027 end function get_unit
1031 subroutine sum_clock_data()
1033 integer :: i,j,k,ct,event_size,event_cnt
1036 clock_type:
do ct=1,clock_num
1037 if( .NOT.clocks(ct)%detailed )cycle
1038 event_type:
do j=1,max_event_types-1
1039 event_cnt = clocks(ct)%events(j)%calls
1040 event_summary:
do i=1,event_cnt
1042 clock_summary(ct)%event(j)%total_cnts = &
1043 clock_summary(ct)%event(j)%total_cnts + 1
1045 event_size = int(clocks(ct)%events(j)%bytes(i))
1047 k = find_bin(event_size)
1049 clock_summary(ct)%event(j)%msg_size_cnts(k) = &
1050 clock_summary(ct)%event(j)%msg_size_cnts(k) + 1
1052 clock_summary(ct)%event(j)%msg_size_sums(k) = &
1053 clock_summary(ct)%event(j)%msg_size_sums(k) &
1054 + clocks(ct)%events(j)%bytes(i)
1056 clock_summary(ct)%event(j)%total_data = &
1057 clock_summary(ct)%event(j)%total_data &
1058 + clocks(ct)%events(j)%bytes(i)
1060 msg_time = clocks(ct)%events(j)%ticks(i)
1061 msg_time = tick_rate * real( clocks(ct)%events(j)%ticks(i) )
1063 clock_summary(ct)%event(j)%msg_time_sums(k) = &
1064 clock_summary(ct)%event(j)%msg_time_sums(k) + msg_time
1066 clock_summary(ct)%event(j)%total_time = &
1067 clock_summary(ct)%event(j)%total_time + msg_time
1069 end do event_summary
1076 event_cnt = clocks(ct)%events(j)%calls
1077 clock_summary(ct)%event(j)%msg_size_cnts(1) = event_cnt
1078 clock_summary(ct)%event(j)%total_cnts = event_cnt
1080 msg_time = tick_rate * real( sum( clocks(ct)%events(j)%ticks(1:event_cnt) ) )
1081 clock_summary(ct)%event(j)%msg_time_sums(1) = &
1082 clock_summary(ct)%event(j)%msg_time_sums(1) + msg_time
1084 clock_summary(ct)%event(j)%total_time = clock_summary(ct)%event(j)%msg_time_sums(1)
1090 integer function find_bin(event_size)
1092 integer,
intent(in) :: event_size
1093 integer :: k,msg_size
1097 do while(event_size>msg_size .and. k<max_bins)
1099 msg_size = msg_size*2
1103 end function find_bin
1105 end subroutine sum_clock_data
1111 integer :: old_peset_max,n
1112 type(communicator),
allocatable :: peset_old(:)
1114 old_peset_max = current_peset_max
1115 if(old_peset_max .GE. peset_max)
call mpp_error(fatal, &
1116 "mpp_mod(expand_peset): the number of peset reached PESET_MAX, increase PESET_MAX or contact developer")
1119 allocate(peset_old(0:old_peset_max))
1120 do n = 0, old_peset_max
1121 peset_old(n)%count = peset(n)%count
1122 peset_old(n)%comm = peset(n)%comm
1123 peset_old(n)%group = peset(n)%group
1124 peset_old(n)%name = peset(n)%name
1125 peset_old(n)%start = peset(n)%start
1126 peset_old(n)%log2stride = peset(n)%log2stride
1128 if(
ASSOCIATED(peset(n)%list) )
then
1129 allocate(peset_old(n)%list(
size(peset(n)%list(:))) )
1130 peset_old(n)%list(:) = peset(n)%list(:)
1131 deallocate(peset(n)%list)
1137 current_peset_max = min(peset_max, 2*old_peset_max)
1138 allocate(peset(0:current_peset_max))
1140 peset(:)%comm = mpi_comm_null
1141 peset(:)%group = mpi_group_null
1143 peset(:)%log2stride = -1
1145 do n = 0, old_peset_max
1146 peset(n)%count = peset_old(n)%count
1147 peset(n)%comm = peset_old(n)%comm
1148 peset(n)%group = peset_old(n)%group
1149 peset(n)%name = peset_old(n)%name
1150 peset(n)%start = peset_old(n)%start
1151 peset(n)%log2stride = peset_old(n)%log2stride
1153 if(
ASSOCIATED(peset_old(n)%list) )
then
1154 allocate(peset(n)%list(
size(peset_old(n)%list(:))) )
1155 peset(n)%list(:) = peset_old(n)%list(:)
1156 deallocate(peset_old(n)%list)
1159 deallocate(peset_old)
1161 call mpp_error(note,
"mpp_mod(expand_peset): size of peset is expanded to ", current_peset_max)
1166 function uppercase (cs)
1167 character(len=*),
intent(in) :: cs
1168 character(len=len(cs)),
target :: uppercase
1170 character,
pointer :: ca
1171 integer,
parameter :: co=iachar(
'A')-iachar(
'a')
1177 uppercase = cs(1:tlen)
1179 ca => uppercase(k:k)
1180 if(ca >=
"a" .and. ca <=
"z") ca = achar(ichar(ca)+co)
1183 end function uppercase
1187 function lowercase (cs)
1188 character(len=*),
intent(in) :: cs
1189 character(len=len(cs)),
target :: lowercase
1190 integer,
parameter :: co=iachar(
'a')-iachar(
'A')
1192 character,
pointer :: ca
1198 lowercase = cs(1:tlen)
1200 ca => lowercase(k:k)
1201 if(ca >=
"A" .and. ca <=
"Z") ca = achar(ichar(ca)+co)
1204 end function lowercase
1232 #include<file_version.h>
1234 character(len=*),
intent(in),
optional :: pelist_name_in
1235 character(len=*),
intent(in),
optional :: alt_input_nml_path
1239 integer,
dimension(2) :: lines_and_length
1240 logical :: file_exist
1241 character(len=len(peset(current_peset_num)%name)) :: pelist_name
1242 character(len=FMS_PATH_LEN) :: filename
1245 if (
allocated(input_nml_file) )
then
1246 deallocate(input_nml_file)
1250 if (
PRESENT(pelist_name_in))
then
1252 if (len(pelist_name_in) > len(pelist_name))
then
1253 call mpp_error(fatal, &
1254 "mpp_util.inc: read_input_nml optional argument pelist_name_in has size greater than local pelist_name")
1256 pelist_name = pelist_name_in
1259 pelist_name = mpp_get_current_pelist_name()
1261 filename=
'input_'//trim(pelist_name)//
'.nml'
1262 inquire(file=filename, exist=file_exist)
1263 if (.not. file_exist )
then
1264 if (
present(alt_input_nml_path))
then
1265 filename = alt_input_nml_path
1267 filename =
'input.nml'
1271 allocate(
character(len=lines_and_length(2))::input_nml_file(lines_and_length(1)))
1275 if (pe == root_pe)
then
1277 write(log_unit,
'(a)')
'========================================================================'
1278 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(version)
1279 write(log_unit,
'(a)')
'READ_INPUT_NML: '//trim(filename)//
' '
1280 do i = 1, lines_and_length(1)
1281 write(log_unit,*) trim(input_nml_file(i))
1289 function get_ascii_file_num_lines(FILENAME, LENGTH, PELIST)
1290 character(len=*),
intent(in) :: FILENAME
1291 integer,
intent(in) :: LENGTH
1292 integer,
intent(in),
optional,
dimension(:) :: PELIST
1294 integer :: num_lines, get_ascii_file_num_lines
1295 character(len=LENGTH) :: str_tmp
1296 character(len=5) :: text
1297 integer :: status, f_unit, from_pe
1298 logical :: file_exist
1300 if( read_ascii_file_on)
then
1301 call mpp_error(fatal, &
1302 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1304 read_ascii_file_on = .true.
1307 get_ascii_file_num_lines = -1
1309 if ( pe == root_pe )
then
1310 inquire(file=filename, exist=file_exist)
1312 if ( file_exist )
then
1313 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1315 if ( status .ne. 0 )
then
1316 write (unit=text, fmt=
'(I5)') status
1317 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1318 '. (IOSTAT = '//trim(text)//
')')
1322 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1323 if ( status .lt. 0 )
then
1325 num_lines = max(num_lines - 1, 1)
1328 if ( status .gt. 0 )
then
1329 write (unit=text, fmt=
'(I5)') num_lines
1330 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1331 ' in file '//trim(filename)//
'.')
1333 if ( len_trim(str_tmp) == length )
then
1334 write(unit=text, fmt=
'(I5)') length
1335 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1336 &
' is too small. Increase the LENGTH value.')
1338 num_lines = num_lines + 1
1343 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1348 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1349 get_ascii_file_num_lines = num_lines
1351 end function get_ascii_file_num_lines
1356 character(len=*),
intent(in) :: filename
1357 integer,
intent(in),
optional,
dimension(:) :: pelist
1361 integer :: num_lines, max_length
1362 integer,
parameter :: length=1024
1363 character(len=LENGTH) :: str_tmp
1364 character(len=5) :: text
1365 integer :: status, f_unit, from_pe
1366 logical :: file_exist
1368 if( read_ascii_file_on)
then
1369 call mpp_error(fatal, &
1370 "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file")
1372 read_ascii_file_on = .true.
1378 if ( pe == root_pe )
then
1379 inquire(file=filename, exist=file_exist)
1381 if ( file_exist )
then
1382 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1384 if ( status .ne. 0 )
then
1385 write (unit=text, fmt=
'(I5)') status
1386 call mpp_error(fatal,
'get_ascii_file_num_lines: Error opening file:' //trim(filename)// &
1387 '. (IOSTAT = '//trim(text)//
')')
1392 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1393 if ( status .lt. 0 )
then
1395 num_lines = max(num_lines - 1, 1)
1398 if ( status .gt. 0 )
then
1399 write (unit=text, fmt=
'(I5)') num_lines
1400 call mpp_error(fatal,
'get_ascii_file_num_lines: Error reading line '//trim(text)// &
1401 ' in file '//trim(filename)//
'.')
1403 if ( len_trim(str_tmp) == length)
then
1404 write(unit=text, fmt=
'(I5)') length
1405 call mpp_error(fatal,
'get_ascii_file_num_lines: Length of output string ('//trim(text)//&
1406 &
' is too small. Increase the LENGTH value.')
1408 if (len_trim(str_tmp) > max_length) max_length = len_trim(str_tmp)
1409 num_lines = num_lines + 1
1414 call mpp_error(fatal,
'get_ascii_file_num_lines: File '//trim(filename)//
' does not exist.')
1416 max_length = max_length+1
1420 call mpp_broadcast(num_lines, from_pe, pelist=pelist)
1421 call mpp_broadcast(max_length, from_pe, pelist=pelist)
1449 character(len=*),
intent(in) :: FILENAME
1450 integer,
intent(in) :: LENGTH
1451 character(len=*),
intent(inout),
dimension(:) :: Content
1452 integer,
intent(in),
optional,
dimension(:) :: PELIST
1455 #include<file_version.h>
1457 character(len=5) :: text
1458 logical :: file_exist
1459 integer :: status, f_unit, log_unit
1461 integer :: pnum_lines, num_lines
1462 character(len=LENGTH) :: str_tmp
1464 if( .NOT. read_ascii_file_on)
then
1465 call mpp_error(fatal, &
1466 "mpp_util.inc: get_ascii_file_num_lines needs to be called before calling read_ascii_file")
1468 read_ascii_file_on = .false.
1471 num_lines =
size(content(:))
1473 if ( pe == root_pe )
then
1476 write(log_unit,
'(a)')
'========================================================================'
1477 write(log_unit,
'(a)')
'READ_ASCII_FILE: '//trim(version)
1478 write(log_unit,
'(a)')
'READ_ASCII_FILE: File: '//trim(filename)
1480 inquire(file=filename, exist=file_exist)
1482 if ( file_exist )
then
1483 open(newunit=f_unit, file=filename, action=
'READ', status=
'OLD', iostat=status)
1485 if ( status .ne. 0 )
then
1486 write (unit=text, fmt=
'(I5)') status
1487 call mpp_error(fatal,
'READ_ASCII_FILE: Error opening file: '// &
1488 & trim(filename)//
'. (IOSTAT = '//trim(text)//
')')
1491 if ( num_lines .gt. 0 )
then
1494 rewind(unit=f_unit, iostat=status)
1495 if ( status .ne. 0 )
then
1496 write (unit=text, fmt=
'(I5)') status
1497 call mpp_error(fatal,
'READ_ASCII_FILE: Unable to re-read file '//trim(filename)//
'. (IOSTAT = '&
1504 read (unit=f_unit, fmt=
'(A)', iostat=status) str_tmp
1506 if ( status .lt. 0 )
then
1508 pnum_lines = max(pnum_lines - 1, 1)
1511 if ( status .gt. 0 )
then
1512 write (unit=text, fmt=
'(I5)') pnum_lines
1513 call mpp_error(fatal,
'READ_ASCII_FILE: Error reading line '// &
1514 & trim(text)//
' in file '//trim(filename)//
'.')
1516 if(pnum_lines > num_lines)
then
1517 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1518 ' is greater than size(Content(:)). ')
1520 if ( len_trim(str_tmp) == length )
then
1521 write(unit=text, fmt=
'(I5)') length
1522 call mpp_error(fatal,
'READ_ASCII_FILE: Length of output string ('//trim(text)// &
1523 &
' is too small. Increase the LENGTH value.')
1525 content(pnum_lines) = str_tmp
1526 pnum_lines = pnum_lines + 1
1528 if(num_lines .NE. pnum_lines)
then
1529 call mpp_error(fatal,
'READ_ASCII_FILE: number of lines in file '//trim(filename)// &
1530 ' does not equal to size(Content(:)) ' )
1537 call mpp_error(fatal,
'READ_ASCII_FILE: File '//trim(filename)//
' does not exist.')
1542 call mpp_broadcast(content, length, from_pe, pelist=pelist)
1554 integer,
intent(in) :: x(:)
1555 integer,
intent(out) :: y(size(x))
1562 if (x(i).ge.1 .and. x(i).le.n)
then
1566 character(2) :: nstr
1568 write (nstr,
"(I0)") n
1569 call mpp_error(fatal,
"inverse_permutation: Invalid dimension map. &
1570 Values must be in the range from 1 to " // trim(nstr) //
".")
1575 if (any(y.eq.0))
then
1576 call mpp_error(fatal,
"inverse_permutation: Invalid dim_order. Values must be non-repeating.")
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 inverse_permutation(x, y)
Produce an inverse permutation. For example, transform [2, 3, 1, 4] to [3, 1, 2, 4].
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....