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

EMA: JB ROBERTSON, Re: 980428: A bug with SUN F90



>To: address@hidden
>From: ineris <address@hidden>
>Subject: A bug with SUN F90
>Organization: French National Institute for Industrial Environment and Hazards
>Keywords: 199804281506.JAA03747

Hi,

> I would please to have some help on the following problem:
> 
> I encounter errors I am not able to understand when using netcdf-2.4-beta6
> with my fortran 90 compiler (SUN SC4.0 11 Sep 1995 FORTRAN 90 1.1). I have
> no way to translate any f77 program using NetCDF into f90 : some data can
> be read, but nothing can be written in a file.
> 
> I use the netcdf.f90 file (written by Russ Rew, Unidata, and Robert Pincus,
> NASA/GSFC) and compile the following program with
> 
> f90 -o toto tralala2.f90 -L/export/home/Stg_Num/netcdf-2.4-beta6/lib
> -lnetcdf \
>     -L/usr/lib -lnsl
> 
> (The file netcdf.o is in libnetcdf)
> 

Sorry it has taken so long to reply to your question.  We are now
supporting netCDF version 3.4, and I could not find the netcdf-2.4-beta6
version of the netcdf.f90 file you refer to.  I did find a version of
netcdf.f90 in the netcdf-2.4.3 version from August 1996 that may be the
same.  

This was an experiment in trying to provide some Fortran 90 support, but
we never succeeded in creating a complete Fortran 90 interface for
netCDF-2.  The Fortran interface uses "type punning" where the same
parameter to a subroutine such as NCVPT's data parameter is intended to
serve for INTEGER or REAL arguments of various ranks (scalar, vector,
multidimensional arrays ...).  We did not know how to get around Fortran
90's stricter type checking that only permits a single type and shape
the data parameter.  We should have made it clearer in the documentation
for netcdf.f90 that it was not complete, but the version from
netcdf-2.4.3 does contain the following comment, indicating the kinds of
problems we were running in to:

    ! In some of the following routines, values may legally have any type and 
any
    ! dimension up to 7 (the Fortran limit). We haven't worked out a way to 
    ! treat this in Fortran-90, so the interface blocks have been commented 
out. 

    !   subroutine ncvpt1 (ncid,varid,indices,value, rcode)
    !     integer            , intent ( in) :: ncid, varid
    !     integer, dimension(:), &
    !                          intent ( in) :: indices
    !     real               , intent ( in) :: value
    !     integer            , intent (out) :: rcode
    !   end subroutine ncvpt1

In the latest version (netcdf-3.4), we have provided a new version of
the Fortran interface in addition to the old netcdf-2 Fortran interface.
The new interface solves the type punning problem by doing automatic
type conversion between the external numeric type and whatever internal
numeric type you desire, but it doesn't solve the problem of allowing
different ranks for the data argument.  We have discussed with Robert
Pincus of NASA how to solve this problem and provide a good Fortran 90
interface for netCDF, but we haven't finished the required work.  Pincus
has showed us how we could use generic functions and optional (named)
arguments to implement a Fortran90 interface (purely with module
definitions) that uses just one read and one write interface.  In case
you are interested, I've appended some email about this subject ...

Hence for now, it is necessary to use one of the two Fortran 77
interfaces, which should still work OK with a Fortran 90 compiler.

> The program that follows has been translated from fortran 77, and worked with-
> out any errors.
> 
> tralala2.f90:_____________________________________________________
> 
> program tralala
> 
> use netcdf
> 
>   implicit none
>   integer  rcode, ncid
> 
>  !declaration partie tableau
> 
>   integer                           :: dimxid, dimyid, dimzid
>   integer, parameter                :: dimx=3, dimy=4, dimz=5
>   integer                           :: varid, i, j, k
>   integer, dimension(3)             :: profil, start, tcount
>   real, dimension(dimx, dimy, dimz) :: tableau
> 
> 
>   call ncpopt(NCVERBOS)
>   ncid = NCCRE("monfichier2.nc", ncclob, rcode) 
> 
>  !Stockage d un tableau
> 
>   dimxid = NCDDEF(ncid, 'dimx', dimx, rcode)
>   dimyid = NCDDEF(ncid, 'dimy', dimy, rcode)
>   dimzid = NCDDEF(ncid, 'dimz', dimz, rcode)
> 
>   profil(1) = dimxid
>   profil(2) = dimyid
>   profil(3) = dimzid
> 
>   write(*,*) 'NCVDEF'
> 
>   varid = NCVDEF( ncid, 'tableau', NCFLOAT, 3, profil, rcode)
> 
>  !Remplissage du tableau
> 
>   do i=1, dimx
>      do j =1, dimy
>         do k=1, dimz
>            tableau(i,j,k) = float(i*j*k)
>         enddo
>      enddo
>   enddo
> 
>  !Ecriture
> 
>   call NCENDF(ncid, rcode)
> 
>   start(1) = 1
>   start(2) = 1
>   start(3) = 1
> 
>   tcount(1) = dimx
>   tcount(2) = dimy
>   tcount(3) = dimz
> 
>   call NCVPT(ncid, varid, start, tcount, tableau, rcode)
> 
>   call NCCLOS( ncid, rcode)
> 
> end program tralala
> 
> _____________________________________________________
> 
> 
> I cannot believe such a bug can come form NetCDF: I suppose it comes from
> my f90 compiler. 

I think this will work if you just replace the "use netcdf" statement
with an "include 'netcdf.inc' statement, so that you are no longer
trying to use the faulty netcdf.f90 interface block.  I just tried this
on a SunOS 2.6 system using the f90 compiler, and it worked fine.

--Russ

_____________________________________________________________________

Russ Rew                                         UCAR Unidata Program
address@hidden                     http://www.unidata.ucar.edu

    ----------------------------------------------------

    From address@hidden  Fri Oct 31 12:32:56 1997
            by unidata.ucar.edu (8.8.6/8.8.6) with SMTP id MAA06800;
            Fri, 31 Oct 1997 12:32:56 -0700 (MST)
    Message-Id: <address@hidden>
    To: Robert Pincus <address@hidden>
            address@hidden
    Subject: Re: Fortran 90 support in netCDF 3.3.1 
    In-reply-to: Your message of "Thu, 30 Oct 1997 18:42:34 EST."
                 <v03010d0db07ebc671886@[128.183.200.25]> 
    Organization: UCAR Unidata Program
    Date: Fri, 31 Oct 1997 12:32:55 -0700
    From: Russ Rew <address@hidden>

    > To: Russ Rew <address@hidden>
    > From: Robert Pincus <address@hidden>
    > Subject: Fortran 90 support in netCDF 3.3.1

    Robert,

    > Wow, that Fortran 90 module for netCDF 3.3.1 looks like a lot of work.

    Only a couple of hours with emacs macros ...

    > I have been using another approach to get at the number of bytes used in
    > different representations. At
    > ftp://climate.gsfc.nasa.gov/pub/pincus/F90/typeSizes.f90 is a module I
    > wrote to try and get around the problem of specifying integer*1, etc. It
    > defines symbolic type parameters for one, two, and four byte integers, and
    > four and eight byte reals. There is also a Boolean function which would be
    > invoked during testing to ensure that the reported kind parameters are
    > consistent, since some compilers don't support all those different kinds.
    > Feel free to include whatever you need from the module in the netCDF
    > release.

    Thanks, this looks useful.

    > I think you may want to change the interface blocks to the Fortran 77
    > functions. On some compilers, if a variable is declared as assumed shape
    > (i.e. has the declaration dimension(:) rather than dimension(*)) the
    > compiler passes along extra information to let the called routine 
determine
    > the bounds and size of the array. Your F77 functions won't know what to do
    > with that, so I suspect all you should replace every occurrence of
    > dimension(:) with dimension(*).

    OK, I've done that.

    > I remember having a discussion with you about the interfaces last summer,
    > and I wondered how you were going to be able to match both type (as you
    > have in this model) and rank. In the module you sent me it appears that 
one
    > can only one dimension arrays. For example, if one tried to pass a two
    > dimensional array as the IVALS argument to
    > 
    > INTEGER FUNCTION NF_PUT_VARA_INT(NCID, VARID, START, COUNT,IVALS)
    >   ....
    >   integer,         dimension(*), intent ( in) :: IVALS
    > end function NF_PUT_VARA_INT
    > 
    > the compiler would complain that the argument had the wrong rank (number 
of
    > dimensions). The user could get around this problem by PACKing the values
    > from a multi-dimensional array before handing them off to the NF_PUT_VARA_
    > routines, but you would probably want to note that in the documentation.
    > (I'm pretty sure there is no way to build an interface block that tells 
the
    > compiler that the underlying routine doesn't care about the rank of the
    > array.)

    Oops, I forgot about that.  That makes the whole idea of adding extra
    checking with an interface block kind of useless.  I just tried
    inserting some "use netcdf" statements in various nf_test subroutines,
    and saw errors caused by this.  How do math libraries like IMSL that
    exploit the fact that you can use a vector or a matrix for the RHS of a
    linear system (for example) deal with this?  This seems like a mistake
    in the standard ...

    > I have a couple of suggestions as to ways you could exploit the neat
    > features of Fortran 90, but I don't know what level of resources and/or
    > expertise you have to devote to this. I will say that a lot of numerical
    > people use netCDF, and many of us are moving to Fortran 90. I would be
    > happy to help you with some of these ideas as my time allows.

    Currently, we have no expertise or resources to adapt netCDF to Fortran
    90.  We're trying to recruit someone from NCAR's Scientific Computing
    Division to help with that.

    > Have you given any thought to making generic versions of some functions?
    > For example, you could use the netCDF module to define a generic function
    > for putting one dimensional arrays. I put a free-standing module to do 
that
    > at ftp://climate.gsfc.nasa.gov/pub/pincus/F90/netcdfF90.f90. Using this
    > module, one could make a call to
    >   NF90_PUT_VARA(NCID, VARID, START, COUNT, VALUES)
    > where VALUES could be of any type (1, 2, 4 byte ints, single precision and
    > double precision reals, or text). I think this would be a nice addition.
    >
    > The idea of generic functions could be expanded to allow one to write
    > multi-dimensional arrays using the current interface. One would have to
    > write a LOT of specific functions: 7 (to include up to 7 dimensional 
arrays,
    > the max in the standard) times 6 (3 kinds of ints, 2 reals, 1 text) is 42.
    > But one could also do some error checking in the specific functions to
    > ensure that start, count, and stride were consistent with the array 
section
    > being passed, since Fortran 90 (unlike C or F77) knows how many values are
    > being passed. That could be really neat.
    > 
    > As icing on the cake, one could use the optional argument features of
    > Fortran 90. One obvious place is if one is writing every element of an
    > array. Since netCDF can check the file definition to see the shape of the
    > array in the file, one could make start, count, and stride optional
    > arguments, which only needed to be supplied if one were writing a
    > subsection. That would enable calls like
    >   NF90_PUT_VARA(NCID, VARID, VALUES)
    > which would also be cool.

    Yes, this looks very useful.  I'll save your message, in case we get
    resources for adapting netCDF to Fortran 90.

    Thanks for the information.

    --Russ

    _____________________________________________________________________

    Russ Rew                                         UCAR Unidata Program
    address@hidden                     http://www.unidata.ucar.edu