Figure 3.9 depicts the history buffer for a case in which the user has requested two auxiliary history files in addition to the primary history file. The history buffer is represented by the vertical rectangle in the center of the figure. Notice that the buffer is divided into three sections, the first corresponding to the portion of memory devoted to fields on the primary history file, followed by the portions allotted to the first and second auxiliary files, respectively. The values in array hbufpt point to the starting word of the latitude data record for each history file in the buffer. Arrays nplen and nrlen contain the packed and unpacked field lengths of each data record. Recall namelist variable NDENS(i) specifies the packing density of fields in each history file. For the buffer shown in Figure 3.9, NDENS(1)=2, thus nplen(1) (the packed length) is one-half the length of nrlen(1) (the unpacked length) as shown.
Figure 3.9. History buffer layout.
Allocation of memory for the history buffer occurs during the initialization phase of a run, in subroutine intht. If the buffer is contained entirely in-core, then the model calls routine getmem to dynamically allocate a segment of in-core memory of length plat x lhbuf. The storage address of the first word in this in-core memory block is pointed to by the Cray pointer phbufic and its associated two-dimensional pointee array hbufic(lhbuf,plat). After being allocated, the in-core history buffer exists and is accessible for the remainder of the run.
During the time integration phase, field values to be output to a history
file are accumulated in the history buffer. For each field that will be
saved in the history buffer, a call is made to routine outfld.
Calls to outfld occur within a multitasked loop over latitudes,
from routines linemsbc or linemsac and below. When running
multitasked, each process will perform calls to outfld and load
the history buffer with fields from a single latitude index. Access
to the section of the in-core history buffer relevant to that latitude
index is facilitated by the pointer array hbuf. The following
block of code, extracted from linemsbc, shows how this is accomplished.
subroutine linemsbc(lat
,tdt ,ps ,psm1 ,u3 ,
.
.
.
pointer (phbuf,hbuf)
real hbuf(lhbuf)
! history buffer pointee array
.
.
.
if (incorhst) then
phbuf = loc(hbufic(1,lat))
!in-core history buffer
else
.
.
.
call outfld('PS
',psm1,plond,lat,hbuf)
In this code, lat refers to the particular latitude index that is being calculated, and is passed as an argument to linemsbc from a multitasked loop in scan1bc. The pointee array hbuf is associated with the portion of hbufic that corresponds to lat (since INCORHST is true when the buffer is in-core). The call to outfld that is shown will load the surface pressure array, psm1, into the history buffer. A similar call to outfld exists for every history file field.
If the history buffer is declared out-of-core, the model will use the SSD to accumulate history file fields. If no SSD exists, then the model will use a local disk file to store the out-of-core history buffer. This should be avoided since disk I/O is typically very slow. As described in "Out-of-Core Data Storage: The SSD Work Units" , the SSD is high-speed, out-of-core secondary storage that is accessed using Fortran read and write statements. Thus, the out-of-core history buffer can be thought of as a direct access Fortran file with extremely fast I/O. The SSD file contains plat data records, each of length lhbuf. When the model needs to accumulate fields in the history buffer (from within multitasked routines linemsbc and linemsac), the following steps are executed on each processor:
subroutine linemsbc(lat
,tdt ,ps ,psm1 ,u3 ,
.
.
.
pointer (phbuf,hbuf)
real hbuf(lhbuf)
! history buffer pointee array
.
.
.
if (incorhst) then
phbuf = loc(hbufic(1,lat))
!in-core history buffer
else
call getmem(`LINEMSBC',lhbuf,phbuf)
!out-of-core hbuf
call readric(sunit,hbuf,lhbuf,lat)
endif
.
.
.
call outfld('PS
',psm1,plond,lat,hbuf)
.
.
.
if (.not.incorhst) then
call writeric(sunit,hbuf,lhbuf,lat)
! write to SSD
call freemem(phbuf)
endif
.
.
.
return
Again, the current latitude index lat is passed as an argument
to linemsbc from scan1bc. The pointee array hbuf
and its pointer phbuf are then declared. Because INCORHST
is false when the history buffer is kept out-of-core, the model calls getmem
and readric to access the history buffer as described in the steps
above. Just as with the in-core history buffer, fields are accumulated
in array hbuf via calls to outfld, as shown for the surface
pressure array psm1. After all history fields have been loaded
into the hbuf array, and prior to executing the return
statement in linemsbc, the history buffer fields are written to
the out-of-core history buffer on the SSD by calling routine writeric.
Once this has been completed, freemem is called to release the
in-core memory and return it to the heap.
Questions on these pages can be sent to... erik@ucar.edu .