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

[netCDF #PFU-753378]: Error in closing netCDF file (due to presence of user-defined type)



Lynton,

> Thanks for the reply. In fact the "feature" you picked up was a genuine
> mistake of mine
> when translating from the C++ API to the C API. The real problem was
> somewhat different
> as I will explain. The programme I attach is the same as before but with
> the user-type error corrected
> and some data assigned to the variable "weightDDXXYY"
> 
> I can compile the code fine and run it fine.
> 
> However, when I run ncdump I get problems. In this case the output is
> wrong, but in other cases ncdump can actually crash.
> The error appears to be associated with assigning values to the variable
> "ironBoundaries" on line 44 of efit++.cpp.
> This causes the dimensioning of weightDDXXYY to be screwed up, at least
> according to ncdump.
> However h5dump appears not to have the same problem suggesting that
> there is a problem in ncdump !!
> 
> To see this for yourself, compare the files efitOut.txt (ncdump output)
> and efitOut.hdf5.txt (h5Dump output).
> You will see that the dimensioning of weightDDXXYY is apparently different.
> 
> Note as I said before, this is using netCDF version 4.2

OK, now I can reproduce the bug.  It appears to be an example of the bug that 
depends
on the order in which netCDF functions are called, but the results should not 
depend on
the order.

I'm attaching a version of your program that works when I reorder the function 
calls to 
appear in the following groups of calls:

  create file and groups
  define types
  define dimensions
  define variables
  write data

and it works as expected.  I don't know if there's a simpler permutation of 
statement orders
that would also work.

The fact that it doesn't work in the order you used is definitely a major bug.  
I'm also creating a Jira ticket for this and will consider it a priority to try
to diagnose the underlying problem and fix it.

--Russ

> On 01/24/2013 01:46 PM, Unidata netCDF Support wrote:
> > Hi Lynton,
> >
> >> I have a short programme that throws up an HDF5 error: NC_EHDFERR  when 
> >> closing. It appears to be connected with defining a user-defined type:
> >> Have  you got any idea what the problem is?
> >>
> >>
> >> The output of the code is:
> >> 0 1
> >> 0 2
> >> 0 3
> >> 0 4
> >> 0 5
> >> 0 6
> >> 0 7
> >> 0 9
> >> 0 10
> >> -101 11
> > It looks to me as if you started to define a netCDF user-defined type
> > named "ironBoundaryType", but didn't finish that definition.  Then you
> > tried to define netCDF variables of the incompletely defined type.
> > It's a bug that the netCDF API lets you do this without returning an
> > error until you close the file.  I'm not sure whether there's also a
> > corresponding bug in HDF5 that allows this.
> >
> > To complete the definition of the user-defined type, you need to fill
> > out the type with repeated calls to nc_insert_compound(). Call the
> > nc_insert_compound function once for each field (member) you wish to
> > insert into the compound type.  Don't define variables using a type
> > until you finish defining the type.
> >
> > I'll enter a Jira ticket for this later and try to determine where the bug
> > is, but it may have to wait until after we get the 4.3 release for the C
> > library out ...
> >
> > --Russ

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



Ticket Details
===================
Ticket ID: PFU-753378
Department: Support netCDF
Priority: Normal
Status: Closed
#include  <string>
#include  <iostream>
#include  <netcdf.h>

using namespace std;


int main(int argc, char* argv[])
{
  int fileId,timeDimId,ironModelId,segmentDimId,ironBoundaryDimId;  
  nc_type ironBoundaryTypeId;

  // Create file and groups
  cout << nc_create("efixOut.nc", NC_NETCDF4 | NC_CLOBBER, &fileId) << " 1 " << 
endl;
  cout << nc_def_grp(fileId,"ironModel",&ironModelId) << " 3 " << endl;

  // Create types
  struct s1
  {
    int materialId;
  };
  size_t typeSize=sizeof(struct s1);
  cout << nc_def_compound(fileId, 
typeSize,"ironBoundaryType",&ironBoundaryTypeId) << " 5 " << endl;
  cout << 
nc_insert_compound(fileId,ironBoundaryTypeId,"materialId",offsetof(s1,materialId),NC_INT)
 << " 6 " << endl;

  // Create dimensions
  size_t dimSize=2;
  cout << nc_def_dim(fileId,"time",dimSize,&timeDimId) << " 2 " << endl;
  size_t segmentCount =3;
  cout << nc_def_dim(ironModelId,"segmentDim",segmentCount,&segmentDimId) << " 
4 " << endl;
  dimSize=1;  
  cout <<nc_def_dim(ironModelId,"ironBoundaryDim",dimSize,&ironBoundaryDimId) 
<< " 7 " << endl;
  int varId,dimIds,ndims;
  nc_type myId;
  myId=NC_DOUBLE;
  dimIds=timeDimId;
  cout <<nc_def_var(fileId,"weightCCXXYY",myId,ndims,&dimIds,&varId) << " 10 " 
<< endl;
  int weightCCXXYYId = varId;
  ndims=1;
  myId=ironBoundaryTypeId;
  dimIds=ironBoundaryDimId;
  cout << nc_def_var(ironModelId,"ironBoundaries",myId,ndims,&dimIds,&varId) << 
" 8 " << endl;
  int ironBoundariesId = varId;
  myId=NC_DOUBLE;
  dimIds=timeDimId;
  cout << nc_def_var(ironModelId,"weightDDXXYY",myId,ndims,&dimIds,&varId) << " 
11 " << endl;
  int weightDDXXYY = varId;

  // Create variables
  s1 bufferStruct;
  bufferStruct.materialId=10;
  size_t index=0;
  varId = ironBoundariesId;
  cout <<  nc_put_var1(ironModelId, varId,&index,(const void*) &bufferStruct) 
<< " 9 " << endl;

  // Write data
  const double timeVar[] = {1.3, 4.6 };
  varId = weightDDXXYY;
  cout <<  nc_put_var_double(ironModelId, varId,timeVar) << " 12 " << endl;
  //  NcVar ironBoundariesVar = NcVar(ironModelGroup,varId);
  //  NcVar  
weightVarXXYY(defineNetCdfVar(ncFile,"weightCCXXYY",NcType::nc_DOUBLE,timeDim));
  //  NcVar  
weightVarDDXXYY(defineNetCdfVar(ironModelGroup,"weightDDXXYY",NcType::nc_DOUBLE,timeDim));
  cout << nc_close(fileId) << " 13 " << endl;
  return 0;
}