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

Re: 19990503: nc_put_varm_* usage



Andrei,

> To: address@hidden
> From: Andrei Fedorov <address@hidden>
> Subject: nc_put_varm_* usage
> Organization: Space Research Institute, Moscow, Russia
> Keywords: 199905031327.HAA28192

In the above message, you wrote:

> Please, could you clarify usage of nc_put_varm_* function?
> 
> I met the problem while I was converting my NetCDF 2.3 programs
> to last 3.4 version. In my code I extract double value "location"
> from array of structures
> 
>      typedef struct {
>                     short brick_n;  
>                     double location;
>                  } solid_t;
> 
> to write it into NetCDF file.
> 
> Previously I used ncvarputg with IMAP as follows
>    long imap[1]  = {(long)sizeof(solid_t)};
> 
> Now it is impossible.
> 
> I have tried to use  nc_put_varm_double with
>        
>       ptrdiff_t imap[1]  = {(ptrdiff_t)(sizeof(solid_t) /  sizeof(double))};
> 
> BUT of course, it works on 64 bits (DEC alpha) platform and does not
> work on 32 bits  (IBM R6000) platform.
> 
> Could you point me the right way?
> 
> Thank you in advance
>    Anderi Fedorov, Space Research Institute, Moscow, Russia

When we created the netCDF 3 package, we decided to change the "imap"
vector from a data-dependent one to a data-independent one (i.e. the
memory strides would change from units of bytes to units in the natural
length of the individual elements). At the time, all systems used
natural alignment for structure members, so we assumed this wouldn't
cause any problems.

It looks like you discovered a new system that breaks that assumption.

There might be a workaround.  The "-qalign=natural" option to the C
compiler will cause structure members to be aligned on their natural
boundaries.  You can see this with the following test program:

    $ cat a.c
    #include <stdio.h>
    #include <stddef.h>
    void main() {
        typedef struct {
            short brick_n;
            double location;
        } solid_t;
        printf("sizeof(solid_t) = %d\n", sizeof(solid_t));
        printf("offsetof(solid_t, location) = %d\n",
            offsetof(solid_t, location));
        printf("sizeof(solid_t)/sizeof(double) = %ld\n", 
            sizeof(solid_t)/sizeof(double));
    }
    $ /bin/cc a.c
    $ ./a.out
    sizeof(solid_t) = 12
    offsetof(solid_t, location) = 4             <<< bad!
    sizeof(solid_t)/sizeof(double) = 1          <<< bad!
    $ /bin/cc -qalign=natural a.c
    $ ./a.out
    sizeof(solid_t) = 16
    offsetof(solid_t, location) = 8             <<< good
    sizeof(solid_t)/sizeof(double) = 2          <<< good

Using the "-qalign=natural" option might also result in better program
performance due to the natural alignment of the data elements.

Please try this option and let me know if it solves your problem.

--------
Steve Emmerson   <http://www.unidata.ucar.edu>