PnetCDF Fortran Binding Issues

Jianwei Li jianwei at cheetah.cpdc.ece.nwu.edu
Thu Aug 7 13:00:30 CDT 2003


Bill,

I've identified those functions & arguments that need such F-C conversion
in the attached txt file. They are C functions that the Fortran binding
functions are calling, and F-C conversion should be done before calling
the C interface functions.

I have following assumptions:
1. Fortran interface requires users to define their multi-dimension arrays
   in a reverse numerical dimension order than their target netCDF array
   variables (which are stored in row-major/C order);
2. Fortran users specify 1-based indices for array element coordinates
   when they call those data access functions;
3. Dimension ID follows 0-based convention, as all other internal IDs do.

Assumption 1&2 are specified in Original netCDF Fortran Interface user
guide and confirmed in the src code.
Assumption 3, however, is not confirmed in the original netCDF src code;
instead, the original one seems to try putting it 1-based. But I don't
find any reason to do that way, since all other internal IDs (ncid,
varid, attrid, ...) are 0-based, and as long as they are for internal
references, they can be kept 0-based, which will save a lot of function
modifications. And, what's strange is that I didn't find any code
converting between 0-based and 1-based dimids in the original netCDF,
except in the definition/inquiry of dimension list for the array varible.
If they didn't take care of it for other single dimention definitions
and inquiries, that'll be a big bug in their code //Yet I didn't find
anyone report such a failure... hmm, maybe they hid it some where else?

Anyway, we should try solve the F-C conversion problem in one way and
test it.

Jianwei

On Wed, 6 Aug 2003, William Gropp wrote:

> At 01:21 PM 8/4/2003 -0500, Jianwei Li wrote:
>
> >Bill,
> >
> >I took a look at the original netCDF library User Guide and the src code,
> >The index in C interface is 0-based and that in Fortran is 1-based.
> >
> >There is functions converting FORTRAN co-ordinates into C co-ordinates.
> >
> >     for (i = 0; i < ndims; ++i)
> >         ccoords[i] = fcoords[ndims - 1 - i] - 1;
> >
> >The dimension-ID vector, count, stride are also converted in such a way.
> >So, now I'm sure the original netCDF requires that Fortran users define
> >their array variables in a reverse dimension order than if C code is used.
> >In users' view, if we talk about most/least significant dimension instead
> >of the numerical order, Fortran interface and C interface look common.
> >Within the Fortran binding, however, it reverses all dimension-related
> >index vectors before calling the C functions, and it also converts between
> >0-based and 1-based indices.
> >That way, the data buffer of the array variables don't need to be
> >transposed in the Fortran binding implementation.
> >
> >So, I think, all we need to do in the Fortran binding is to implement the
> >same index vector convertion for those involved functions --- convert
> >from F to C for input index vectors, and from C to F for output ones.
> >
> >I can list those function and their victim arguments, if that helps.
>
> That would be a big help.  This might also change the size_t handling.
>
> Bill
>
-------------- next part --------------
int ncmpi_def_var(int ncid, const char *name, nc_type xtype, 
              int ndims, const int *dimidsp, int *varidp);
				   ^ IN

int ncmpi_inq_var(int ncid, int varid, char *name,
              nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp);
						^ OUT

int ncmpi_inq_vardimid(int ncid, int varid, int *dimidsp);
						^ OUT

All ABOVE functions have victim OUTPUT/INPUT arguments: *dimidsp
that need to be converted from C to Fortran (for OUTPUT arguments) or
from Fortran to C (for INPUT arguments) in such ways as:
################### For OUTPUT *dimidsp ##################
NF_INTEGER*
c2f_dimids(int ncid, int varid, const int* cdimids, NF_INTEGER* fdimids)
{
    int i;
    int ndims;

    if (nc_inq_varndims(ncid, varid, &ndims) != 0)
        return NULL;

    for (i = 0; i < ndims; ++i)
        fdimids[ndims - 1 - i] = cdimids[i];

    return fdimids;
}
##########################################################

################### For INPUT *dimidsp ###################
int*
f2c_dimids(int ndims, const NF_INTEGER* fdimids, int* cdimids)
{
    int i;

    for (i = 0; i < ndims; ++i)
        cdimids[i] = fdimids[ndims - 1 - i];

    return cdimids;
}
##########################################################






All FOLLOWING functions have victim INPUT arguments:
	index[]/start[], count[], stride[]
that need to be converted from Fortran to C in the fortran binding
in such ways as:
################## For index[]/start[] ##################
size_t*
f2c_coords(int ncid, int varid, const NF_INTEGER* fcoords,
    size_t* ccoords)
{
    int i;
    int ndims;

    if (nc_inq_varndims(ncid, varid, &ndims) != 0)
        return NULL;

    for (i = 0; i < ndims; ++i)
        ccoords[i] = fcoords[ndims - 1 - i] - 1;

    return ccoords;
}
##########################################################

################# For count[], stride[] ##################
size_t*
f2c_counts(int ncid, int varid, const NF_INTEGER* fcounts,
    size_t* ccounts)
{
    int i;
    int ndims;

    if (nc_inq_varndims(ncid, varid, &ndims) != 0)
        return NULL;

    for (i = 0; i < ndims; ++i)
        ccounts[i] = fcounts[ndims - 1 - i];

    return ccounts;
}

size_t*
f2c_strides(int ncid, int varid, const NF_INTEGER* fstrides,
    size_t* cstrides)
{
    int i;
    int ndims;

    if (nc_inq_varndims(ncid, varid, &ndims) != 0)
        return NULL;

    for (i = 0; i < ndims; ++i)
        cstrides[i] = fstrides[ndims - 1 - i];

    return cstrides;
}
############################################################

int ncmpi_put_var1(int ncid, int varid,
               const size_t index[],
               const void *buf, int bufcount,
               MPI_Datatype datatype);
int ncmpi_get_var1(int ncid, int varid,
               const size_t index[],
               void *buf, int bufcount,
               MPI_Datatype datatype);
int ncmpi_put_var1_text(int ncid, int varid,
                    const size_t index[],
                    const char *op);
int ncmpi_put_var1_short(int ncid, int varid,
                     const size_t index[],
                     const short *op);
int ncmpi_put_var1_int(int ncid, int varid,
                   const size_t index[],
                   const int *op);
int ncmpi_put_var1_float(int ncid, int varid,
                     const size_t index[],
                     const float *op);
int ncmpi_put_var1_double(int ncid, int varid,
                      const size_t index[],
                      const double *op);
int ncmpi_get_var1_text(int ncid, int varid,
                    const size_t index[],
                    char *ip);
int ncmpi_get_var1_short(int ncid, int varid,
                     const size_t index[],
                     short *ip);
int ncmpi_get_var1_int(int ncid, int varid,
                   const size_t index[],
                   int *ip);
int ncmpi_get_var1_float(int ncid, int varid,
                     const size_t index[],
                     float *ip);
int ncmpi_get_var1_double(int ncid, int varid,
                      const size_t index[],
                      double *ip);

int ncmpi_put_vara_all(int ncid, int varid,
                   const size_t start[], const size_t count[],
                   const void *buf, int bufcount,
                   MPI_Datatype datatype);
int ncmpi_get_vara_all(int ncid, int varid,
                   const size_t start[], const size_t count[],
                   void *buf, int bufcount,
                   MPI_Datatype datatype);
int ncmpi_put_vara(int ncid, int varid,
               const size_t start[], const size_t count[],
               const void *buf, int bufcount,
               MPI_Datatype datatype);
int ncmpi_get_vara(int ncid, int varid,
               const size_t start[], const size_t count[],
               void *buf, int bufcount,
               MPI_Datatype datatype);
int ncmpi_put_vara_text_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    const char *op);
int ncmpi_put_vara_text(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    const char *op);
int ncmpi_put_vara_short_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    const short *op);
int ncmpi_put_vara_short(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    const short *op);
int ncmpi_put_vara_int_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    const int *op);
int ncmpi_put_vara_int(int ncid, int varid,
                const size_t start[], const size_t count[],
                const int *op);
int ncmpi_put_vara_float_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    const float *op);
int ncmpi_put_vara_float(int ncid, int varid,
                const size_t start[], const size_t count[],
                const float *op);
int ncmpi_put_vara_double_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    const double *op);
int ncmpi_put_vara_double(int ncid, int varid,
                const size_t start[], const size_t count[],
                const double *op);
int ncmpi_get_vara_text_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    char *ip);
int ncmpi_get_vara_text(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    char *ip);
int ncmpi_get_vara_short_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    short *ip);
int ncmpi_get_vara_short(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    short *ip);
int ncmpi_get_vara_int_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    int *ip);
int ncmpi_get_vara_int(int ncid, int varid,
                const size_t start[], const size_t count[],
                int *ip);
int ncmpi_get_vara_float_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    float *ip);
int ncmpi_get_vara_float(int ncid, int varid,
                const size_t start[], const size_t count[],
                float *ip);
int ncmpi_get_vara_double_all(int ncid, int varid,
                    const size_t start[], const size_t count[],
                    double *ip);
int ncmpi_get_vara_double(int ncid, int varid,
                const size_t start[], const size_t count[],
                double *ip);


int ncmpi_put_vars_all(int ncid, int varid,
                   const size_t start[],
                   const size_t count[],
                   const size_t stride[],
                   const void *buf, int bufcount,
                   MPI_Datatype datatype);
int ncmpi_get_vars_all(int ncid, int varid,
                   const size_t start[],
                   const size_t count[],
                   const size_t stride[],
                   void *buf, int bufcount,
                   MPI_Datatype datatype);
int ncmpi_put_vars(int ncid, int varid,
               const size_t start[],
               const size_t count[],
               const size_t stride[],
               const void *buf, int bufcount,
               MPI_Datatype datatype);
int ncmpi_get_vars(int ncid, int varid,
               const size_t start[],
               const size_t count[],
               const size_t stride[],
               void *buf, int bufcount,
               MPI_Datatype datatype);
int ncmpi_put_vars_text_all(int ncid, int varid,
                        const size_t start[],
                        const size_t count[],
                        const size_t stride[],
                        const char *op);
int ncmpi_put_vars_text(int ncid, int varid,
                    const size_t start[],
                    const size_t count[],
                    const size_t stride[],
                    const char *op);
int ncmpi_put_vars_short_all(int ncid, int varid,
                         const size_t start[],
                         const size_t count[],
                         const size_t stride[],
                         const short *op);
int ncmpi_put_vars_short(int ncid, int varid,
                     const size_t start[],
                     const size_t count[],
                     const size_t stride[],
                     const short *op);
int ncmpi_put_vars_int_all(int ncid, int varid,
                       const size_t start[],
                       const size_t count[],
                       const size_t stride[],
                       const int *op);
int ncmpi_put_vars_int(int ncid, int varid,
                   const size_t start[],
                   const size_t count[],
                   const size_t stride[],
                   const int *op);
int ncmpi_put_vars_float_all(int ncid, int varid,
                         const size_t start[],
                         const size_t count[],
                         const size_t stride[],
                         const float *op);
int ncmpi_put_vars_float(int ncid, int varid,
                     const size_t start[],
                     const size_t count[],
                     const size_t stride[],
                     const float *op);
int ncmpi_put_vars_double_all(int ncid, int varid,
                          const size_t start[],
                          const size_t count[],
                          const size_t stride[],
                          const double *op);
int ncmpi_put_vars_double(int ncid, int varid,
                      const size_t start[],
                      const size_t count[],
                      const size_t stride[],
                      const double *op);
int ncmpi_get_vars_text_all(int ncid, int varid,
                        const size_t start[],
                        const size_t count[],
                        const size_t stride[],
                        char *ip);
int ncmpi_get_vars_text(int ncid, int varid,
                    const size_t start[],
                    const size_t count[],
                    const size_t stride[],
                    char *ip);
int ncmpi_get_vars_short_all(int ncid, int varid,
                         const size_t start[],
                         const size_t count[],
                         const size_t stride[],
                         short *ip);
int ncmpi_get_vars_short(int ncid, int varid,
                     const size_t start[],
                     const size_t count[],
                     const size_t stride[],
                     short *ip);
int ncmpi_get_vars_int_all(int ncid, int varid,
                       const size_t start[],
                       const size_t count[],
                       const size_t stride[],
                       int *ip);
int ncmpi_get_vars_int(int ncid, int varid,
                   const size_t start[],
                   const size_t count[],
                   const size_t stride[],
                   int *ip);
int ncmpi_get_vars_float_all(int ncid, int varid,
                         const size_t start[],
                         const size_t count[],
                         const size_t stride[],
                         float *ip);
int ncmpi_get_vars_float(int ncid, int varid,
                     const size_t start[],
                     const size_t count[],
                     const size_t stride[],
                     float *ip);
int ncmpi_get_vars_double_all(int ncid, int varid,
                          const size_t start[],
                          const size_t count[],
                          const size_t stride[],
                          double *ip);
int ncmpi_get_vars_double(int ncid, int varid,
                      const size_t start[],
                      const size_t count[],
                      const size_t stride[],
                      double *ip);


More information about the parallel-netcdf mailing list