1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
/*********************************************************************
* Copyright 2018, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* $Id: vputgetg.c,v 1.13 2006/10/31 16:19:40 ed Exp $
*********************************************************************/
#include <config.h>
#include <stdio.h>
#include <stdlib.h> /* for free() */
#include "netcdf.h"
#include "testcdf.h" /* defines in-memory test cdf structure */
#include "add.h" /* functions to update in-memory netcdf */
#include "val.h"
#include "error.h"
#include "tests.h"
#include "emalloc.h"
#undef max
#define max(A, B) ((A) > (B) ? (A) : (B))
/*
* For every variable in open netcdf, puts and gets three hypercubes
* of data of the appropriate type, comparing values from get to
* values put to check that both ncvarputg and ncvargetg worked. The
* three hypercubes are
* - a large hypercube from (0, 0, ...) to the far corner (diagonally
* opposite (0, 0, ...), trivial strides and index mapping vector;
* - a size 1 hypercube from the far corner with edge lengths of 1
* in every direction, trivial strides and index mapping vector; and
* - a hypercube starting about 1/3 of the way along the diagonal
* from (0,0,...) extending 1/3 of the way in every direction
* toward the far corner, dimension-dependent strides and inverted
* index mapping vector rooted at the "upper-left" corned.
*/
int
test_varputgetg(cdfid)
int cdfid; /* handle of netcdf open and in data mode */
{
int nerrs = 0;
static char pname[] = "test_varputgetg";
int id = 0, ie = 0, iv = 0; /* loop indices */
int ne = 3; /* number of test hypercubes for each var */
struct cdfhc { /* a hypercube with generic values */
long cor[MAX_NC_DIMS]; /* netcdf coordinates for lower corner */
long npts[MAX_NC_DIMS]; /* netcdf edge lengths to upper corner */
long strd[MAX_NC_DIMS]; /* external strides */
long imap[MAX_NC_DIMS]; /* internal, index mapping vector */
long offset; /* offset in bytes to I/O start corner */
void *vals; /* pointer to block of values */
} hc[3], tmp; /* test hypercubes */
long nel[3]; /* number of elements in hypercube */
for (iv = 0; iv < test.nvars; iv++) { /* for each var in netcdf */
for (ie = 0; ie < ne; ie++)
nel[ie] = 1; /* to compute space for hypercube values */
/*
* The following macro returns the size of a dimension for a
* variable with a maximum dimension size of 5 for the record
* dimension.
*/
# define EXTNPTS(varid, idim) \
(test.dims[test.vars[varid].dims[id]].size == NC_UNLIMITED \
? 5 \
: test.dims[test.vars[varid].dims[id]].size)
# define STRIDE(idim) (idim + 2)
# define INTNPTS(extnpts, idim) (1 + (extnpts - 1) / STRIDE(idim))
for (id = test.vars[iv].ndims-1; id >= 0; --id) { /* set cubes */
/* start at "lower-left" corner, do whole variable. unity
* strides and trivial index mapping */
hc[0].cor[id] = 0;
hc[0].npts[id] = EXTNPTS(iv, id);
hc[0].strd[id] = 1;
hc[0].imap[id] = id == test.vars[iv].ndims-1
? nctypelen(test.vars[iv].type)
: hc[0].imap[id+1] * hc[0].npts[id+1];
nel[0] *= hc[0].npts[id];
if (id <= 0)
hc[0].offset = 0;
/* start at "upper-right" corner, do one point */
hc[1].cor[id] = EXTNPTS(iv, id) - 1;
hc[1].npts[id] = 1;
hc[1].strd[id] = 1;
hc[1].imap[id] = id == test.vars[iv].ndims-1
? nctypelen(test.vars[iv].type)
: hc[1].imap[id+1] * hc[1].npts[id+1];
nel[1] *= hc[1].npts[id];
if (id == 0)
hc[1].offset = 0;
/* start about 1/3 way along diagonal, do 1/3 in each direction.
* dimension-dependent strides; inverted index mapping starting
* from "upper-right" corner. */
hc[2].cor[id] = EXTNPTS(iv, id)/3;
hc[2].npts[id] = INTNPTS(max(EXTNPTS(iv, id)/3, 1), id);
hc[2].strd[id] = STRIDE(id);
hc[2].imap[id] = id == test.vars[iv].ndims-1
? -nctypelen(test.vars[iv].type)
: hc[2].imap[id+1] * hc[2].npts[id+1];
nel[2] *= hc[2].npts[id];
if (id == 0)
hc[2].offset = (nel[2]-1)*nctypelen(test.vars[iv].type);
}
for (ie = 0; ie < ne; ie++) { /* for each test */
int nelms = (int)nel[ie]*nctypelen(test.vars[iv].type) + 8;
/* allocate space for the cube of values */
hc[ie].vals = emalloc(nelms);
tmp.vals = emalloc(nelms);
/* fill allocated space with different values of right type */
val_fill(test.vars[iv].type, nel[ie], hc[ie].vals);
if(ncvarputg (cdfid, iv, hc[ie].cor, hc[ie].npts,
hc[ie].strd, hc[ie].imap,
(char*)hc[ie].vals+hc[ie].offset)
== -1) {
error("%s: ncvarputg failed for point %d, variable %s",
pname, ie, test.vars[iv].name);
nerrs++;
errvar(&test, &test.vars[iv]);
(void)fprintf(stderr," corner = (");
for (id = 0 ; id < test.vars[iv].ndims; id++)
(void)fprintf(stderr,"%ld%s",(long)hc[ie].cor[id],
(id < test.vars[iv].ndims-1) ? ", " : "");
(void)fprintf(stderr,")\n");
(void)fprintf(stderr," npts = (");
for (id = 0 ; id < test.vars[iv].ndims; id++)
(void)fprintf(stderr,"%ld%s",(long)hc[ie].npts[id],
(id < test.vars[iv].ndims-1) ? ", " : "");
(void)fprintf(stderr,")\n");
(void)fprintf(stderr," external strides = (");
for (id = 0 ; id < test.vars[iv].ndims; id++)
(void)fprintf(stderr,"%ld%s",(long)hc[ie].strd[id],
(id < test.vars[iv].ndims-1) ? ", " : "");
(void)fprintf(stderr,")\n");
(void)fprintf(stderr," internal index mapping vector = (");
for (id = 0 ; id < test.vars[iv].ndims; id++)
(void)fprintf(stderr,"%ld%s",(long)hc[ie].imap[id],
(id < test.vars[iv].ndims-1) ? ", " : "");
(void)fprintf(stderr,")\n");
} else {
long dsize[MAX_NC_DIMS];
for (id = 0; id < test.vars[iv].ndims; id++)
dsize[id] = EXTNPTS(iv, id);
add_data(&test, iv, hc[ie].cor, dsize);
/* keep test in sync */
if(ncvargetg (cdfid, iv, hc[ie].cor, hc[ie].npts,
hc[ie].strd, hc[ie].imap,
(char*)tmp.vals+hc[ie].offset)
== -1) {
error("%s: ncvargetg failed for point %d, variable %s",
pname, ie, test.vars[iv].name);
nerrs++;
}
else {
if (val_cmp(test.vars[iv].type, nel[ie],
hc[ie].vals, tmp.vals) != 0) {
error("%s: bad values returned from ncvargetg",
pname);
nerrs++;
errvar(&test, &test.vars[iv]); /* describe var */
}
}
}
free (hc[ie].vals);
free (tmp.vals);
}
}
return nerrs;
}
|