FV3 Bundle
Timing_Utility.f90
Go to the documentation of this file.
1 ! Utility to define a timing structure and
2 ! timing utility routines.
3 !
5 
6  ! Module usage
7  USE type_kinds , ONLY: fp
9  USE file_utility , ONLY: get_lun, file_exists
10  USE datetime_utility, ONLY: datetime_type , &
11  datetime_now , &
13  ! Disable all implicit typing
14  IMPLICIT NONE
15 
16 
17  ! Visibilities
18  PRIVATE
19  ! ...Datatypes
20  PUBLIC :: timing_type
21  ! ...Procedures
22  PUBLIC :: timing_begin
23  PUBLIC :: timing_end
24  PUBLIC :: timing_display
25  PUBLIC :: timing_inspect
26  PUBLIC :: timing_set
27  PUBLIC :: timing_get
28  PUBLIC :: timing_writefile
29  ! ...Old named procedures
30  PUBLIC :: begin_timing
31  PUBLIC :: end_timing
32  PUBLIC :: display_timing
33 
34 
35  ! Parameters
36  CHARACTER(*), PARAMETER :: module_version_id = &
37  '$Id: Timing_Utility.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
38  INTEGER, PARAMETER :: ml = 256
39 
40 
41  ! Overloads
42  INTERFACE begin_timing
43  MODULE PROCEDURE timing_begin
44  END INTERFACE begin_timing
45 
46  INTERFACE end_timing
47  MODULE PROCEDURE timing_end
48  END INTERFACE end_timing
49 
50  INTERFACE display_timing
51  MODULE PROCEDURE timing_display
52  END INTERFACE display_timing
53 
54 
55  ! Derived type definitions
56  !:tdoc+:
57  TYPE :: timing_type
58  PRIVATE
59  LOGICAL :: is_valid = .false.
60  INTEGER :: hertz = 0
61  INTEGER :: begin_clock = 0
62  INTEGER :: end_clock = 0
63  END TYPE timing_type
64  !:tdoc-:
65 
66 
67 CONTAINS
68 
69 
70 !################################################################################
71 !################################################################################
72 !## ##
73 !## ## PUBLIC MODULE ROUTINES ## ##
74 !## ##
75 !################################################################################
76 !################################################################################
77 
78 !--------------------------------------------------------------------------------
79 !:sdoc+:
80 !
81 ! NAME:
82 ! Timing_Begin
83 !
84 ! PURPOSE:
85 ! Subroutine to set the begin time count in a timing object
86 !
87 ! CALLING SEQUENCE:
88 ! CALL Timing_Begin( timing )
89 !
90 ! INPUTS:
91 ! timing: Timing object.
92 ! UNITS: N/A
93 ! TYPE: Timing_type
94 ! DIMENSION: Scalar
95 ! ATTRIBUTES: INTENT(OUT)
96 !
97 !:sdoc-:
98 !--------------------------------------------------------------------------------
99 
100  SUBROUTINE timing_begin( self ) ! In/Output
101  TYPE(timing_type), INTENT(OUT) :: self
102  CALL system_clock( count_rate=self%Hertz, &
103  count =self%Begin_Clock )
104  IF ( self%Hertz == 0 ) RETURN
105  self%Is_Valid = .true.
106  END SUBROUTINE timing_begin
107 
108 
109 !--------------------------------------------------------------------------------
110 !:sdoc+:
111 !
112 ! NAME:
113 ! Timing_End
114 !
115 ! PURPOSE:
116 ! Subroutine to set the end time count in a timing object
117 !
118 ! CALLING SEQUENCE:
119 ! CALL Timing_End( timing )
120 !
121 ! INPUTS:
122 ! timing: Timing object.
123 ! UNITS: N/A
124 ! TYPE: Timing_type
125 ! DIMENSION: Scalar
126 ! ATTRIBUTES: INTENT(IN OUT)
127 !
128 !:sdoc-:
129 !--------------------------------------------------------------------------------
130 
131  SUBROUTINE timing_end( self ) ! In/Output
132  TYPE(timing_type), INTENT(IN OUT) :: self
133  CALL system_clock( count=self%End_Clock )
134  END SUBROUTINE timing_end
135 
136 
137 !--------------------------------------------------------------------------------
138 !:sdoc+:
139 !
140 ! NAME:
141 ! Timing_Display
142 !
143 ! PURPOSE:
144 ! Subroutine to display the elapsed time defined by the begin and end time
145 ! counts in the timing object.
146 !
147 ! CALLING SEQUENCE:
148 ! CALL Timing_Display( timing, Caller = caller )
149 !
150 ! INPUTS:
151 ! timing: Timing object.
152 ! UNITS: N/A
153 ! TYPE: Timing_type
154 ! DIMENSION: Scalar
155 ! ATTRIBUTES: INTENT(IN)
156 !
157 ! OPTIONAL INPUTS:
158 ! caller: String containing the name of the calling routine.
159 ! If not specified, the name of this procedure is used.
160 ! UNITS: N/A
161 ! TYPE: CHARACTER(*)
162 ! DIMENSION: Scalar
163 ! ATTRIBUTES: INTENT(IN)
164 !
165 !:sdoc-:
166 !--------------------------------------------------------------------------------
167 
168  SUBROUTINE timing_display( &
169  self , & ! Input
170  Caller ) ! Optional input
171  ! Arguments
172  TYPE(timing_type), INTENT(IN) :: self
173  CHARACTER(*), OPTIONAL, INTENT(IN) :: caller
174  ! Local variables
175  CHARACTER(ML) :: msg
176  CHARACTER(ML) :: routine_name
177 
178  ! Set up
179  routine_name = 'Timing_Display'
180  IF ( PRESENT(caller) ) routine_name = trim(adjustl(caller))
181  ! ...Check if timing structure valid for display
182  IF ( .NOT. self%Is_Valid ) THEN
183  msg = 'Invalid timing structure!'
184  CALL display_message( routine_name, msg, failure ); RETURN
185  END IF
186 
187  ! Construct the character string
188  WRITE( msg, '("Elapsed time-- ",a)' ) trim(timing_tostring(self))
189  CALL display_message( routine_name, msg, information )
190 
191  END SUBROUTINE timing_display
192 
193 
194 !--------------------------------------------------------------------------------
195 !:sdoc+:
196 !
197 ! NAME:
198 ! Timing_Inspect
199 !
200 ! PURPOSE:
201 ! Subroutine to print the contents of a Timing object to stdout.
202 !
203 ! CALLING SEQUENCE:
204 ! CALL Timing_Inspect( timing )
205 !
206 ! OBJECTS:
207 ! Timing: Timing object to display.
208 ! UNITS: N/A
209 ! TYPE: Timing_type
210 ! DIMENSION: Scalar
211 ! ATTRIBUTES: INTENT(IN)
212 !
213 !:sdoc-:
214 !--------------------------------------------------------------------------------
215 
216  SUBROUTINE timing_inspect( self )
217  TYPE(timing_type), INTENT(IN) :: self
218  WRITE(*,'(1x,"Timing OBJECT")')
219  WRITE(*,'(3x,"Hertz : ",i0)') self%Hertz
220  WRITE(*,'(3x,"Begin_Clock : ",i0)') self%Begin_Clock
221  WRITE(*,'(3x,"End_Clock : ",i0)') self%End_Clock
222  WRITE(*,'(3x,"Is_Valid : ",l1)') self%Is_Valid
223  END SUBROUTINE timing_inspect
224 
225 
226 !------------------------------------------------------------------------------
227 !:sdoc+:
228 !
229 ! NAME:
230 ! Timing_ToString
231 !
232 ! PURPOSE:
233 ! Elemental function to return the equivalent string representation
234 ! of the Timing object.
235 !
236 ! CALLING SEQUENCE:
237 ! string = Timing_ToString( Timing, Seconds=seconds, Fmt_String=fmt_string )
238 !
239 ! OBJECTS:
240 ! Timing: Timing structure containing the timed data.
241 ! UNITS: N/A
242 ! TYPE: Timing_type
243 ! DIMENSION: Scalar or any rank
244 ! ATTRIBUTES: INTENT(IN)
245 !
246 ! OPTIONAL INPUTS:
247 ! Seconds: Set this logical argument to create a string that is
248 ! simply the number of seconds of elpased time.
249 ! If == .FALSE., the output string format is HH:MM:SS.sss [DEFAULT].
250 ! == .TRUE., the output string format is XX.XXXXXXe+EE (es13.6).
251 ! If not specified, default is .FALSE.
252 ! UNITS: N/A
253 ! TYPE: LOGICAL
254 ! DIMENSION: Conformable with the Timing input
255 ! ATTRIBUTES: INTENT(IN), OPTIONAL
256 !
257 ! Fmt_String: Character string holding the format string to use for
258 ! seconds of elasped time output. If not supplied, the
259 ! default is '(es13.6)'.
260 ! This argument is ignored if the "Seconds" argument is
261 ! not specified, or not set.
262 ! UNITS: N/A
263 ! TYPE: CHARACTER(*)
264 ! DIMENSION: Conformable with the Timing input.
265 ! ATTRIBUTES: INTENT(IN), OPTIONAL
266 !
267 ! FUNCTION RESULT:
268 ! string: String containing the time elapsed in seconds.
269 ! UNITS: N/A
270 ! TYPE: CHARACTER(80)
271 ! DIMENSION: Conformable with input Timing argument.
272 !
273 !:sdoc-:
274 !------------------------------------------------------------------------------
275 
276  ELEMENTAL FUNCTION timing_tostring( &
277  self , & ! Input
278  Seconds , & ! Optional input
279  Fmt_String) & ! Optional input
280  result( string )
281  ! Arguments
282  TYPE(timing_type), INTENT(IN) :: self
283  LOGICAL , OPTIONAL, INTENT(IN) :: seconds
284  CHARACTER(*) , OPTIONAL, INTENT(IN) :: fmt_string
285  ! Function result
286  CHARACTER(80) :: string
287  ! Local parameters
288  REAL(fp), PARAMETER :: n_seconds_in_hour = 3600.0_fp
289  REAL(fp), PARAMETER :: n_seconds_in_minute = 60.0_fp
290  REAL(fp), PARAMETER :: n_milliseconds_in_second = 1000.0_fp
291  ! Local variables
292  CHARACTER(80) :: fmt
293  LOGICAL :: hhmmss
294  REAL(fp) :: total_time
295  INTEGER :: n_hours
296  INTEGER :: n_minutes
297  INTEGER :: n_seconds
298  INTEGER :: n_milliseconds
299 
300  ! Setup
301  ! ...Process keyword arguments
302  hhmmss = .true.
303  IF ( PRESENT(seconds) ) hhmmss = .NOT. seconds
304  fmt = '(es13.6)'
305  IF ( PRESENT(fmt_string) ) fmt = adjustl(fmt_string)
306 
307 
308  ! Compute the total time in seconds
309  total_time = timing_elapsedtime( self )
310 
311 
312  ! Create the string
313  IF ( hhmmss ) THEN
314  ! ...Split the total time into hours, minutes, seconds, and millseconds
315  n_hours = int(total_time / n_seconds_in_hour)
316  n_minutes = int(mod(total_time,n_seconds_in_hour) / n_seconds_in_minute)
317  n_seconds = int(mod(mod(total_time,n_seconds_in_hour), n_seconds_in_minute))
318  n_milliseconds = int((total_time - aint(total_time,fp)) * n_milliseconds_in_second)
319  ! ...Construct the HH:MM:SS.sss string
320  WRITE( string,'(i2.2,":",i2.2,":",i2.2,".",i3.3 )' ) &
321  n_hours, n_minutes, n_seconds, n_milliseconds
322  ELSE
323  ! ...Construct the number of seconds string
324  WRITE( string,fmt=fmt ) total_time
325  END IF
326 
327  END FUNCTION timing_tostring
328 
329 
330  ! Subroutine to set the components of a timing object
331  ! Public, but only for testing so it's undocumented.
332  SUBROUTINE timing_set( &
333  self , &
334  Hertz , &
335  Begin_Clock, &
336  End_Clock , &
337  Is_Valid )
338  ! Arguments
339  TYPE(timing_type), INTENT(IN OUT) :: self
340  INTEGER, OPTIONAL, INTENT(IN) :: hertz
341  INTEGER, OPTIONAL, INTENT(IN) :: begin_clock
342  INTEGER, OPTIONAL, INTENT(IN) :: end_clock
343  LOGICAL, OPTIONAL, INTENT(IN) :: is_valid
344  ! Set object components
345  IF ( PRESENT(hertz ) ) self%Hertz = hertz
346  IF ( PRESENT(begin_clock) ) self%Begin_Clock = begin_clock
347  IF ( PRESENT(end_clock ) ) self%End_Clock = end_clock
348  IF ( PRESENT(is_valid ) ) self%Is_Valid = is_valid
349  END SUBROUTINE timing_set
350 
351 
352  ! Subroutine to get the components of a timing object
353  ! Public, but only for testing so it's undocumented.
354  SUBROUTINE timing_get( &
355  self , &
356  Hertz , &
357  Begin_Clock, &
358  End_Clock , &
359  Is_Valid )
360  ! Arguments
361  TYPE(timing_type), INTENT(IN) :: self
362  INTEGER, OPTIONAL, INTENT(OUT) :: hertz
363  INTEGER, OPTIONAL, INTENT(OUT) :: begin_clock
364  INTEGER, OPTIONAL, INTENT(OUT) :: end_clock
365  LOGICAL, OPTIONAL, INTENT(OUT) :: is_valid
366  ! Set object components
367  IF ( PRESENT(hertz ) ) hertz = self%Hertz
368  IF ( PRESENT(begin_clock) ) begin_clock = self%Begin_Clock
369  IF ( PRESENT(end_clock ) ) end_clock = self%End_Clock
370  IF ( PRESENT(is_valid ) ) is_valid = self%Is_Valid
371  END SUBROUTINE timing_get
372 
373 !--------------------------------------------------------------------------------
374 !:sdoc+:
375 !
376 ! NAME:
377 ! Timing_WriteFile
378 !
379 ! PURPOSE:
380 ! Function to write timing object information to an ASCII file.
381 !
382 ! CALLING SEQUENCE:
383 ! Error_Status = Timing_WriteFile( &
384 ! Timing_Array, &
385 ! Filename , &
386 ! Clobber = clobber, &
387 ! Heading = heading )
388 !
389 ! OBJECTS:
390 ! Timing_Array: Array of Timing objects to write to file. All elements
391 ! must be valid.
392 ! UNITS: N/A
393 ! TYPE: Timing_type
394 ! DIMENSION: Rank-1
395 ! ATTRIBUTES: INTENT(IN)
396 !
397 ! INPUTS:
398 ! Filename: Name of the file to write.
399 ! - If file does not exist, it is created.
400 ! - If file does exist, it is opened for appending data.
401 ! UNITS: N/A
402 ! TYPE: Timing_type
403 ! DIMENSION: Rank-1
404 ! ATTRIBUTES: INTENT(IN)
405 !
406 ! OPTIONAL INPUTS:
407 ! Clobber: Set this logical argument to overwrite an existing filename.
408 ! If == .FALSE., an existing file is opened with OLD status and
409 ! positioned at end-of-file for appending data [DEFAULT].
410 ! == .TRUE., an existing file is opened with REPLACE status.
411 ! If not specified, default is .FALSE.
412 ! UNITS: N/A
413 ! TYPE: LOGICAL
414 ! DIMENSION: Scalar
415 ! ATTRIBUTES: INTENT(IN), OPTIONAL
416 !
417 ! Heading: Array of character strings to use as heading labels for each
418 ! timing object element.
419 ! - If not specified, default is "Time 1", "Time 2", etc..
420 ! - If specified, size must be same as Timing_Array.
421 ! UNITS: N/A
422 ! TYPE: CHARACTER
423 ! DIMENSION: Rank-1
424 ! ATTRIBUTES: INTENT(IN), OPTIONAL
425 !
426 ! FUNCTION RESULT:
427 ! Error_Status: The return value is an integer defining the error status.
428 ! The error codes are defined in the Message_Handler module.
429 ! If == SUCCESS the data write was successful
430 ! == FAILURE an unrecoverable error occurred.
431 ! UNITS: N/A
432 ! TYPE: INTEGER
433 ! DIMENSION: Scalar
434 !
435 !:sdoc-:
436 !--------------------------------------------------------------------------------
437 
438  FUNCTION timing_writefile( &
439  Timing_Array, &
440  Filename , &
441  Clobber , &
442  Heading ) &
443  result( err_stat )
444  ! Arguments
445  TYPE(timing_type), INTENT(IN) :: timing_array(:)
446  CHARACTER(*) , INTENT(IN) :: filename
447  LOGICAL , OPTIONAL, INTENT(IN) :: clobber
448  CHARACTER(*) , OPTIONAL, INTENT(IN) :: heading(:)
449  ! Function result
450  INTEGER :: err_stat
451  ! Local parameters
452  CHARACTER(*), PARAMETER :: routine_name = 'Timing_WriteFile'
453  ! Local variables
454  CHARACTER(ML) :: msg, io_msg
455  CHARACTER(ML) :: current_time
456  CHARACTER(ML) :: title(size(timing_array))
457  CHARACTER(ML) :: elapsed_time(size(timing_array))
458  CHARACTER(ML) :: output_fmt
459  CHARACTER(8) :: status, position
460  LOGICAL :: append
461  INTEGER :: fid
462  INTEGER :: io_stat
463  INTEGER :: i, n_times
464  INTEGER :: sl_current_time
465  INTEGER :: sl_elapsed_time
466 
467  ! Set up
468  err_stat = success
469  ! ...Check structures
470  IF ( .NOT. all(timing_array%Is_Valid) ) THEN
471  err_stat = failure
472  msg = 'Input timing array contains invalid elements'
473  CALL display_message(routine_name, msg, err_stat); RETURN
474  END IF
475  n_times = SIZE(timing_array)
476  ! ...Check clobber argument
477  append = .true.
478  IF ( PRESENT(clobber) ) append = .NOT. clobber
479  ! ...Check header argument
480  IF ( PRESENT(heading) ) THEN
481  IF ( SIZE(heading) /= n_times ) THEN
482  err_stat = failure
483  msg = 'Input heading array different size from timing array'
484  CALL display_message(routine_name, msg, err_stat); RETURN
485  END IF
486  DO i = 1, n_times
487  title(i) = '| '//trim(heading(i))
488  END DO
489  ELSE
490  DO i = 1, n_times
491  WRITE(title(i),'("| Time ",i0)') i
492  END DO
493  END IF
494 
495 
496  ! Open the file
497  ! ...Set specifiers for write
498  IF ( append ) THEN
499  status = 'OLD'
500  position = 'APPEND'
501  ELSE
502  status = 'REPLACE'
503  position = 'REWIND'
504  END IF
505  ! ...Special case for a file that doesn't exist yet
506  IF ( .NOT. file_exists(filename) ) status = 'NEW'
507  ! ...Get a free unit number
508  fid = get_lun()
509  IF ( fid < 0 ) THEN
510  err_stat = failure
511  msg = 'Error obtaining free logical unit number'
512  CALL display_message(routine_name, msg, err_stat); RETURN
513  END IF
514  ! ...Open the file for output
515  OPEN( fid, file = filename , &
516  form = 'FORMATTED', &
517  status = status , &
518  position = position , &
519  iostat = io_stat , &
520  iomsg = io_msg )
521  IF ( io_stat /= 0 ) THEN
522  err_stat = failure
523  msg = 'Error opening file '//trim(filename)//' - '//trim(io_msg)
524  CALL display_message(routine_name, msg, err_stat); RETURN
525  END IF
526 
527 
528  ! Get the current date/time string, and its length, for output
529  current_time = datetime_tostring(datetime_now(),format='s')
530  sl_current_time = len_trim(current_time)
531 
532 
533  ! Transform the timing info to strings, and get their length
534  elapsed_time = timing_tostring(timing_array,seconds=.true.)
535  sl_elapsed_time = max(maxval(len_trim(elapsed_time)), maxval(len_trim(title)))
536 
537 
538  ! Construct the output write format
539  WRITE(output_fmt,'("(a",i0,",",i0,"(2x,a",i0,"))")') &
540  sl_current_time, n_times, sl_elapsed_time
541 
542 
543  ! Write the header line if necessary
544  IF ( trim(status) == 'NEW' ) THEN
545  WRITE(fid,fmt = output_fmt, iostat = io_stat, iomsg = io_msg) &
546  'Current time', (trim(title(i)), i = 1, n_times)
547  IF ( io_stat /= 0 ) THEN
548  err_stat = failure
549  msg = 'Error writing header to '//trim(filename)//' - '//trim(io_msg)
550  CALL display_message(routine_name, msg, err_stat); RETURN
551  END IF
552  END IF
553 
554 
555  ! Write the current set of times to file
556  WRITE(fid,fmt = output_fmt, iostat = io_stat, iomsg = io_msg) &
557  trim(current_time), &
558  (trim(elapsed_time(i)), i = 1, n_times)
559  IF ( io_stat /= 0 ) THEN
560  err_stat = failure
561  msg = 'Error writing timing data to '//trim(filename)//' - '//trim(io_msg)
562  CALL display_message(routine_name, msg, err_stat); RETURN
563  END IF
564 
565 
566  ! Done
567  CLOSE(fid, iostat = io_stat, &
568  iomsg = io_msg )
569  IF ( io_stat /= 0 ) THEN
570  err_stat = failure
571  msg = 'Error closing file '//trim(filename)//' - '//trim(io_msg)
572  CALL display_message(routine_name, msg, err_stat); RETURN
573  END IF
574 
575  END FUNCTION timing_writefile
576 
577 
578 
579 !##############################################################################
580 !##############################################################################
581 !## ##
582 !## ## PRIVATE MODULE ROUTINES ## ##
583 !## ##
584 !##############################################################################
585 !##############################################################################
586 
587  ! Private elemental function to compute the elapsed time in seconds
588  ELEMENTAL FUNCTION timing_elapsedtime( self ) RESULT( Elapsed_Time )
589  TYPE(timing_type), INTENT(IN) :: self
590  REAL(fp) :: elapsed_time
591  elapsed_time = 0.0_fp
592  IF ( .NOT. self%Is_Valid ) RETURN
593  elapsed_time = REAL(self%End_Clock - self%Begin_Clock, fp) / REAL(self%hertz, fp)
594  END FUNCTION timing_elapsedtime
595 
596 END MODULE timing_utility
integer, parameter, public failure
integer, parameter, public fp
Definition: Type_Kinds.f90:124
subroutine, public timing_set(self, Hertz, Begin_Clock, End_Clock, Is_Valid)
subroutine, public timing_get(self, Hertz, Begin_Clock, End_Clock, Is_Valid)
integer function, public get_lun()
elemental character(80) function timing_tostring(self, Seconds, Fmt_String)
subroutine, public timing_display(self, Caller)
integer, parameter ml
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
type(datetime_type) function, public datetime_now()
subroutine, public timing_end(self)
elemental character(80) function, public datetime_tostring(DateTime, Format)
elemental real(fp) function timing_elapsedtime(self)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
#define max(a, b)
Definition: mosaic_util.h:33
character(*), parameter module_version_id
subroutine, public timing_begin(self)
integer, parameter, public success
integer, parameter, public information
subroutine, public timing_inspect(self)
integer function, public timing_writefile(Timing_Array, Filename, Clobber, Heading)