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