[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 20011116: f90 on Cray T3E



>To: address@hidden
>From: Kate Hedstrom <address@hidden>
>Subject: f90 on Cray T3E
>Organization: UCAR/Unidata
>Keywords: 200111161935.fAGJZwN14729

Hi Kate,

> I would like to use the new f90 NetCDF interface on a Cray T3E. First I
> tried version 3.5.0, finding that it has the 8-byte integer problem. I now
> have beta 3.5.1 and it gets a little farther:
> 
> % make test
>  Not a netCDF data type or _FillValue type mismatch
>  Not a netCDF data type or _FillValue type mismatch
>  Not a netCDF data type or _FillValue type mismatch
> example_good.cdl example.cdl differ: char 78, line 5
> *** Failure ***
> *** example_good.cdl  Wed Apr  5 11:33:14 2000
> --- example.cdl       Fri Nov 16 10:30:51 2001
> ***************
> *** 2,15 ****
>   dimensions:
>       lat = 4 ;
>       lon = 3 ;
> !     frtime = UNLIMITED ; // (2 currently)
>       timelen = 20 ;
>   variables:
>       float P(frtime, lat, lon) ;
>               P:long_name = "pressure at maximum wind" ;
>               P:units = "hectopascals" ;
> !             P:valid_range = 0.f, 1500.f ;
> !             P:_FillValue = -9999.f ;
>       float lat(lat) ;
>               lat:long_name = "latitude" ;
>               lat:units = "degrees_north" ;
> --- 2,15 ----
>   dimensions:
>       lat = 4 ;
>       lon = 3 ;
> !     frtime = UNLIMITED ; // (0 currently)
>       timelen = 20 ;
>   variables:
>       float P(frtime, lat, lon) ;
>               P:long_name = "pressure at maximum wind" ;
>               P:units = "hectopascals" ;
> !             P:valid_range = 0., 1500. ;
> !             P:_FillValue = -9999. ;
>       float lat(lat) ;
>               lat:long_name = "latitude" ;
>               lat:units = "degrees_north" ;
> ***************
> *** 29,49 ****
>               :title = "NMC Global Product Set: Pressure at Maximum Wind" ;
>   data:
>   
> -  P =
> -   950, 951, 952,
> -   953, 954, 955,
> -   956, 957, 958,
> -   959, 960, 961,
> -   962, 963, 964,
> -   965, 966, 967,
> -   968, 969, 970,
> -   971, 972, 973 ;
> - 
>    lat = -90, -87.5, -85, -82.5 ;
>   
>    lon = -180, -175, -170 ;
> - 
> -  frtime = 12, 18 ;
>   
>    reftime = "1992-3-21 12:00" ;
>   
> --- 29,37 ----
> Make: "./netcdf_test; \
> ../ncdump/ncdump example.nc >example.cdl; \
> if cmp example_good.cdl example.cdl; then \
>     echo '*** Success ***'; \
> else \
>     echo '*** Failure ***'; \
>     diff -c example_good.cdl example.cdl; \
> fi": Error code 1
> cmd-2436 make: Stop.
> 
> 
> 
> The three warning messages are printed when executing:
> 
> call check(nf90_put_var(ncFileID, frTimeVarId,  (/ 12, 18 /)
> call check(nf90_put_var(ncFileID, pressVarID, pressure(:, :, 1)) )
> call check(nf90_put_var(ncFileID, pressVarID, pressure(:, :, 2), start = (/ 
> 1, 1, 2 /)) )

I believe the problems you are seeing are with the test program,
netcdf_test.f90, rather than with the Fortran 90 library interface.
The test program is using integer and real constants in calls where
the type is then determined by the number of bytes required for the
constant.  For example,

  call check(nf90_put_var(ncFileID, frTimeVarId,  (/ 12, 18 /)                ) 
)

provides an anonymous array of integer values, which are each 8-byte
integers on the Cray T3E.  But the variable frTimeVarId is defined to
correspond to a netCDF 4-byte integer in

  call check(nf90_def_var(ncFileID, "frtime", nf90_int, frTimeDimID, 
frTimeVarID) )

Although I don't have access to a Cray T3E on which to check this, I
think if the anonymous array above were replaced by an array of 4-byte
integers that would make one of the 3 warnings disappear.

Similarly, the attribute values for P:valid_range and P:_FillValue
are the wrong type if anonymous values are used, so these should be in
named variables of the right type also.

I have appended a new version of netcdf_test.f90 that I'd like to have
you try on the Cray T3E, if that's convenient.  Please let me know if
this works; I've already checked it on 32-bit platforms.  Thanks.

--Russ

--------------- f90/netcdf_test.f90 -----------------------------------
! This program provides an elementary check of some of the parts of the 
!   Fortran 90 interface to netCDF 3.5. It is a Fortran 90 implementation
!   of the nctst.cpp program provided with the C++ interface to netcdf
!   (in the src/cxx directory of the netcdf distribution). 
!
program netcdfTest
  use typeSizes
  use netcdf
  implicit none
  
  ! netcdf related variables
  integer :: ncFileID,                                   &
             latDimID, lonDimID, frTimeDimID, timeDimID, &
             pressVarID, latVarID, lonVarID, frTimeVarID, refTimeVarID, 
scalarVarID
             
  ! Local variables
  integer, parameter :: numLats = 4, numLons = 3, &
                        numFrTimes = 2, timeStringLen = 20
  character (len = *), parameter :: fileName = "example.nc"
  integer :: counter                      
  real, dimension(numLons, numLats, numFrTimes) :: pressure
  integer (kind = FourByteInt), dimension(numFrTimes) :: frTimeVals
  real (kind = FourByteReal) fillVal;
  real (kind = FourByteReal), dimension(2) :: validRange;
  
  ! --------------------
  ! Code begins
  ! --------------------
  if(.not. byteSizesOK()) then
    print *, "Compiler does not appear to support required kinds of variables."
    stop
  end if
    
  ! Create the file
  call check(nf90_create(path = trim(fileName), cmode = nf90_clobber, ncid = 
ncFileID))
  
  ! Define the dimensions
  call check(nf90_def_dim(ncid = ncFileID, name = "lat",     len = numLats,     
   dimid = latDimID))
  call check(nf90_def_dim(ncid = ncFileID, name = "lon",     len = numLons,     
   dimid = lonDimID))
  call check(nf90_def_dim(ncid = ncFileID, name = "frtime",  len = 
nf90_unlimited, dimid = frTimeDimID))
  call check(nf90_def_dim(ncid = ncFileID, name = "timelen", len = 
timeStringLen,  dimid = timeDimID))

  ! Create variables and attributes
  call check(nf90_def_var(ncid = ncFileID, name = "P", xtype = nf90_float,     &
                     dimids = (/ lonDimID, latDimID, frTimeDimID /), varID = 
pressVarID) )
  call check(nf90_put_att(ncFileID, pressVarID, "long_name",   "pressure at 
maximum wind"))
  call check(nf90_put_att(ncFileID, pressVarID, "units",       "hectopascals") )
  ! Use 4-byte reals explicitly, to match 4-byte attribute type in test file
  validRange(1) = 0.
  validRange(2) = 1500
  call check(nf90_put_att(ncFileID, pressVarID, "valid_range", validRange))
  ! Use a 4-byte float constant, to match variable type
  fillVal = -9999.0
  call check(nf90_put_att(ncFileID, pressVarID,  "_FillValue", fillVal ) )
                      
  call check(nf90_def_var(ncFileID, "lat", nf90_float, dimids = latDimID, varID 
= latVarID) )
  call check(nf90_put_att(ncFileID, latVarID, "long_name", "latitude"))
  call check(nf90_put_att(ncFileID, latVarID, "units", "degrees_north"))

  call check(nf90_def_var(ncFileID, "lon", nf90_float, lonDimID, lonVarID) )
  call check(nf90_put_att(ncFileID, lonVarID, "long_name", "longitude"))
  call check(nf90_put_att(ncFileID, lonVarID, "units",     "degrees_east"))

  call check(nf90_def_var(ncFileID, "frtime", nf90_int, frTimeDimID, 
frTimeVarID) )
  call check(nf90_put_att(ncFileID, frTimeVarID, "long_name", "forecast time"))
  call check(nf90_put_att(ncFileID, frTimeVarID, "units",     "hours"))

  call check(nf90_def_var(ncFileID, "reftime", nf90_char, timeDimID, 
refTimeVarID) )
  call check(nf90_put_att(ncFileID, refTimeVarID, "long_name", "reference 
time"))
  call check(nf90_put_att(ncFileID, refTimeVarID, "units",     "text_time"))
                     
  ! In the C++ interface the define a scalar variable - do we know how to do 
this? 
  call check(nf90_def_var(ncFileID, "ScalarVariable", nf90_real, scalarVarID))
  
  ! Global attributes
  call check(nf90_put_att(ncFileID, nf90_global, "history", &
                     "created by Unidata LDM from NPS broadcast"))
  call check(nf90_put_att(ncFileID, nf90_global, "title", &
                     "NMC Global Product Set: Pressure at Maximum Wind"))
  
  ! Leave define mode
  call check(nf90_enddef(ncfileID))
  
  ! Write the dimension variables
  call check(nf90_put_var(ncFileID, latVarId,     (/ -90., -87.5, -85., -82.5 
/)) )
  call check(nf90_put_var(ncFileID, lonVarId,     (/ -180, -175, -170 /)      ) 
)
  ! Don't use anonymous array here, in case platform has 8-byte integers
  frTimeVals(1) = 12
  frTimeVals(2) = 18
  call check(nf90_put_var(ncFileID, frTimeVarId,  frTimeVals                  ) 
)
  call check(nf90_put_var(ncFileID, reftimeVarID, "1992-3-21 12:00"           ) 
)
  
  ! Write the pressure variable. Write a slab at a time to check incrementing.
  pressure = 949. + real(reshape( (/ (counter, counter = 1, numLats * numLons * 
numFrTimes) /),  &
                                    (/ numLons, numLats, numFrTimes /) ) )
  call check(nf90_put_var(ncFileID, pressVarID, pressure(:, :, 1)) )
  call check(nf90_put_var(ncFileID, pressVarID, pressure(:, :, 2), start = (/ 
1, 1, 2 /)) )
  
  call check(nf90_put_var(ncFileID, scalarVarID, 10))
  call check(nf90_close(ncFileID))

contains
  ! Internal subroutine - checks error status after each netcdf, prints out 
text message each time
  !   an error code is returned. 
  subroutine check(status)
    integer, intent ( in) :: status
    
    if(status /= nf90_noerr) then 
      print *, trim(nf90_strerror(status))
    end if
  end subroutine check  
end program netcdfTest
--------------- end of f90/netcdf_test.f90 -----------------------------------