mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-02-17 16:50:18 +08:00
Fix jira NCF-249
This commit is contained in:
parent
e960416761
commit
7e8bfb01f3
@ -433,17 +433,25 @@ buildcdftree34r(NCDAPCOMMON* nccomm, OCddsnode ocnode, CDFnode* container,
|
||||
{
|
||||
size_t i,ocrank,ocnsubnodes;
|
||||
OCtype octype;
|
||||
OCtype ocatomtype;
|
||||
char* ocname = NULL;
|
||||
NCerror ncerr = NC_NOERR;
|
||||
CDFnode* cdfnode;
|
||||
|
||||
oc_dds_class(nccomm->oc.conn,ocnode,&octype);
|
||||
if(octype == OC_Atomic)
|
||||
oc_dds_atomictype(nccomm->oc.conn,ocnode,&ocatomtype);
|
||||
else
|
||||
ocatomtype = OC_NAT;
|
||||
oc_dds_name(nccomm->oc.conn,ocnode,&ocname);
|
||||
oc_dds_rank(nccomm->oc.conn,ocnode,&ocrank);
|
||||
oc_dds_nsubnodes(nccomm->oc.conn,ocnode,&ocnsubnodes);
|
||||
|
||||
#ifdef DEBUG1
|
||||
fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(octype),ocname);
|
||||
if(ocatomtype == OC_NAT)
|
||||
fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(octype),ocname);
|
||||
else
|
||||
fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(ocatomtype),ocname);
|
||||
#endif
|
||||
|
||||
switch (octype) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define DEBUG_H
|
||||
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
#define DAPDEBUG 1
|
||||
#define OCDEBUG
|
||||
#endif
|
||||
|
@ -12,25 +12,27 @@
|
||||
|
||||
/* Build an odometer covering slices startslice upto, but not including, stopslice */
|
||||
Dapodometer*
|
||||
dapodom_fromsegment(DCEsegment* segment, size_t startslice, size_t stopslice)
|
||||
dapodom_fromsegment(DCEsegment* segment, size_t startindex, size_t stopindex)
|
||||
{
|
||||
int i;
|
||||
Dapodometer* odom;
|
||||
|
||||
assert(stopslice > startslice);
|
||||
assert((stopslice - startslice) <= NC_MAX_VAR_DIMS);
|
||||
assert(stopindex > startindex);
|
||||
assert((stopindex - startindex) <= NC_MAX_VAR_DIMS);
|
||||
odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
|
||||
MEMCHECK(odom,NULL);
|
||||
odom->rank = (stopslice - startslice);
|
||||
odom->rank = (stopindex - startindex);
|
||||
for(i=0;i<odom->rank;i++) {
|
||||
odom->start[i] = segment->slices[i+startslice].first;
|
||||
odom->count[i] = segment->slices[i+startslice].count;
|
||||
odom->stride[i] = segment->slices[i+startslice].stride;
|
||||
odom->declsize[i] = segment->slices[i+startslice].declsize;
|
||||
odom->stop[i] = odom->start[i] + odom->count[i];
|
||||
odom->start[i] = segment->slices[i+startindex].first;
|
||||
odom->stride[i] = segment->slices[i+startindex].stride;
|
||||
odom->stop[i] = (segment->slices[i+startindex].last + 1);
|
||||
/* should the above line be instead?
|
||||
odom->stop[i] = odom->start[i] + (odom->count[i]*odom->stride[i]);
|
||||
*/
|
||||
#if 0
|
||||
odom->count[i] = segment->slices[i+startindex].count;
|
||||
#endif
|
||||
odom->declsize[i] = segment->slices[i+startindex].declsize;
|
||||
odom->index[i] = odom->start[i];
|
||||
}
|
||||
return odom;
|
||||
@ -47,13 +49,17 @@ dapodom_new(size_t rank,
|
||||
odom->rank = rank;
|
||||
assert(odom->rank <= NC_MAX_VAR_DIMS);
|
||||
for(i=0;i<odom->rank;i++) {
|
||||
odom->start[i] = (start != NULL ? start[i] : 0);
|
||||
odom->count[i] = (count != NULL ? count[i]
|
||||
: (size != NULL ? size[i] : 1));
|
||||
odom->stride[i] = (size_t)(stride != NULL ? stride[i] : 1);
|
||||
odom->declsize[i] = (size != NULL ? size[i]
|
||||
: (odom->start[i]+odom->count[i]));
|
||||
odom->stop[i] = odom->start[i] + odom->count[i];
|
||||
size_t istart,icount,istop,ideclsize;
|
||||
ptrdiff_t istride;
|
||||
istart = (start != NULL ? start[i] : 0);
|
||||
icount = (count != NULL ? count[i] : (size != NULL ? size[i] : 1));
|
||||
istride = (size_t)(stride != NULL ? stride[i] : 1);
|
||||
istop = istart + icount*istride;
|
||||
ideclsize = (size != NULL ? size[i]: (istop - istart));
|
||||
odom->start[i] = istart;
|
||||
odom->stop[i] = istop;
|
||||
odom->stride[i] = istride;
|
||||
odom->declsize[i] = ideclsize;
|
||||
odom->index[i] = odom->start[i];
|
||||
}
|
||||
return odom;
|
||||
|
@ -11,7 +11,9 @@ typedef struct Dapodometer {
|
||||
int rank;
|
||||
size_t index[NC_MAX_VAR_DIMS];
|
||||
size_t start[NC_MAX_VAR_DIMS];
|
||||
#if 0
|
||||
size_t count[NC_MAX_VAR_DIMS];
|
||||
#endif
|
||||
size_t stride[NC_MAX_VAR_DIMS];
|
||||
size_t stop[NC_MAX_VAR_DIMS];
|
||||
size_t declsize[NC_MAX_VAR_DIMS];
|
||||
|
@ -65,12 +65,12 @@ fprintf(stderr,"constraint: %s",dcetostring((DCEnode*)dapconstraint));
|
||||
|
||||
#ifdef DEBUG1
|
||||
static void
|
||||
dumpslice(const char* prefix, DCEslice* s)
|
||||
slicedump(const char* prefix, DCEslice* s)
|
||||
{
|
||||
#if 1
|
||||
int v = dceverbose;
|
||||
dceverbose = 1;
|
||||
fprintf(stderr,"%s: %s\n",prefix,dcetostring(s));
|
||||
fprintf(stderr,"%s: %s\n",prefix,dcetostring((DCEnode*)s));
|
||||
dceverbose = v;
|
||||
#else
|
||||
size_t last = (s->first+s->length)-1;
|
||||
@ -199,8 +199,8 @@ dceslicecompose(DCEslice* s1, DCEslice* s2, DCEslice* result)
|
||||
size_t lastx = 0;
|
||||
DCEslice sr; /* For back compatability so s1 and result can be same object */
|
||||
#ifdef DEBUG1
|
||||
dumpslice("compose: s1",s1);
|
||||
dumpslice("compose: s2",s2);
|
||||
slicedump("compose: s1",s1);
|
||||
slicedump("compose: s2",s2);
|
||||
#endif
|
||||
sr.node.sort = CES_SLICE;
|
||||
sr.stride = s1->stride * s2->stride;
|
||||
@ -213,10 +213,10 @@ dumpslice("compose: s2",s2);
|
||||
sr.declsize = XMAX(s1->declsize,s2->declsize); /* use max declsize */
|
||||
/* fill in other fields */
|
||||
sr.count = (sr.length + (sr.stride - 1))/sr.stride;
|
||||
#ifdef DEBUG1
|
||||
dumpslice("compose: result",sr);
|
||||
#endif
|
||||
*result = sr;
|
||||
#ifdef DEBUG1
|
||||
slicedump("compose: result",result);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ typedef struct Getvara {
|
||||
void* memory; /* where result is put*/
|
||||
struct NCcachenode* cache;
|
||||
struct DCEprojection* varaprojection;
|
||||
/* associated variable*/
|
||||
OCtype dsttype;
|
||||
/* associated nc variable*/
|
||||
nc_type dsttype;
|
||||
CDFnode* target;
|
||||
int wholevariable;
|
||||
} Getvara;
|
||||
|
@ -158,7 +158,7 @@ nc3d_getvarx(int ncid, int varid,
|
||||
int i;
|
||||
fprintf(stderr,"getvarx: %s",cdfvar->ncfullname);
|
||||
for(i=0;i<ncrank;i++)
|
||||
fprintf(stderr,"[%ld:%ld:%ld]",
|
||||
fprintf(stderr,"(%ld:%ld:%ld)",
|
||||
(long)startp[i],
|
||||
(long)countp[i],
|
||||
(long)stridep[i]
|
||||
@ -199,7 +199,7 @@ NClist* dims = cdfvar->array.dimsetall;
|
||||
fprintf(stderr,"getvarx: %s",cdfvar->ncfullname);
|
||||
if(nclistlength(dims) > 0) {int i;
|
||||
for(i=0;i<nclistlength(dims);i++)
|
||||
fprintf(stderr,"[%lu:%lu:%lu]",(unsigned long)startp[i],(unsigned long)countp[i],(unsigned long)stridep[i]);
|
||||
fprintf(stderr,"(%lu:%lu:%lu)",(unsigned long)startp[i],(unsigned long)countp[i],(unsigned long)stridep[i]);
|
||||
fprintf(stderr," -> ");
|
||||
for(i=0;i<nclistlength(dims);i++)
|
||||
if(stridep[i]==1)
|
||||
|
@ -36,14 +36,17 @@ test_vara_SOURCES = test_vara.c
|
||||
test_partvar_SOURCES = test_partvar.c
|
||||
test_varm3_SOURCES = test_varm3.c
|
||||
t_dap3a_SOURCES = t_dap3a.c
|
||||
test_nstride_cached_SOURCE = test_nstride_cached.c
|
||||
|
||||
TESTS += t_dap3a test_cvt3 test_vara test_partvar
|
||||
TESTS += test_varm3
|
||||
TESTS += t_dap3a
|
||||
TESTS += test_nstride_cached
|
||||
|
||||
check_PROGRAMS += t_dap3a test_cvt3 test_vara test_partvar
|
||||
check_PROGRAMS += test_varm3
|
||||
check_PROGRAMS += t_dap3a
|
||||
check_PROGRAMS += test_nstride_cached
|
||||
|
||||
endif #ENABLE_DAP_REMOTE_TESTS
|
||||
|
||||
@ -80,7 +83,7 @@ EXTRA_DIST = tst_ncdap3.sh tst_ncdap4.sh \
|
||||
tst_ncdap.sh tst_ncdap_shared.sh tst_remote.sh \
|
||||
t_dap.c CMakeLists.txt
|
||||
|
||||
CLEANFILES = test_varm3 test_cvt3 results/*.dmp results/*.das results/*.dds datadds* t_dap3a
|
||||
CLEANFILES = test_varm3 test_cvt3 results/*.dmp results/*.das results/*.dds datadds* t_dap3a test_nstride_cached
|
||||
|
||||
if USE_NETCDF4
|
||||
CLEANFILES += test_cvt4 t_dap4
|
||||
|
233
ncdap_test/test_nstride_cached.c
Normal file
233
ncdap_test/test_nstride_cached.c
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
Report from Ansely Manke:
|
||||
I've attached a file with a short c program that
|
||||
demonstrates what I'm seeing. I don't know that we'd call
|
||||
this a constraint, so that was a misleading description.
|
||||
|
||||
The thing I'm mimicking is a sequence where I read the 2-D
|
||||
coordinate variables, make some decisions about the size of
|
||||
a subset region, and then define index ranges and strides
|
||||
for reading other variables. Reading the full variable
|
||||
happens correctly, but the read with strides winds up
|
||||
messing up the data. Here it shows up returning some valid
|
||||
data and some zero's, but in other sequences of events it
|
||||
seems to be actually mis-ordered.
|
||||
|
||||
I notice that the results are correct if the initial read of
|
||||
the variable uses counts that are size-1. So that might be a
|
||||
clue. And the read is correct if I either close and reopen
|
||||
the dataset after reading the original full variable, or if
|
||||
I don't do that step of first reading the whole grid. It's
|
||||
also fine with NetCDF 4.2.1.1.
|
||||
|
||||
-Ansley
|
||||
|
||||
Problem was two-fold:
|
||||
1. struct Getvara has the dsttype field as OC_Type rather than nc_type
|
||||
2. the dap odometer code dapnew_segment was incorrectly
|
||||
handling strides > 1: specifically, the stop position was incorrect.
|
||||
|
||||
*/
|
||||
|
||||
/* vars_whoi_test */
|
||||
/* acm 4/2013 */
|
||||
/* ansley.b.manke@noaa.gov */
|
||||
/*
|
||||
/* test nc_get_vars_float with calls similar to Ferret calls */
|
||||
|
||||
|
||||
/*linked with:
|
||||
|
||||
cc vars_whoi_test.c -g -o vars_whoi_test_4211 /usr/local/netcdf_4211/lib/libnetcdf.a /usr/local/hdf5_189/lib/libhdf5_hl.a /usr/local/hdf5_189/lib/libhdf5.a /usr/local/lib/libz.a -L/usr/lib64 -lc -lm -lcurl
|
||||
cc vars_whoi_test.c -g -o vars_whoi_test /home/users/ansley/local/x86_nc43/lib/libnetcdf.a /usr/local/hdf5_189/lib/libhdf5_hl.a /usr/local/hdf5_189/lib/libhdf5.a /usr/local/lib/libz.a -L/usr/lib64 -lc -lm -lcurl
|
||||
|
||||
*/
|
||||
|
||||
/* Closing and reopening the dataset between the two reads fixes the
|
||||
incorrect data return */
|
||||
|
||||
/* Setting the count to one less in the full data read also fixes the
|
||||
incorrect data return */
|
||||
|
||||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
#include<string.h>
|
||||
#include "netcdf.h"
|
||||
|
||||
static int coords = 0;
|
||||
|
||||
static char* URL="[noprefetch]http://geoport.whoi.edu/thredds/dodsC/coawst_4/use/fmrc/coawst_4_use_best.ncd";
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
|
||||
int ncid;
|
||||
int varid;
|
||||
int i;
|
||||
int ncstatus;
|
||||
size_t start[5], count[5];
|
||||
ptrdiff_t stride[5], tmp_ptrdiff_t;
|
||||
|
||||
int idim, ndim;
|
||||
float dat[301060];
|
||||
float sdat[10];
|
||||
|
||||
for (idim=0; idim<5; idim++) {
|
||||
start[idim] = 0;
|
||||
count[idim] = 1;
|
||||
stride[idim] = 1;
|
||||
}
|
||||
|
||||
ndim=2;
|
||||
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("open URL %s\n",URL);
|
||||
printf(" \n");
|
||||
|
||||
ncstatus = nc_open(URL, NC_NOWRITE, &ncid);
|
||||
|
||||
ncstatus = nc_inq_varid(ncid, "lon_rho", &varid);
|
||||
|
||||
printf("varid = %d\n", varid);
|
||||
printf("ncid = %d\n", ncid);
|
||||
|
||||
ndim=2;
|
||||
|
||||
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("Read lon_rho data w/o strides\n");
|
||||
printf(" \n");
|
||||
|
||||
start[0] = 0;
|
||||
start[1] = 0;
|
||||
start[2] = 0;
|
||||
start[3] = 0;
|
||||
|
||||
count[0] = 336;
|
||||
count[1] = 896;
|
||||
|
||||
stride[0] = 1;
|
||||
stride[1] = 1;
|
||||
|
||||
for (idim=0; idim<ndim; idim++)
|
||||
printf("start[%1d]=%3d count[%1d]=%3d stride[%1d]=%3d\n",
|
||||
idim,start[idim],idim,count[idim],idim,stride[idim]);
|
||||
|
||||
ncstatus = nc_get_vars_float (ncid, varid, start, count, stride, (float*) dat);
|
||||
|
||||
if(coords) {
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("Print some of lon_rho\n");
|
||||
printf(" \n");
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
printf("lon_rho[%d] = %f\n",i,dat[i]);
|
||||
printf(" \n");
|
||||
|
||||
for (i=301045; i<301055; i++)
|
||||
printf("lon_rho[%d] = %f\n",i,dat[i]);
|
||||
printf(" \n");
|
||||
}
|
||||
|
||||
memset((void*)dat,0,sizeof(dat));
|
||||
|
||||
/* Read a second variable */
|
||||
|
||||
ncstatus = nc_inq_varid(ncid, "lat_rho", &varid);
|
||||
|
||||
printf("varid = %d\n", varid);
|
||||
printf("ncid = %d\n", ncid);
|
||||
|
||||
ndim=2;
|
||||
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("Read lat_rho data w/o strides\n");
|
||||
printf(" \n");
|
||||
|
||||
start[0] = 0;
|
||||
start[1] = 0;
|
||||
start[2] = 0;
|
||||
start[3] = 0;
|
||||
|
||||
count[0] = 336;
|
||||
count[1] = 896;
|
||||
|
||||
stride[0] = 1;
|
||||
stride[1] = 1;
|
||||
|
||||
for (idim=0; idim<ndim; idim++)
|
||||
printf("start[%d]=%3d count[%d]=%3d stride[%d]=%3d\n",
|
||||
idim, start[idim], idim, count[idim], idim, stride[idim]);
|
||||
|
||||
ncstatus = nc_get_vars_float (ncid, varid, start, count, stride, (float*) dat);
|
||||
|
||||
if(coords) {
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("Print some of lat_rho\n");
|
||||
printf(" \n");
|
||||
for (i=0; i<10; i++)
|
||||
printf("lat_rho[%d] = %f\n",i,dat[i]);
|
||||
printf(" \n");
|
||||
|
||||
printf(" \n");
|
||||
for (i=301045; i<301055; i++)
|
||||
printf("lon_rho[%d] = %f\n",i,dat[i]);
|
||||
printf(" \n");
|
||||
}
|
||||
|
||||
memset((void*)dat,0,sizeof(dat));
|
||||
|
||||
/* close and reopen the dataset, then the below read is correct
|
||||
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("Close and reopen the dataset\n");
|
||||
|
||||
ncstatus = nc_close (ncid);
|
||||
ncstatus = nc_open(URL, NC_NOWRITE, &ncid);
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* Read a subset of the data with strides */
|
||||
|
||||
ncstatus = nc_inq_varid(ncid, "lon_rho", &varid);
|
||||
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("Read a subset of lon_rho data with strides\n");
|
||||
printf(" \n");
|
||||
|
||||
start[0] = 250;
|
||||
start[1] = 704;
|
||||
|
||||
count[0] = 5;
|
||||
count[1] = 2;
|
||||
|
||||
stride[0] = 2;
|
||||
stride[1] = 4;
|
||||
|
||||
for (idim=0; idim<ndim; idim++)
|
||||
printf("start[%1d]=%3d count[%1d]=%3d stride[%1d]=%3d\n",
|
||||
idim,start[idim],idim,count[idim],idim,stride[idim]);
|
||||
|
||||
memset((void*)sdat,0,sizeof(sdat));
|
||||
ncstatus = nc_get_vars_float (ncid, varid, start, count, stride, (float*) sdat);
|
||||
|
||||
printf("status = %d\n", ncstatus);
|
||||
|
||||
printf(" \n");
|
||||
printf("********************\n");
|
||||
printf("Print values read. They should all be -67.xxxx \n");
|
||||
printf(" \n");
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
printf("lon_rho[%d] = %f\n",i,sdat[i]);
|
||||
|
||||
ncstatus = nc_close (ncid);
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user