Fix jira NCF-249

This commit is contained in:
Dennis Heimbigner 2013-04-23 20:18:16 +00:00
parent e960416761
commit 7e8bfb01f3
9 changed files with 282 additions and 30 deletions

View File

@ -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) {

View File

@ -7,7 +7,7 @@
#define DEBUG_H
#if 0
#if 1
#define DAPDEBUG 1
#define OCDEBUG
#endif

View File

@ -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;

View File

@ -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];

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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

View 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);
}