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

Re: NetCDF - Fortran77 Interface Question



>To: address@hidden
>From: "Mattison, Frank (Contractor)" <address@hidden>
>Subject: Re: 20050121: NetCDF -  Fortran77 Interface Question
>Organization: Naval Research Lab
>Keywords: f77 interface implementation

Hi Frank,

> Unidata has provided lots of documentation on netCDF, and after reading much
> of it I really feel stupid for asking the following question.  I want to use
> the Fortran77 interface, and somehow I feel I am missing all of the nf_*
> code.  Could you please read this and try to straighten me out?
> 
> I have downloaded these directories & files:
> 
> netcdf-3.6.0
>    src
>       cxx
>       f90
>       fortran
>       libsrc
>       man
>       nctest
>       ncdump
>       ncgen
>       nctest
>       nf_test
>       win32
>          aclocal.m4    (file)
>          config.guess    "
>                  .
>                  .
>                  .
>          VERSION
> 
> I am focused on the following from your Fortran77 interface documentaion:
> 
> 1.1 Creating a NetCDF Dataset
> Here is a typical sequence of netCDF calls used to create a new netCDF
> dataset: 
>          NF_CREATE           ! create netCDF dataset: enter define mode
>               ...
>             NF_DEF_DIM       ! define dimensions: from name and length
>               ...
>             NF_DEF_VAR       ! define variables: from name, type, dims
>               ...
>             NF_PUT_ATT       ! assign attribute values
>               ...
>          NF_ENDDEF           ! end definitions: leave define mode
>               ...
>             NF_PUT_VAR       ! provide values for variable
>               ...
>          NF_CLOSE            ! close: save new netCDF dataset
> 
> QUESTIONS: Where is the code for NF_CREATE and the others shown here?
>            I have not been able to locate it --- fortran, libsrc, any
>            directory.
> 
>           After installation, I am under the impression that my
>           Fortran77 code can call NF_CREATE and the others.  Is this
>           correct?
> 
> If you could find the time to reply, I would appreciate it very much!

Yes, if you run "make test", you will see that a Fortran77 test
program is compiled and run successfully, verifying that the code is
there.  The f77 interface is a thin layer over the C interface.  It's
in the src/fortran/ directory and is implemented in C, along with an
include file "cfortran.h" that encapsulates how to call C functions
from Fortran for a large number of platforms and compilers.

The reason you won't find any files that contain straightforward
source for functions such as NF_CREATE and NF_DEF_DIM is the indirect
way these are implemented, using the C macros defined in the
cfortran.h and ncfortran.h files.  For example, the code for the
NF_CREATE functions gets generated by the following macro call in
fort-control.c:

  /*
   * Create a netCDF dataset.
   */
  FCALLSCFUN3(NF_INT, nc_create, NF_CREATE, nf_create,
              STRING, FINT2CINT, PNCID)

which is used for Fortran functions that call C functions with 3
parameters.  This macro is defined in cfortran.h in terms of
the FCALLSCFUN5 macro:

  #define FCALLSCFUN3( T0,CN,UN,LN,T1,T2,T3) \
          FCALLSCFUN5 (T0,CN,UN,LN,T1,T2,T3,CF_0,CF_0)

which is defined in terms of the FCALLSCFUN10 macro:

  #define FCALLSCFUN5( T0,CN,UN,LN,T1,T2,T3,T4,T5) \
          FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0)

which is defined in terms of the FCALLSCFUN14 macro:

  #define FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
          
FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0)

which is defined in terms of a bunch of other macros:

  #define FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)   
 \
                                   CFextern _(T0,_cfF)(UN,LN)                   
 \
   CFARGT14(NCF,DCF,ABSOFT_cf2(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) 
 \
   {                 CFARGT14S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)   
 \
    _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0)      CN(    TCF(LN,T1,1,0)  
TCF(LN,T2,2,1) \
      TCF(LN,T3,3,1)  TCF(LN,T4,4,1) TCF(LN,T5,5,1)  TCF(LN,T6,6,1)  
TCF(LN,T7,7,1) \
      TCF(LN,T8,8,1)  TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) 
TCF(LN,TC,12,1) \
      TCF(LN,TD,13,1) TCF(LN,TE,14,1) );                          
_Icf(0,K,T0,0,0) \
                     CFARGT14S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)  
_(T0,_cfI) }

which ultimately results in C code that can be called from Fortran to
implement NF_CREATE in terms of nf_create.  But this is all done at
pre-compile time, so there is no run-time cost for this kind of macro
implementation.

All this complexity may seem unnecessary, but it's the best way we've
found to handle calling C from Fortran in a semi-portable way (thanks
to Burkhard D. Steinmacher-Burow, the author of the cfortran.h header
file), since there is no standard yet for the Fortran to C interface.
We're looking forward to Fortran 2003, which is supposed to mandate a
standard for Fortran calling C, eventually making all this nonsense
unnecessary :-).  If you're really interested in the cfortran.h
macros, I recommend:

  http://www-zeus.desy.de/~burow/cfortran/

--Russ