Re: [netcdfgroup] offsets are ignored when creating compound types

Hi Russ,

Thanks for your reply. Unfortunately it is not working for me:

First, when I inspect the file fb.c that ncgen creates, I find the following
declaration at the very top:

typedef struct mystruct_t {
    signed char field1;
    int field2;
    float field3;
} mystruct_t;

In other words, it is in fact declaring the struct. To generate a C file and
compile it and run it behind the scenes is certainly a workaround to my
problem but it is not the sort of solution that I was looking for :o)

Even so, when I comment the line that inserts the field2 member, as follows:

stat = nc_def_compound(root_grp, sizeof(mystruct_t), "mystruct_t",
&mystruct_t_typ);
check_err(stat,__LINE__,__FILE__);
{
    stat = nc_insert_compound(root_grp, mystruct_t_typ, "field1",
NC_COMPOUND_OFFSET(mystruct_t,field1), NC_BYTE);
    check_err(stat,__LINE__,__FILE__);
    /*    stat = nc_insert_compound(root_grp, mystruct_t_typ, "field2",
NC_COMPOUND_OFFSET(mystruct_t,field2), NC_INT); */
    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_compound(root_grp, mystruct_t_typ, "field3",
NC_COMPOUND_OFFSET(mystruct_t,field3), NC_FLOAT);
    check_err(stat,__LINE__,__FILE__);
}

The result is incorrect:

$ ncdump fb.nc
netcdf fb {
types:
  compound mystruct_t {
    byte field1 ;
    float field3 ;
  }; // mystruct_t
variables:
    mystruct_t cvar ;
data:

 cvar = {123, 1.471363e-43} ;
}

FYI, I am using netcdf library version 4.0.1 on CentOS 64 bits.

I puzzled about one thing: if NetCDF ignores the offsets that I pass it, why
do I have to provide them in the first place? What use do they have?

Felipe

On Wed, Nov 18, 2009 at 6:00 PM, Russ Rew <russ@xxxxxxxxxxxxxxxx> wrote:

> Hi Felipe,
>
> > I have found out that NetCDF-4 ignores the offsets that the users
> specifies
> > when creating compound types. Instead, I think it calculates the offsets
> > taking into account the architecture alignment rules.
> >
> > So it is not possible for example to create a compound offset without
> > defining a "struct" in your C program. My problem is that I need to write
> a
> > program that is able to create arbitrary compound objects.
>
> It *is* possible to create a compound offset without defining a struct
> in your C program.  For example, ncgen uses CDL input describing a
> compound type to generate a corresponding netCDF file at run time,
> without a corresponding struct.  Also the new nccopy utility uses only
> the netCDF C API to structurally copy netCDF files, so when it copies a
> netCDF-4 file with a compound type, it must create the necessary type in
> the target file without having a corresponding C struct.
>
> As an example, consider the following CDL file, fb.cdl:
>
>  netcdf fb {
>  types:
>    compound mystruct_t {
>      byte field1;
>      int field2;
>      float field3;
>    }; // mystruct_t
>  variables:
>    mystruct_t cvar;
>  data:
>    cvar = {123, 0, 45.67};
>  }
>
> If you use the ncgen in the current snapshot release (previously named
> ncgen4 in the 4.0.1 release), it creates the corresponding netCDF file,
> as ncdump verifies:
>
>  $ ncgen -k 3 -b fb.cdl
>  $ ncdump fb.nc
>  netcdf fb {
>  types:
>    compound mystruct_t {
>      byte field1 ;
>      int field2 ;
>      float field3 ;
>    }; // mystruct_t
>  variables:
>          mystruct_t cvar ;
>  data:
>
>   cvar = {123, 0, 45.67} ;
>  }
>
> Furthermore, you can use ncgen to generate a corresponding C program,
> compile and run it, and you will still get the same netCDF file.  The
> generated C program does use a C struct for simplicity.
>
>  $ ncgen -k 3 -lc fb.cdl > fb.c
>  $ cc `nc-config --cflags` fb.c -o fb `nc-config --libs`
>  $ ./fb
>  $ ncdump fb.nc
>  [ ... same result as above]
>
> > Another thing that is not possible is to create a compound type that is
> an
> > extract (a subset) of a larger struct. In the following simplified
> example,
> > I have a struct with 3 fields, but I want to write to disk only the 1st
> and
> > the 3rd fields:
> >
> > ////////////////////////////
> >
> > struct mystruct {
> >     char field1;
> >     int field2;
> >     float field3;
> > };
> > struct mystruct myvar;
> > myvar.field1=123;
> > myvar.field3=45.67;
> >
> > nc_def_compound(ncid, sizeof(struct mystruct), "MYSTRUCTEXTRACT",
> &typeid);
> > nc_insert_compound(ncid, typeid, "FIELD1", 0, NC_BYTE)==0);
> > nc_insert_compound(ncid, typeid, "FIELD3", NC_COMPOUND_OFFSET(struct
> > mystruct, field3), NC_FLOAT);
> >
> > nc_def_var(ncid, "CVAR", typeid, 0, NULL, &varid);
> > nc_put_var(ncid, varid, &myvar);
> >
> > ////////////////////////////
> >
> > The file that I create does not contain the right value for "FIELD3", and
> I
> > think the reason is that the library is ignoring the offset that I am
> > supplying.
>
> If you edit the generated C program, fb.c, and comment out the line
> inserting the "field2" member, it still works, and when run shows a
> compound type with only the first and third field and the correct value
> for the field3 member:
>
>  netcdf fb {
>  types:
>    compound mystruct_t {
>      byte field1 ;
>      float field3 ;
>    }; // mystruct_t
>  variables:
>          mystruct_t cvar ;
>  data:
>
>   cvar = {123, 45.67} ;
>  }
>
> It's possible that the different results you are seeing are from bugs in
> an earlier version or indicate a new platform-specific bug we haven't
> seen, but we can't reproduce the problem here.
>
> --Russ
>



-- 
Mission and Data Systems Division
Deimos Space, SLU
http://www.deimos-space.com
Ph. +34 91.806.3450 Ext. 124
  • 2009 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: