Re: 19990928: NetCDF conversion problems on Crays

  • To: jps@xxxxxxxx
  • Subject: Re: 19990928: NetCDF conversion problems on Crays
  • From: Brian Eaton <eaton@xxxxxxxxxxxx>
  • Date: Tue, 5 Oct 1999 20:48:08 -0600 (MDT)
Hi John,

I think that using f90 generic functions as wrappers to the type specific
netCDF routines addresses the problem you have presented.  Here is an
example of using a generic function for writing a 1D array of real data:

module mod1
  implicit none
  save
  private
  public :: writenc_var_real
  interface writenc_var_real
    module procedure writenc_var_sp, writenc_var_dp
  end interface
contains
integer function writenc_var_sp( ncid, varid, vals )
! Write single precision data to a netCDF file.
  implicit none
  include 'netcdf.inc'
  integer, intent(in) :: ncid, varid
  real, intent(in), dimension(:) :: vals
  writenc_var_sp = NF_PUT_VAR_REAL( ncid, varid, vals )
end function writenc_var_sp
integer function writenc_var_dp( ncid, varid, vals )
! Write double precision data to a netCDF file.
  implicit none
  include 'netcdf.inc'
  integer, intent(in) :: ncid, varid
  double precision, intent(in), dimension(:) :: vals
  writenc_var_dp = NF_PUT_VAR_DOUBLE( ncid, varid, vals )
end function writenc_var_dp
end module mod1

program main
  ! Write single or double precision data to a netCDF file.
  use mod1
  implicit none
  include 'netcdf.inc'
  integer, parameter :: len = 4
  real :: arr(len) = (/ 1., 2., 3., 4. /)
  integer :: ret, ncid, ndims = 1, dimid, varid
  ! Create file.
  ret = NF_CREATE( 'zzz.nc', NF_CLOBBER, ncid )
  ! Define dimensions.
  ret = NF_DEF_DIM( ncid, 'len', len, dimid )
  ! Define variables.
  ret = NF_DEF_VAR( ncid, 'arr', NF_FLOAT, ndims, dimid, varid )
  ! End definition mode.
  ret = NF_ENDDEF( ncid )
  ! Write the data.
  ret = writenc_var_real( ncid, varid, arr )
  ! Close file.
  ret = NF_CLOSE( ncid )
end program main

Notes:

1. The module should be compiled separately, and it can't be compiled with
   a -r8 flag because then the specific funtions have identical interfaces
   and the generic function is ambiguous.

2. The main program can be compiled with or without a -r8 flag and the
   generic function writenc_var_real calls the correct netCDF function.
   Alternatively the main program can declare different real types using
   real*4, real*8, or parameterized real types as in f90.  I did manage to
   break the code on a Cray J90 using a real(selected_real_kind(p=6))
   declaration of arr.  This is because the J90 returned a kind value of 4
   even though there are no 4-byte floating point representations on that
   machine.

3. Since generic functions identify the correct specific functions based on
   both type and rank of array arguments, additional specific functions
   need to be added to writenc_var_real to generalize this example to
   arrays of dimension other than one.

4. This should work on Crays in general (with the specific exception
   described in note 2.).  On the older PVP type machines using Cray
   floating point the specific function for writing double precision data
   (16-byte) is of course broken, but under normal circumstances that
   function would not be called.  The newer Crays use IEEE floating point
   and things should work the same there as on non-Cray platforms.

Regards,
Brian


Brian Eaton                               | email: eaton@xxxxxxxx
Climate Modeling Section                  |
National Center for Atmospheric Research  |
P.O. Box 3000, Boulder, CO  80307         |


  • 1999 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: