Merged latest from trunk

This commit is contained in:
Ward Fisher 2013-03-26 16:23:09 +00:00
commit 618f3ea1a5
5 changed files with 146 additions and 15 deletions

View File

@ -8,6 +8,11 @@ VERSION COMMENTS
------- --------
4.3 Released 201?-??-??
Fixed netCDF-4 bug with particular order of
creation of dimensions, coordinate variables, and
subgroups resulting in two dimensions with the same
dimension ID. [NCF-244]
Fixed bug with incorrect fixed-size variable offsets in header
getting written when schema changed for files created
by parallel-netcdf. Thanks to Wei-keng Liao for

View File

@ -317,6 +317,7 @@ int nc4_pg_varm(NC_PG_T pg, NC *nc, int ncid, int varid, const size_t *startp,
const size_t *countp, const ptrdiff_t *stridep,
const ptrdiff_t *imapp, nc_type xtype, int is_long, void *op);
int nc4_rec_match_dimscales(NC_GRP_INFO_T *grp);
int nc4_rec_detect_bad_coord_order(NC_GRP_INFO_T *grp, int *bad_coord_orderp);
int nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order);
int nc4_rec_write_types(NC_GRP_INFO_T *grp);
int nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5);

View File

@ -2964,6 +2964,8 @@ sync_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
int bad_coord_order = 0; /* if detected, propagate to all groups to consistently store dimids */
if ((retval = nc4_rec_write_types(h5->root_grp)))
return retval;
if ((retval = nc4_rec_detect_bad_coord_order(h5->root_grp, &bad_coord_order)))
return retval;
if ((retval = nc4_rec_write_metadata(h5->root_grp, bad_coord_order)))
return retval;
}

View File

@ -2425,26 +2425,18 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, int write_dimid)
return retval;
}
/* Recursively write all the metadata in a group. Groups and types
* have all already been written. Propagate bad cooordinate order to
* subgroups, if detected. */
/* Recursively determine if there is a mismatch between order of
* coordinate creation and associated dimensions in this group or any
* subgroups, to find out if we have to handle that situation. */
int
nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
nc4_rec_detect_bad_coord_order(NC_GRP_INFO_T *grp, int *bad_coord_orderp)
{
NC_DIM_INFO_T *dim;
NC_VAR_INFO_T *var;
NC_GRP_INFO_T *child_grp;
int found_coord, coord_varid = -1, wrote_coord;
int last_dimid = -1;
int retval;
assert(grp && grp->name && grp->hdf_grpid);
LOG((3, "nc4_rec_write_metadata: grp->name %s, bad_coord_order %d", grp->name, bad_coord_order));
/* Write global attributes for this group. */
if ((retval = write_attlist(grp->att, NC_GLOBAL, grp)))
return retval;
/* If the user writes coord vars in a different order then he
* defined their dimensions, then, when the file is reopened, the
* order of the dimids will change to match the order of the coord
@ -2456,8 +2448,8 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
{
if (var->dimids[0] < last_dimid)
{
bad_coord_order++;
break;
*bad_coord_orderp = 1;
return NC_NOERR;
}
last_dimid = var->dimids[0];
}
@ -2472,9 +2464,39 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
if (!strcmp(dim->name, var->name) && !dim->dirty)
{
LOG((5, "coord var defined after enddef/redef"));
bad_coord_order++;
*bad_coord_orderp = 1;
return NC_NOERR;
}
/* If there are any child groups, check them also for this condition. */
for (child_grp = grp->children; child_grp; child_grp = child_grp->next)
if ((retval = nc4_rec_detect_bad_coord_order(child_grp, bad_coord_orderp)))
return retval;
return NC_NOERR;
}
/* Recursively write all the metadata in a group. Groups and types
* have all already been written. Propagate bad cooordinate order to
* subgroups, if detected. */
int
nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
{
NC_DIM_INFO_T *dim;
NC_VAR_INFO_T *var;
NC_GRP_INFO_T *child_grp;
int found_coord, coord_varid = -1, wrote_coord;
int last_dimid = -1;
int retval;
assert(grp && grp->name && grp->hdf_grpid);
LOG((3, "nc4_rec_write_metadata: grp->name %s, bad_coord_order %d", grp->name, bad_coord_order));
/* Write global attributes for this group. */
if ((retval = write_attlist(grp->att, NC_GLOBAL, grp)))
return retval;
/* For some stupid reason, the dim list is stored backwards! Get to
* the back of the list. */

View File

@ -20,10 +20,18 @@ nc_set_log_level(0);
#define FILE_NAME "tst_dims3.nc"
#define RANK_time 1
#define GRP_NAME "G"
#define GRP2_NAME "G2"
#define TIME_NAME "time"
#define VAR2_NAME "z"
#define TIME_RANK 1
#define NUM_TIMES 2
#define LEV_NAME "level"
#define VRT_NAME "vert_number"
#define LEV_NUM 3
#define LEV_RANK 1
#define VRT_RANK 1
#define VAR2_RANK 2
#define NUM_VRT 3
int ncid, grpid;
int time_dim, time_dim_in;
int time_var, z_var;
@ -97,5 +105,98 @@ nc_set_log_level(0);
ERR_RET;
}
SUMMARIZE_ERR;
printf("*** testing defining dimensions and coord variables in different orders in root group...");
{
int ncid, grpid, grp2id;
int time_dimid, lev_dimid, vrt_dimid, g2lev_dimid, g2vrt_dimid;
int time_dimid_in, lev_dimid_in, vrt_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
int time_varid, lev_varid, gvar2_varid, g2lev_varid, g2vrt_varid;
int var2_dims[VAR2_RANK];
/* Create test for fix of bug that resulted in two dimensions
* having the same dimid, which violates the Pauli exclusion
* principle for dimensions. */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR_RET;
if (nc_def_grp(ncid, GRP_NAME, &grpid)) ERR;
if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dimid)) ERR_RET;
if (nc_def_dim(ncid, LEV_NAME, LEV_NUM, &lev_dimid)) ERR_RET;
var2_dims[0] = time_dimid;
var2_dims[1] = lev_dimid;
if (nc_def_var(grpid, VAR2_NAME, NC_FLOAT, VAR2_RANK, var2_dims, &gvar2_varid)) ERR;
/* define coord vars in opposite order of coord dims */
if (nc_def_var(ncid, LEV_NAME, NC_FLOAT, LEV_RANK, &lev_dimid, &lev_varid)) ERR;
if (nc_def_var(ncid, TIME_NAME, NC_FLOAT, TIME_RANK, &time_dimid, &time_varid)) ERR;
if (nc_def_grp(ncid, GRP2_NAME, &grp2id)) ERR;
if (nc_def_dim(grp2id, LEV_NAME, LEV_NUM, &g2lev_dimid)) ERR_RET;
if (nc_def_dim(grp2id, VRT_NAME, NUM_VRT, &g2vrt_dimid)) ERR_RET;
if (nc_def_var(grp2id, LEV_NAME, NC_FLOAT, LEV_RANK, &g2lev_dimid, &g2lev_varid)) ERR;
if (nc_def_var(grp2id, VRT_NAME, NC_FLOAT, VRT_RANK, &g2vrt_dimid, &g2vrt_varid)) ERR;
if (nc_close(ncid)) ERR;
/* Re-open, in which dimids may get reassigned */
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
if (nc_inq_dimid(ncid, TIME_NAME, &time_dimid_in)) ERR;
if (nc_inq_dimid(ncid, LEV_NAME, &lev_dimid_in)) ERR;
if (nc_inq_ncid(ncid, GRP2_NAME, &grp2id)) ERR;
if (nc_inq_dimid(grp2id, LEV_NAME, &g2lev_dimid_in)) ERR;
if (nc_inq_dimid(grp2id, VRT_NAME, &g2vrt_dimid_in)) ERR;
/* dimids must still all be distinct */
if (time_dimid_in == lev_dimid_in ||
time_dimid_in == g2lev_dimid_in ||
time_dimid_in == g2vrt_dimid_in ||
lev_dimid_in == g2lev_dimid_in ||
lev_dimid_in == g2vrt_dimid_in ||
g2lev_dimid_in == g2vrt_dimid_in) ERR;
if (nc_close(ncid))
ERR_RET;
}
SUMMARIZE_ERR;
printf("*** testing defining dimensions and coord variables in different orders in subgroup...");
{
int ncid, grpid, grp2id;
int time_dimid, lev_dimid, vrt_dimid, g2lev_dimid, g2vrt_dimid;
int time_dimid_in, lev_dimid_in, vrt_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
int time_varid, lev_varid, gvar2_varid, g2lev_varid, g2vrt_varid;
int var2_dims[VAR2_RANK];
/* Create test for fix of bug inside a subgroup that results in two dimensions
* having the same dimid. */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR_RET;
if (nc_def_grp(ncid, GRP_NAME, &grpid)) ERR;
if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dimid)) ERR_RET;
if (nc_def_dim(ncid, LEV_NAME, LEV_NUM, &lev_dimid)) ERR_RET;
var2_dims[0] = time_dimid;
var2_dims[1] = lev_dimid;
if (nc_def_var(grpid, VAR2_NAME, NC_FLOAT, VAR2_RANK, var2_dims, &gvar2_varid)) ERR;
if (nc_def_var(ncid, TIME_NAME, NC_FLOAT, TIME_RANK, &time_dimid, &time_varid)) ERR;
if (nc_def_var(ncid, LEV_NAME, NC_FLOAT, LEV_RANK, &lev_dimid, &lev_varid)) ERR;
if (nc_def_grp(ncid, GRP2_NAME, &grp2id)) ERR;
if (nc_def_dim(grp2id, LEV_NAME, LEV_NUM, &g2lev_dimid)) ERR_RET;
if (nc_def_dim(grp2id, VRT_NAME, NUM_VRT, &g2vrt_dimid)) ERR_RET;
/* define coord vars in opposite order of coord dims */
if (nc_def_var(grp2id, VRT_NAME, NC_FLOAT, VRT_RANK, &g2vrt_dimid, &g2vrt_varid)) ERR;
if (nc_def_var(grp2id, LEV_NAME, NC_FLOAT, LEV_RANK, &g2lev_dimid, &g2lev_varid)) ERR;
if (nc_close(ncid)) ERR;
/* Re-open, in which dimids may get reassigned */
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
if (nc_inq_dimid(ncid, TIME_NAME, &time_dimid_in)) ERR;
if (nc_inq_dimid(ncid, LEV_NAME, &lev_dimid_in)) ERR;
if (nc_inq_ncid(ncid, GRP2_NAME, &grp2id)) ERR;
if (nc_inq_dimid(grp2id, LEV_NAME, &g2lev_dimid_in)) ERR;
if (nc_inq_dimid(grp2id, VRT_NAME, &g2vrt_dimid_in)) ERR;
/* dimids must still all be distinct */
if (time_dimid_in == lev_dimid_in ||
time_dimid_in == g2lev_dimid_in ||
time_dimid_in == g2vrt_dimid_in ||
lev_dimid_in == g2lev_dimid_in ||
lev_dimid_in == g2vrt_dimid_in ||
g2lev_dimid_in == g2vrt_dimid_in) ERR;
if (nc_close(ncid))
ERR_RET;
}
SUMMARIZE_ERR;
FINAL_RESULTS;
}