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

[netCDF #UGH-617347]: Trouble reading a 4D NetCDF variable with c++ interface


In the answer I sent, I forgot to say that it's OK to allocate arrays
a row at a time or a slice at a time, if you also make netCDF calls a
row for getting datat into memory or putting it in the file a row at a
time or a slice at a time.  The important thing is that any pointer to
an array must point to a contiguous block of memory in the the values 
will be read or from which the values will be written.

The reason for this restriction is that the method/function called can't
tell how the memory for the array argument was allocated, so can't return 
an error indication, in case the memory for the array is scattered in chunks
all over memory ...


> Sorry to have taken so long to respond to your question.
> > I am hoping you can help me with the following problem:
> >
> > I need to read a NetCDF file whose cdl version is attached to this email
> > (data.cdl). The data.nc file is 1.88 GB of size. I am using the c++
> > interface. I successfully extracted the 1D variables "x", "y", "z", and
> > "time", but the extraction of the 4D variables (e.g. "QN") fails.
> >
> > For instance, suppose I want to extract the "QN" variable, which is a 14 x
> > 2048 x 2048 z-y-x grid, with 1 timestep (record) of data. The code
> > compiles (I am using the Intel C++ Compiler, version 11.0 I believe) and
> > runs fine, but the resulting "qnIn" array has (1) the wrong dimensions,
> > and (2) ill positioned data.
> >
> > I have attached the c++ code (test.cpp) that I wrote for the extraction.
> > Please let me know if you need any other information in order to diagnose
> > the problem. I really appreciate your assistance, and look forward to your
> > response.
> I think the problem is with the statement
> if (!qn -> get(&qnIn[0][0][0],1,ZDIM,YDIM,XDIM)) return NC_ERR;
> where you are trying to read all the data into the qnIn array.  But
> that array is not a set of contiguous values in memory, because it
> was allocated one row at a time:
> /* Allocate dynamically the qnIn array */
> qnIn = new float**[ZDIM];
> for (int j = 0; j < ZDIM; ++j)
> {
> qnIn[j] = new float*[YDIM];
> for (int k = 0; k < YDIM; ++k)
> qnIn[j][k] = new float[XDIM];
> }
> Therefore, the value qnIn[j+1][k] does not necessarily follow
> the value qnIn[j][YDIM-1] in memory, but may be allocated in a
> different part of memory.  You could check this by printing the
> addesses of the rows of the array, and note that there will be
> one or more gaps indicating that the array has been allocated
> memory in non-contiguous blocks.
> It's a requirement of netCDF that arrays used as arguments to netCDF
> calls, except for the C nc_get_varm() and nc_put_varm() calls, are
> contiguous blocks of memory.  I just checked the C++ documentation and
> noted it doesn't make that clear, but it's definitely in the
> language-neutral netCDF Users guide, for example:
> An array section is a "slab" or contiguous rectangular block that is
> specified by two vectors. The index vector gives the indices of the
> element in the corner closest to the origin. The count vector gives
> the lengths of the edges of the slab along each of the variable's
> dimensions, in order. The number of values accessed is the product
> of these edge lengths.
> We've recently had another question indicating we need to make this
> clearer in the documentation, and I will see that that is done before
> the next release.  You can follow the progress of this fix in our bugs
> database, here:
> https://www.unidata.ucar.edu/jira/browse/NCF-69
> Thanks for pointing out the documentation problem!
> --Russ
> Russ Rew                                         UCAR Unidata Program
> address@hidden                      http://www.unidata.ucar.edu

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

Ticket Details
Ticket ID: UGH-617347
Department: Support netCDF
Priority: Critical
Status: Closed

NOTE: All email exchanges with Unidata User Support are recorded in the Unidata inquiry tracking system and then made publicly available through the web. If you do not want to have your interactions made available in this way, you must let us know in each email you send to us.