mpp_io_mod, is a set of simple calls for parallel I/O on distributed systems. It is geared toward the writing of data in netCDF format. It requires the modules and , upon which it is built.
type, public :: axistype sequence character(len=128) :: name character(len=128) :: units character(len=256) :: longname character(len=8) :: cartesian integer :: len integer :: sense !+/-1, depth or height? type(domain1D), pointer :: domain real, dimension(:), pointer :: data integer :: id, did integer :: type ! external NetCDF type format for axis data integer :: natt type(atttype), pointer :: Att(:) ! axis attributes end type axistypeA field is described using the type fieldtype:
type, public :: fieldtype sequence character(len=128) :: name character(len=128) :: units character(len=256) :: longname real :: min, max, missing, fill, scale, add integer :: pack type(axistype), dimension(:), pointer :: axes integer, dimension(:), pointer :: size integer :: time_axis_index integer :: id integer :: type ! external NetCDF format for field data integer :: natt, ndim type(atttype), pointer :: Att(:) ! field metadata end type fieldtypeAn attribute (global, field or axis) is described using the atttype:
type, public :: atttype sequence integer :: type, len character(len=128) :: name character(len=256) :: catt real(FLOAT_KIND), pointer :: fatt(:) end type atttypeThis default set of field attributes corresponds closely to various conventions established for netCDF files. The pack attribute of a field defines whether or not a field is to be packed on output. Allowed values of pack are 1,2,4 and 8. The value of pack is the number of variables written into 8 bytes. In typical use, we write 4-byte reals to netCDF output; thus the default value of pack is 2. For pack = 4 or 8, packing uses a simple-minded linear scaling scheme using the scale and add attributes. There is thus likely to be a significant loss of dynamic range with packing. When a field is declared to be packed, the missing and fill attributes, if supplied, are packed also.
... type(domain2D), dimension(:), allocatable, target :: domain type(fieldtype) :: field type(axistype) :: x, y, z, t ... call mpp_define_domains( (/1,nx,1,ny/), domain ) allocate( a(domain(pe)%x%data%start_index:domain(pe)%x%data%end_index, & domain(pe)%y%data%start_index:domain(pe)%y%data%end_index,nz) ) ... call mpp_write_meta( unit, x, 'X', 'km', 'X distance', & domain=domain(pe)%x, data=(/(float(i),i=1,nx)/) ) call mpp_write_meta( unit, y, 'Y', 'km', 'Y distance', & domain=domain(pe)%y, data=(/(float(i),i=1,ny)/) ) call mpp_write_meta( unit, z, 'Z', 'km', 'Z distance', & data=(/(float(i),i=1,nz)/) ) call mpp_write_meta( unit, t, 'Time', 'second', 'Time' ) call mpp_write_meta( unit, field, (/x,y,z,t/), 'a', '(m/s)', AAA', & missing=-1e36 ) ... call mpp_write( unit, x ) call mpp_write( unit, y ) call mpp_write( unit, z ) ...In this example, x and y have been declared as distributed axes, since a domain decomposition has been associated. z and t are undistributed axes. t is known to be a record axis (netCDF terminology) since we do not allocate the data element of the axistype. Only one record axis may be associated with a file. The call to initializes the axes, and associates a unique variable ID with each axis. The call to mpp_write_meta with argument field declared field to be a 4D variable that is a function of (x,y,z,t), and a unique variable ID is associated with it. A 3D field will be written at each call to mpp_write(field).
... integer :: unit, natt, nvar, ntime type(domain2D), dimension(:), allocatable, target :: domain type(fieldtype), allocatable, dimension(:) :: fields type(atttype), allocatable, dimension(:) :: global_atts real, allocatable, dimension(:) :: times ... call mpp_define_domains( (/1,nx,1,ny/), domain ) call mpp_read_meta(unit) call mpp_get_info(unit,natt,nvar,ntime) allocate(global_atts(natt)) call mpp_get_atts(unit,global_atts) allocate(fields(nvar)) call mpp_get_vars(unit, fields) allocate(times(ntime)) call mpp_get_times(unit, times) allocate( a(domain(pe)%x%data%start_index:domain(pe)%x%data%end_index, & domain(pe)%y%data%start_index:domain(pe)%y%data%end_index,nz) ) ... do i=1, nvar if (fields(i)%name == 'a') call mpp_read(unit,fields(i),domain(pe), a, tindex) enddo ...In this example, the data are distributed as in the previous example. The call to initializes all of the metadata associated with the file, including global attributes, variable attributes and non-record dimension data. The call to mpp_get_info returns the number of global attributes (natt), variables (nvar) and time levels (ntime) associated with the file identified by a unique ID (unit). mpp_get_atts returns all global attributes for the file in the derived type atttype(natt). mpp_get_vars returns variable types (fieldtype(nvar)). Since the record dimension data are not allocated for calls to , a separate call to mpp_get_times is required to access record dimension data. Subsequent calls to mpp_read return the field data arrays corresponding to the fieldtype. The domain type is an optional argument. If domain is omitted, the incoming field array should be dimensioned for the global domain, otherwise, the field data is assigned to the computational domain of a local array.
mpp_mod
mpp_domains_mod
use mpp_io_mod [, only: mpp_write_meta,
mpp_write,
mpp_read,
mpp_get_atts,
mpp_io_init,
mpp_io_exit,
mpp_open,
mpp_close,
mpp_read_meta,
mpp_get_info,
mpp_get_times,
mpp_flush,
mpp_get_ncid ]
call mpp_write_meta ( unit, axis, name, units, longname, cartesian, sense, domain, data )
call mpp_write_meta ( unit, field, axes, name, units, longname, min, max, missing, fill, scale, add, pack )
call mpp_write_meta ( unit, id, name, rval=rval, pack=pack )
call mpp_write_meta ( unit, id, name, ival=ival )
call mpp_write_meta ( unit, id, name, cval=cval )
call mpp_write_meta ( unit, name, rval=rval, pack=pack )
call mpp_write_meta ( unit, name, ival=ival )
call mpp_write_meta ( unit, name, cval=cval )
unit | |
name | |
units | |
longname | |
cartesian | |
sense | |
domain | |
data | |
min, max | |
missing | |
fill | |
scale | |
add | |
pack | |
id | |
cval | |
ival | |
rval |
axis | |
field |
mpp_write ( unit, axis )
mpp_write ( unit, field, data, tstamp )
mpp_write ( unit, field, domain, data, tstamp )
tstamp | tstamp is an optional argument. It is to be omitted if the field was defined not to be a function of time. Results are unpredictable if the argument is supplied for a time- independent field, or omitted for a time-dependent field. Repeated writes of a time-independent field are also not recommended. One time level of one field is written per call. tstamp must be an 8-byte real, even if the default real type is 4-byte. |
data = packed_data*scale + addNOTE: mpp_write does not check to see if the scaled data in fact fits into the dynamic range implied by the specified packing. It is incumbent on the user to supply correct scaling attributes.
call mpp_read ( unit, field, data, time_index )
call mpp_read ( unit, field, domain, data, time_index )
unit |
[integer] |
field |
[type(fieldtype)] |
domain | |
time_index | time_index is an optional argument. It is to be omitted if the field was defined not to be a function of time. Results are unpredictable if the argument is supplied for a time- independent field, or omitted for a time-dependent field. |
data |
[real, dimension(:,:,:)] |
call mpp_get_atts ( unit, global_atts)
unit |
[integer] |
global_atts |
[atttype, dimension(:)] |
call mpp_io_init ( flags, maxunit )
flags |
[integer] |
maxunit |
[integer] |
call mpp_io_exit ()
call mpp_open ( unit, file, action, form, access, threading, fileset, iospec, nohdrs, recl, pelist )
file | file is the filename: REQUIRED
we append .nc to filename if it is a netCDF file
we append .<pppp> to filename if fileset is private (pppp is PE number) [character(len=*)] |
action | action is one of MPP_RDONLY, MPP_APPEND, MPP_WRONLY or MPP_OVERWR. [integer] |
form | form is one of MPP_ASCII: formatted read/write
MPP_NATIVE: unformatted read/write with no conversion
MPP_IEEE32: unformatted read/write with conversion to IEEE32
MPP_NETCDF: unformatted read/write with conversion to netCDF [integer] |
access | access is one of MPP_SEQUENTIAL or MPP_DIRECT (ignored for netCDF).
RECL argument is REQUIRED for direct access IO. [integer] |
threading | threading is one of MPP_SINGLE or MPP_MULTI
single-threaded IO in a multi-PE run is done by PE0. [integer] |
fileset | fileset is one of MPP_MULTI and MPP_SINGLE
fileset is only used for multi-threaded I/O
if all I/O PEs in <pelist> use a single fileset, they write to the same file
if all I/O PEs in <pelist> use a multi fileset, they each write an independent file [integer] |
pelist | pelist is the list of I/O PEs (currently ALL). [integer] |
recl | recl is the record length in bytes. [integer] |
iospec | iospec is a system hint for I/O organization, e.g assign(1) on SGI/Cray systems. [character(len=*)] |
nohdrs | nohdrs has no effect when action=MPP_RDONLY|MPP_APPEND or when form=MPP_NETCDF [logical] |
unit | unit is intent(OUT): always _returned_by_ mpp_open(). [integer] |
namelist / nml / ... ... call mpp_open( unit, 'input.nml', action=MPP_RDONLY ) read(unit,nml)will result in each PE independently reading the same namelist.
call mpp_open( unit, ... iospec='-F cachea' )on an SGI/Cray system, which would pass the supplied iospec to the assign(3F) system call.
call mpp_close ( unit, action )
unit |
[integer] |
action |
[integer] |
call mpp_read_meta (unit)
unit |
[integer] |
call mpp_get_info ( unit, ndim, nvar, natt, ntime )
unit |
[integer] |
ndim |
[integer] |
nvar |
[integer] |
natt |
[integer] |
ntime |
[integer] |
call mpp_get_times ( unit, time_values )
unit |
[integer] |
time_values |
[real(DOUBLE_KIND), dimension(:)] |
call mpp_flush (unit)
unit |
[integer] |
mpp_get_ncid (unit)
unit |
[integer] |
use mpp_io_modIf netCDF output is desired, the cpp flag -Duse_netCDF must be turned on. The loader step requires an explicit link to the netCDF library (typically something like -L/usr/local/lib -lnetcdf, depending on the path to the netCDF library). netCDF release 3 for fortran is required.
The source consists of the main source file and also requires the following include files: (when compiled with ) GFDL users can check it out of the main CVS repository as part of the CVS module. The current public tag is . External users can download the latest package . Public access to the GFDL CVS repository will soon be made available.