PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/hdf-4.2.7/mfhdf/nctest/slabs.c

#
C | 463 lines | 380 code | 32 blank | 51 comment | 85 complexity | c070aa0f31822cf17d7aa08da5f420eb MD5 | raw file
  1. /*********************************************************************
  2. * Copyright 1993, UCAR/Unidata
  3. * See netcdf/COPYRIGHT file for copying and redistribution conditions.
  4. * $Id: slabs.c 4998 2007-11-16 03:14:03Z epourmal $
  5. *********************************************************************/
  6. #include "h4config.h"
  7. #ifdef H4_HAVE_NETCDF
  8. #include "netcdf.h"
  9. #else
  10. #include "hdf4_netcdf.h"
  11. #endif
  12. #include "testcdf.h" /* defines in-memory test cdf structure */
  13. #include "add.h" /* functions to update in-memory netcdf */
  14. #include "error.h"
  15. #include "tests.h"
  16. #include "alloc.h"
  17. #include "emalloc.h"
  18. #ifdef HDF
  19. #include "hdf.h"
  20. #endif
  21. #define LEN_OF(array) ((sizeof array) / (sizeof array[0]))
  22. /* dimension sizes */
  23. #define NDIMS 4 /* number of dimensions */
  24. #define WSIZE 7 /* sizes of dimensions */
  25. #define XSIZE 5
  26. #define YSIZE 6
  27. #define ZSIZE 4
  28. /* Added new function for character and byte so we will not overflow; pgcc
  29. compiler screamed at VF macro */
  30. #define VFC(w) (1000*w[0]+100*w[1]+10*w[2]+w[3])%64 + 48
  31. /* Any function that maps dimension values 1-1 to values is OK here */
  32. #define VF(w) (1000*w[0]+100*w[1]+10*w[2]+w[3])
  33. #define NVARS 6 /* number of variables */
  34. /*
  35. * Fill typed array element with specified value, that is
  36. *
  37. * v[ii] = val;
  38. */
  39. static void
  40. val_stuff(type, v, ii, val) /* v[ii] = val */
  41. nc_type type; /* netcdf type of v, NC_BYTE, ..., NC_DOUBLE */
  42. void *v; /* array of specified type */
  43. int ii; /* it's v[ii] we want to store into */
  44. long val; /* value to store */
  45. {
  46. static char pname[] = "val_stuff";
  47. #ifdef WRONG_for_PGCC /* This way caused a lot of problems for PGI CC compiler
  48. EIP 2004/12/15 */
  49. union gp {
  50. char cp[1];
  51. short sp[1];
  52. nclong lp[1];
  53. float fp[1];
  54. double dp[1];
  55. } *gp;
  56. gp = (union gp *) v;
  57. switch (type) {
  58. case NC_BYTE:
  59. case NC_CHAR:
  60. gp->cp[ii] = (char) val;
  61. break;
  62. case NC_SHORT:
  63. gp->sp[ii] = (short)val;
  64. break;
  65. case NC_LONG:
  66. gp->lp[ii] = (nclong)val;
  67. break;
  68. case NC_FLOAT:
  69. gp->fp[ii] = (float)val;
  70. break;
  71. case NC_DOUBLE:
  72. gp->dp[ii] = val;
  73. break;
  74. default:
  75. error("%s: bad type, test program error", pname);
  76. #endif /*WRONG_for_PGCC*/
  77. switch (type) {
  78. case NC_BYTE:
  79. case NC_CHAR:
  80. ((char *)v)[ii] = (char) val;
  81. break;
  82. case NC_SHORT:
  83. ((short *)v)[ii] = (short)val;
  84. break;
  85. case NC_LONG:
  86. ((nclong *)v)[ii] = (nclong)val;
  87. break;
  88. case NC_FLOAT:
  89. ((float *)v)[ii] = (float)val;
  90. break;
  91. case NC_DOUBLE:
  92. ((double *)v)[ii] = (double)val;
  93. break;
  94. default:
  95. error("%s: bad type, test program error", pname);
  96. }
  97. }
  98. /*
  99. * Compare typed array element with specified value, that is return
  100. *
  101. * (v[ii] != val)
  102. *
  103. * returns 0 if equal, 1 if not equal
  104. */
  105. static int
  106. val_diff(type, v, ii, val) /* v[ii] != val */
  107. nc_type type; /* netcdf type of v, NC_BYTE, ..., NC_DOUBLE */
  108. void *v; /* array of specified type */
  109. int ii; /* it's v[ii] we want to compare */
  110. long val; /* value to compare with */
  111. {
  112. static char pname[] = "val_diff";
  113. #ifdef WRONG_for_PGCC /* This way caused a lot of problems for PGI CC compiler
  114. EIP 2004/12/15 */
  115. union gp {
  116. char cp[1];
  117. short sp[1];
  118. nclong lp[1];
  119. float fp[1];
  120. double dp[1];
  121. } *gp;
  122. gp = (union gp *) v;
  123. switch (type) {
  124. case NC_BYTE:
  125. case NC_CHAR:
  126. return (gp->cp[ii] != (char) val);
  127. case NC_SHORT:
  128. return (gp->sp[ii] != (short) val);
  129. case NC_LONG:
  130. return (gp->lp[ii] != (nclong) val);
  131. case NC_FLOAT:
  132. return (gp->fp[ii] != (float) val);
  133. case NC_DOUBLE:
  134. return (gp->dp[ii] != (double) val);
  135. default:
  136. error("%s: bad type, test program error", pname);
  137. return (-1);
  138. #endif /*WRONG_for_PGCC*/
  139. switch (type) {
  140. case NC_BYTE:
  141. case NC_CHAR:
  142. return (((char*)v)[ii] != (char) val);
  143. case NC_SHORT:
  144. return (((short*)v)[ii] != (short) val);
  145. case NC_LONG:
  146. return (((nclong*)v)[ii] != (nclong) val);
  147. case NC_FLOAT:
  148. return (((float*)v)[ii] != (float) val);
  149. case NC_DOUBLE:
  150. return (((double*)v)[ii] != (double) val);
  151. default:
  152. error("%s: bad type, test program error", pname);
  153. return (-1);
  154. }
  155. }
  156. /*
  157. * For each type of variable, put a four-dimensional hypercube of values
  158. * with a single call to ncvarput. Then use ncvarget to retrieve a single
  159. * interior value, an interior vector of values along each of the four
  160. * dimensions, an interior plane of values along each of the six pairs of
  161. * dimensions, and an interior cube of values along each of the four
  162. * triples of dimensions. In each case, compare the retrieved values with
  163. * the written values.
  164. */
  165. int
  166. test_slabs(cdfid)
  167. int cdfid; /* handle of netcdf open and in data mode */
  168. {
  169. int nerrs = 0;
  170. static char pname[] = "test_slabs";
  171. static struct cdfdim dims[NDIMS] = {
  172. {"w", WSIZE},
  173. {"x", XSIZE},
  174. {"y", YSIZE},
  175. {"z", ZSIZE}
  176. };
  177. int dimids[NDIMS]; /* dimension ids */
  178. long corner[NDIMS], edge[NDIMS], point[NDIMS];
  179. static struct cdfvar va[NVARS] = { /* variables of all types */
  180. {"bytevar", NC_BYTE, NDIMS, ___, 0},
  181. {"charvar", NC_CHAR, NDIMS, ___, 0},
  182. {"shortvar", NC_SHORT, NDIMS, ___, 0},
  183. {"longvar", NC_LONG, NDIMS, ___, 0},
  184. {"floatvar", NC_FLOAT, NDIMS, ___, 0},
  185. {"doublevar", NC_DOUBLE, NDIMS, ___, 0},
  186. };
  187. void *v;
  188. int varid[NVARS], iv; /* variable id */
  189. int idim, jdim, kdim, ldim;
  190. int iw, ix, iy, iz, ii, jj, kk;
  191. if (ncredef(cdfid) == -1) {
  192. error("%s: cdredef failed", pname);
  193. ncclose(cdfid); return 1;
  194. }
  195. /* back in define mode OK, now add dimensions */
  196. for (idim = 0; idim < NDIMS; idim++) {
  197. dimids[idim] = ncdimdef(cdfid, dims[idim].name, dims[idim].size);
  198. if (dimids[idim] == -1) {
  199. error("%s: ncdimdef failed", pname);
  200. ncclose(cdfid);
  201. return 1;
  202. }
  203. add_dim(&test, &dims[idim]);
  204. }
  205. /* define a multi-dimensional variable of each type */
  206. for (iv = 0; iv < NVARS; iv++) {
  207. va[iv].dims = (int *) emalloc(sizeof(int) * va[iv].ndims);
  208. for (idim = 0; idim < va[iv].ndims; idim++)
  209. va[iv].dims[idim] = dimids[idim];
  210. varid[iv] = ncvardef(cdfid, va[iv].name, va[iv].type, va[iv].ndims,
  211. va[iv].dims);
  212. if (varid[iv] == -1) {
  213. error("%s: ncvardef failed", pname);
  214. ncclose(cdfid); return 1;
  215. }
  216. add_var(&test, &va[iv]); /* keep in-memory netcdf in sync */
  217. }
  218. if (ncendef (cdfid) == -1) {
  219. error("%s: ncendef failed", pname);
  220. ncclose(cdfid); return 1;
  221. }
  222. for (iv = 0; iv < NVARS; iv++) { /* test each type of variable */
  223. v = emalloc(WSIZE*XSIZE*YSIZE*ZSIZE * nctypelen(va[iv].type));
  224. /* fill it with values using a function of dimension indices */
  225. ii = 0;
  226. for (iw=0; iw < WSIZE; iw++) {
  227. corner[0] = iw;
  228. for (ix=0; ix < XSIZE; ix++) {
  229. corner[1] = ix;
  230. for (iy=0; iy < YSIZE; iy++) {
  231. corner[2] = iy;
  232. for (iz=0; iz < ZSIZE; iz++) {
  233. corner[3] = iz;
  234. /* v[ii++] = VF(corner); */
  235. if (va[iv].type == NC_BYTE || va[iv].type == NC_CHAR)
  236. val_stuff(va[iv].type, v, ii, VFC(corner));
  237. else
  238. val_stuff(va[iv].type, v, ii, VF(corner));
  239. ii++;
  240. }
  241. }
  242. }
  243. }
  244. for (idim = 0; idim < NDIMS; idim++) {
  245. corner[idim] = 0;
  246. edge[idim] = dims[idim].size;
  247. }
  248. /* ncvarput the whole variable */
  249. if (ncvarput(cdfid, varid[iv], corner, edge, (void *) v) == -1) {
  250. error("%s: ncvarput failed", pname);
  251. nerrs++;
  252. }
  253. add_data(&test, varid[iv], corner, edge); /* keep test in sync */
  254. /*
  255. * For several combinations of fixed dimensions, get a slab and compare
  256. * values to function values.
  257. */
  258. /* get an interior point */
  259. for (idim=0; idim < NDIMS; idim++) {
  260. corner[idim] = dims[idim].size/2;
  261. edge[idim] = 1;
  262. point[idim] = corner[idim];
  263. }
  264. if (ncvarget(cdfid, varid[iv], corner, edge, (void *) v) == -1) {
  265. error("%s: ncvarget of one point failed", pname);
  266. nerrs++;
  267. }
  268. /* if (v[0] != VF(point)) */
  269. if (va[iv].type == NC_BYTE || va[iv].type == NC_CHAR) {
  270. if (val_diff(va[iv].type, v, 0, VFC(point))) {
  271. error("%s: ncvarget got wrong value for point", pname);
  272. nerrs++;
  273. }
  274. }
  275. else
  276. {
  277. if (val_diff(va[iv].type, v, 0, VF(point))) {
  278. error("%s: ncvarget got wrong value for point", pname);
  279. nerrs++;
  280. }
  281. }
  282. /*endif NC_BYTE || NC_CHAR */
  283. /* get an interior vector in each direction */
  284. for (idim=0; idim < NDIMS; idim++) {
  285. for (jdim=0; jdim < NDIMS; jdim++) {
  286. corner[jdim] = dims[jdim].size/2;
  287. edge[jdim] = 1;
  288. point[jdim] = corner[jdim];
  289. }
  290. corner[idim] = 1; /* get vector along dimension idim */
  291. edge[idim] = dims[idim].size - 2;
  292. if (ncvarget(cdfid, varid[iv], corner, edge, (void *) v) == -1) {
  293. error("%s: ncvarget of vector failed", pname);
  294. nerrs++;
  295. }
  296. for (ii=corner[idim]; ii <= edge[idim]; ii++) {
  297. point[idim] = ii;
  298. /* if (v[ii-1] != VF(point)) */
  299. if (va[iv].type == NC_BYTE || va[iv].type == NC_CHAR){
  300. if (val_diff(va[iv].type, v, ii-1, VFC(point))) {
  301. error("%s: ncvarget got wrong value for vector", pname);
  302. nerrs++;
  303. }
  304. }
  305. else
  306. {
  307. if (val_diff(va[iv].type, v, ii-1, VF(point))) {
  308. error("%s: ncvarget got wrong value for vector", pname);
  309. nerrs++;
  310. }
  311. }
  312. }
  313. }
  314. /* get an interior plane in each direction */
  315. for (idim=0; idim < NDIMS; idim++) {
  316. for (jdim=idim+1; jdim < NDIMS; jdim++) {
  317. for (kdim=0; kdim < NDIMS; kdim++) { /* reset corners and edges */
  318. corner[kdim] = dims[kdim].size/2;
  319. edge[kdim] = 1;
  320. point[kdim] = corner[kdim];
  321. }
  322. corner[idim] = 1; /* interior plane along dimensions idim jdim */
  323. corner[jdim] = 1;
  324. edge[idim] = dims[idim].size - 2;
  325. edge[jdim] = dims[jdim].size - 2;
  326. if (ncvarget(cdfid, varid[iv], corner, edge, (void *) v) == -1) {
  327. error("%s: ncvarget of plane failed", pname);
  328. nerrs++;
  329. }
  330. for (ii=corner[idim]; ii <= edge[idim]; ii++) {
  331. for (jj=corner[jdim]; jj <= edge[jdim]; jj++) {
  332. point[idim] = ii;
  333. point[jdim] = jj;
  334. /* if (v[(ii-1)*edge[jdim]+jj-1] != VF(point)) { */
  335. if (va[iv].type == NC_BYTE || va[iv].type == NC_CHAR) {
  336. if (val_diff(va[iv].type, v,
  337. (ii-1)*(int)edge[jdim]+jj-1, VFC(point))) {
  338. error("%s: ncvarget got wrong value in plane", pname);
  339. error("idim=%d,jdim=%d,ii=%d,jj=%d",
  340. idim,
  341. jdim,
  342. ii,
  343. jj);
  344. nerrs++;
  345. }
  346. }
  347. else
  348. {
  349. if (val_diff(va[iv].type, v,
  350. (ii-1)*(int)edge[jdim]+jj-1, VF(point))) {
  351. error("%s: ncvarget got wrong value in plane", pname);
  352. error("idim=%d,jdim=%d,ii=%d,jj=%d",
  353. idim,
  354. jdim,
  355. ii,
  356. jj);
  357. nerrs++;
  358. }
  359. }
  360. }
  361. }
  362. }
  363. }
  364. /* get an interior cube in each direction */
  365. for (idim=0; idim < NDIMS; idim++) {
  366. for (jdim=idim+1; jdim < NDIMS; jdim++) {
  367. for (kdim=jdim+1; kdim < NDIMS; kdim++) {
  368. for (ldim=0; ldim < NDIMS; ldim++) { /* reset corners, edges */
  369. corner[ldim] = dims[ldim].size/2;
  370. edge[ldim] = 1;
  371. point[ldim] = corner[ldim];
  372. }
  373. corner[idim] = 1; /* intr. cube along idim jdim kdim */
  374. corner[jdim] = 1;
  375. corner[kdim] = 1;
  376. edge[idim] = dims[idim].size - 2;
  377. edge[jdim] = dims[jdim].size - 2;
  378. edge[kdim] = dims[kdim].size - 2;
  379. if (ncvarget(cdfid, varid[iv], corner, edge, (void *) v) == -1) {
  380. error("%s: ncvarget of cube failed", pname);
  381. nerrs++;
  382. }
  383. for (ii=corner[idim]; ii <= edge[idim]; ii++) {
  384. for (jj=corner[jdim]; jj <= edge[jdim]; jj++) {
  385. for (kk=corner[kdim]; kk <= edge[kdim]; kk++) {
  386. point[idim] = ii;
  387. point[jdim] = jj;
  388. point[kdim] = kk;
  389. /* if (v[((ii-1)*edge[jdim]+jj-1)*
  390. edge[kdim]+kk-1] != VF(point)) { */
  391. if (va[iv].type == NC_BYTE || va[iv].type == NC_CHAR) {
  392. if (val_diff(va[iv].type,v,
  393. ((ii-1)*(int)edge[jdim]+jj-1)*
  394. (int)edge[kdim]+kk-1,VFC(point))) {
  395. error("%s: ncvarget got wrong value in cube", pname);
  396. error("idim=%d,jdim=%d,kdim=%d,ii=%d,jj=%d,kk=%d",
  397. idim,
  398. jdim,
  399. kdim,
  400. ii,
  401. jj,
  402. kk);
  403. nerrs++;
  404. }
  405. }
  406. else
  407. {
  408. if (val_diff(va[iv].type,v,
  409. ((ii-1)*(int)edge[jdim]+jj-1)*
  410. (int)edge[kdim]+kk-1,VF(point))) {
  411. error("%s: ncvarget got wrong value in cube", pname);
  412. error("idim=%d,jdim=%d,kdim=%d,ii=%d,jj=%d,kk=%d",
  413. idim,
  414. jdim,
  415. kdim,
  416. ii,
  417. jj,
  418. kk);
  419. nerrs++;
  420. }
  421. }
  422. }
  423. }
  424. }
  425. }
  426. }
  427. }
  428. Free((char *)v);
  429. }
  430. return nerrs;
  431. }