[MITgcm-support] MNC oddities on Cray T3E

Mark Hadfield m.hadfield at niwa.co.nz
Tue Mar 27 01:22:39 EDT 2007


Having just spent a couple of happy (?!) days getting the MNC package 
working on our Cray T3E, I thought I should report my success to the 
mailing list. Furthermore, my solution is a bit clunky at the moment and 
I'd appreciate suggestions for doing things better.

The biggest difficulty relates to the compiler's idiosyncratic handling 
of floating-point number precision. By default, single-precision real 
numbers use 8 bytes (64 bits), as do double-precision real numbers, that is

  REAL = DOUBLE = REAL*8

The compiler also supports a 4-byte floating-point type via a REAL*4 
declaration; it does not have a REAL*16 type.

The compiler accepts a "-s default32" switch (which I didn't know about 
until today) that "Adjusts the default sizes as follows:  real, integer, 
and logical are set to 32 bits; complex and double precision are set to 
64 bits; double complex is set to 128 bits." Using this switch might 
solve the problems I'll describe below, but would bring in the 
complication that other libraries (notably the netCDF library) have been 
built without it. So I'll leave that for another day.

The first problem I ran into was that the function MNCCDIR is 
unavailable, because genmake2 found that linking with C routines was 
broken and so disabled it. I worked around this by commenting out the 
call. I suspect that the C-linking problem arises from type mismatches 
between C and Fortran, but haven't got around to checking this out yet.

The second problem occurrs in subroutine MNC_CW_RL_W_OFFSET, defined in 
pkg/mnc/MNC_CW_READWRITE_RL.F. When the model writes out information to 
the state file, it crashes with a floating point exception when writing 
out u-velocity data. The problem arises because the corresponding 
variable (U) in the netCDF file has the FLOAT data type. In this 
situation, MNC_CW_RL_W_OFFSET copies the data into a REAL*4 array, 
resh_r, then puts the data with the netCDF library's NF_PUT_VARA_REAL 
function. But NF_PUT_VARA_REAL expects the data to be of type REAL, 
which on this platform is REAL*8, so it reads data from beyond the area 
that's been initialised, leading to general mayhem.

My work-around is to declare resh_r as

#ifdef TARGET_T3E
      REAL  resh_r( MNC_MAX_BUFF )
#else
      REAL*4  resh_r( MNC_MAX_BUFF )
#endif

This fixes things nicely. So I'm happy for the time being, but I wonder 
if this problem can  be solved more elegantly. Furthermore, I'm a bit 
puzzled about the approach taken by MNC_CW_RL_W_OFFSET. The heart of the 
subroutine is as follows

        IF (stype(1:1) .EQ. 'D') THEN
          ...
          err = NF_PUT_VARA_DOUBLE(fid, idv, vstart, vcount, resh_d)
        ELSEIF (stype(1:1) .EQ. 'R') THEN
          ...
          err = NF_PUT_VARA_REAL(fid, idv, vstart, vcount, resh_r)
        ELSEIF (stype(1:1) .EQ. 'I') THEN
          ...
          err = NF_PUT_VARA_INT(fid, idv, vstart, vcount, resh_i)
        ENDIF

where resh_d is REAL*8, resh_r is REAL*4 and resh_i is INTEGER. So the 
code goes to the trouble of creating and populating a data array that 
matches the netCDF variable. But this is unnecessary, surely, as the 
netCDF library will do this for us, see

http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-f77/Type-Conversion.html#Type-Conversion

-- 
Mark Hadfield          "Ka puwaha te tai nei, Hoea tahi tatou"
m.hadfield at niwa.co.nz
National Institute for Water and Atmospheric Research (NIWA)






More information about the MITgcm-support mailing list