summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/hyperslab.c1192
1 files changed, 1192 insertions, 0 deletions
diff --git a/test/hyperslab.c b/test/hyperslab.c
new file mode 100644
index 0000000..b07a8fa
--- /dev/null
+++ b/test/hyperslab.c
@@ -0,0 +1,1192 @@
+/*
+ * Copyright (C) 1997 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Friday, October 10, 1997
+ *
+ * Purpose: Hyperslab operations are rather complex, so this file
+ * attempts to test them extensively so we can be relatively
+ * sure they really work. We only test 1d, 2d, and 3d cases
+ * because testing general dimensionalities would require us to
+ * rewrite much of the hyperslab stuff.
+ */
+#include <H5private.h>
+#include <H5MMprivate.h>
+#include <H5Vprivate.h>
+
+#define AT() printf (" at %s:%d in %s()\n",__FILE__,__LINE__,__FUNCTION__);
+
+#define TEST_SMALL 0x0001
+#define TEST_MEDIUM 0x0002
+
+#define VARIABLE_SRC 0
+#define VARIABLE_DST 1
+#define VARIABLE_BOTH 2
+
+
+/*-------------------------------------------------------------------------
+ * Function: init_full
+ *
+ * Purpose: Initialize full array.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static uintn
+init_full (uint8 *array, size_t nx, size_t ny, size_t nz)
+{
+ int i, j, k;
+ uint8 acc=128;
+ uintn total=0;
+
+ for (i=0; i<nx; i++) {
+ for (j=0; j<ny; j++) {
+ for (k=0; k<nz; k++) {
+ total += acc;
+ *array++ = acc++;
+ }
+ }
+ }
+ return total;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_array
+ *
+ * Purpose: Prints the values in an array
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_array (uint8 *array, size_t nx, size_t ny, size_t nz)
+{
+ int i, j, k;
+
+ for (i=0; i<nx; i++) {
+ if (nz>1) {
+ printf ("i=%d:\n", i);
+ } else {
+ printf ("%03d:", i);
+ }
+
+ for (j=0; j<ny; j++) {
+ if (nz>1) printf ("%03d:", j);
+ for (k=0; k<nz; k++) {
+ printf (" %3d", *array++);
+ }
+ if (nz>1) printf ("\n");
+ }
+ printf ("\n");
+ }
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_ref
+ *
+ * Purpose: Prints the reference value
+ *
+ * Return: Success: 0
+ *
+ * Failure:
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_ref (size_t nx, size_t ny, size_t nz)
+{
+ uint8 *array;
+
+ array = H5MM_xcalloc (nx*ny*nz, sizeof(uint8));
+
+ printf ("Reference array:\n");
+ init_full (array, nx, ny, nz);
+ print_array (array, nx, ny, nz);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_fill
+ *
+ * Purpose: Tests the H5V_hyper_fill() function.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Saturday, October 11, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_fill (size_t nx, size_t ny, size_t nz,
+ size_t di, size_t dj, size_t dk,
+ size_t ddx, size_t ddy, size_t ddz)
+{
+ uint8 *dst=NULL; /*destination array */
+ size_t hs_size[3]; /*hyperslab size */
+ size_t dst_size[3]; /*destination total size */
+ size_t dst_offset[3]; /*offset of hyperslab in dest */
+ uintn ref_value; /*reference value */
+ uintn acc; /*accumulator */
+ int i, j, k, dx, dy, dz, u, v, w; /*counters */
+ int ndims; /*hyperslab dimensionality */
+ char dim[64],s[256]; /*temp string */
+ uintn fill_value; /*fill value */
+
+ /*
+ * Dimensionality.
+ */
+ if (0==nz) {
+ if (0==ny) {
+ ndims = 1;
+ ny = nz = 1;
+ sprintf (dim, "%d", nx);
+ } else {
+ ndims = 2;
+ nz = 1;
+ sprintf (dim, "%dx%d", nx, ny);
+ }
+ } else {
+ ndims = 3;
+ sprintf (dim, "%dx%dx%d", nx, ny, nz);
+ }
+ sprintf (s, "Testing hyperslab fill %-11s variable hyperslab ", dim);
+ printf ("%-70s", s);
+ fflush (stdout);
+
+ /* Allocate array */
+ dst = H5MM_xcalloc (nx*ny*nz, 1);
+ init_full (dst, nx, ny, nz);
+
+
+ for (i=0; i<nx; i+=di) {
+ for (j=0; j<ny; j+=dj) {
+ for (k=0; k<nz; k+=dk) {
+ for (dx=1; dx<=nx-i; dx+=ddx) {
+ for (dy=1; dy<=ny-j; dy+=ddy) {
+ for (dz=1; dz<=nz-k; dz+=ddz) {
+
+ /* Describe the hyperslab */
+ dst_size[0] = nx;
+ dst_size[1] = ny;
+ dst_size[2] = nz;
+ dst_offset[0] = i;
+ dst_offset[1] = j;
+ dst_offset[2] = k;
+ hs_size[0] = dx;
+ hs_size[1] = dy;
+ hs_size[2] = dz;
+
+ for (fill_value=0; fill_value<256; fill_value+=64) {
+ /*
+ * Initialize the full array, then subtract the
+ * original * fill values and add the new ones.
+ */
+ ref_value = init_full (dst, nx, ny, nz);
+ for (u=dst_offset[0]; u<dst_offset[0]+dx; u++) {
+ for (v=dst_offset[1]; v<dst_offset[1]+dy; v++) {
+ for (w=dst_offset[2]; w<dst_offset[2]+dz; w++) {
+ ref_value -= dst[u*ny*nz + v*nz + w];
+ }
+ }
+ }
+ ref_value += fill_value * dx * dy * dz;
+
+ /* Fill the hyperslab with some value */
+ H5V_hyper_fill (ndims, hs_size, dst_size, dst_offset,
+ dst, fill_value);
+
+ /*
+ * Sum the array and compare it to the reference
+ * value.
+ */
+ acc = 0;
+ for (u=0; u<nx; u++) {
+ for (v=0; v<ny; v++) {
+ for (w=0; w<nz; w++) {
+ acc += dst[u*ny*nz + v*nz + w];
+ }
+ }
+ }
+
+ if (acc != ref_value) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ /*
+ * Print debugging info unless output is going
+ * directly to a terminal.
+ */
+ AT ();
+ printf (" acc != ref_value\n");
+ printf (" i=%d, j=%d, k=%d, "
+ "dx=%d, dy=%d, dz=%d, fill=%d\n",
+ i, j, k, dx, dy, dz, fill_value);
+ print_ref (nx, ny, nz);
+ printf ("\n Result is:\n");
+ print_array (dst, nx, ny, nz);
+ }
+ goto error;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ puts (" PASSED");
+ H5MM_xfree (dst);
+ return SUCCEED;
+
+ error:
+ H5MM_xfree (dst);
+ return FAIL;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy
+ *
+ * Purpose: Tests H5V_hyper_copy().
+ *
+ * The NX, NY, and NZ arguments are the size for the source and
+ * destination arrays. You map pass zero for NZ or for NY and
+ * NZ to test the 2-d and 1-d cases respectively.
+ *
+ * A hyperslab is copied from/to (depending on MODE) various
+ * places in SRC and DST beginning at 0,0,0 and increasing
+ * location by DI,DJ,DK in the x, y, and z directions.
+ *
+ * For each hyperslab location, various sizes of hyperslabs are
+ * tried beginning with 1x1x1 and increasing the size in each
+ * dimension by DDX,DDY,DDZ.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_copy (int mode,
+ size_t nx, size_t ny, size_t nz,
+ size_t di, size_t dj, size_t dk,
+ size_t ddx, size_t ddy, size_t ddz)
+{
+ uint8 *src=NULL; /*source array */
+ uint8 *dst=NULL; /*destination array */
+ size_t hs_size[3]; /*hyperslab size */
+ size_t dst_size[3]; /*destination total size */
+ size_t src_size[3]; /*source total size */
+ size_t dst_offset[3]; /*offset of hyperslab in dest */
+ size_t src_offset[3]; /*offset of hyperslab in source */
+ uintn ref_value; /*reference value */
+ uintn acc; /*accumulator */
+ int i, j, k, dx, dy, dz, u, v, w; /*counters */
+ int ndims; /*hyperslab dimensionality */
+ char dim[64], s[256]; /*temp string */
+ const char *sub;
+
+ /*
+ * Dimensionality.
+ */
+ if (0==nz) {
+ if (0==ny) {
+ ndims = 1;
+ ny = nz = 1;
+ sprintf (dim, "%d", nx);
+ } else {
+ ndims = 2;
+ nz = 1;
+ sprintf (dim, "%dx%d", nx, ny);
+ }
+ } else {
+ ndims = 3;
+ sprintf (dim, "%dx%dx%d", nx, ny, nz);
+ }
+
+ switch (mode) {
+ case VARIABLE_SRC:
+ /*
+ * The hyperslab "travels" through the source array but the
+ * destination hyperslab is always at the origin of the destination
+ * array.
+ */
+ sub = "variable source";
+ break;
+ case VARIABLE_DST:
+ /*
+ * We always read a hyperslab from the origin of the source and copy it
+ * to a hyperslab at various locations in the destination.
+ */
+ sub = "variable destination";
+ break;
+ case VARIABLE_BOTH:
+ /*
+ * We read the hyperslab from various locations in the source and copy
+ * it to the same location in the destination.
+ */
+ sub = "sync source & dest ";
+ break;
+ default:
+ abort ();
+ }
+
+ sprintf (s, "Testing hyperslab copy %-11s %s", dim, sub);
+ printf ("%-70s", s);
+ fflush (stdout);
+
+ /*
+ * Allocate arrays
+ */
+ src = H5MM_xcalloc (nx*ny*nz, 1);
+ dst = H5MM_xcalloc (nx*ny*nz, 1);
+ init_full (src, nx, ny, nz);
+
+ for (i=0; i<nx; i+=di) {
+ for (j=0; j<ny; j+=dj) {
+ for (k=0; k<nz; k+=dk) {
+ for (dx=1; dx<=nx-i; dx+=ddx) {
+ for (dy=1; dy<=ny-j; dy+=ddy) {
+ for (dz=1; dz<=nz-k; dz+=ddz) {
+
+ /*
+ * Describe the source and destination hyperslabs and the
+ * arrays to which they belong.
+ */
+ hs_size[0] = dx;
+ hs_size[1] = dy;
+ hs_size[2] = dz;
+ dst_size[0] = src_size[0] = nx;
+ dst_size[1] = src_size[1] = ny;
+ dst_size[2] = src_size[2] = nz;
+ switch (mode) {
+ case VARIABLE_SRC:
+ dst_offset[0] = 0;
+ dst_offset[1] = 0;
+ dst_offset[2] = 0;
+ src_offset[0] = i;
+ src_offset[1] = j;
+ src_offset[2] = k;
+ break;
+ case VARIABLE_DST:
+ dst_offset[0] = i;
+ dst_offset[1] = j;
+ dst_offset[2] = k;
+ src_offset[0] = 0;
+ src_offset[1] = 0;
+ src_offset[2] = 0;
+ break;
+ case VARIABLE_BOTH:
+ dst_offset[0] = i;
+ dst_offset[1] = j;
+ dst_offset[2] = k;
+ src_offset[0] = i;
+ src_offset[1] = j;
+ src_offset[2] = k;
+ break;
+ default:
+ abort ();
+ }
+
+ /*
+ * Sum the main array directly to get a reference value
+ * to compare against later.
+ */
+ ref_value = 0;
+ for (u=src_offset[0]; u<src_offset[0]+dx; u++) {
+ for (v=src_offset[1]; v<src_offset[1]+dy; v++) {
+ for (w=src_offset[2]; w<src_offset[2]+dz; w++) {
+ ref_value += src[u*ny*nz + v*nz + w];
+ }
+ }
+ }
+
+ /*
+ * Set all loc values to 1 so we can detect writing
+ * outside the hyperslab.
+ */
+ for (u=0; u<nx; u++) {
+ for (v=0; v<ny; v++) {
+ for (w=0; w<nz; w++) {
+ dst[u*ny*nz + v*nz + w] = 1;
+ }
+ }
+ }
+
+ /*
+ * Copy a hyperslab from the global array to the local
+ * array.
+ */
+ H5V_hyper_copy (ndims, hs_size,
+ dst_size, dst_offset, dst,
+ src_size, src_offset, src);
+
+ /*
+ * Sum the destination hyperslab. It should be the same
+ * as the reference value.
+ */
+ acc = 0;
+ for (u=dst_offset[0]; u<dst_offset[0]+dx; u++) {
+ for (v=dst_offset[1]; v<dst_offset[1]+dy; v++) {
+ for (w=dst_offset[2]; w<dst_offset[2]+dz; w++) {
+ acc += dst[u*ny*nz + v*nz + w];
+ }
+ }
+ }
+ if (acc != ref_value) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ /*
+ * Print debugging info unless output is going
+ * directly to a terminal.
+ */
+ AT ();
+ printf (" acc != ref_value\n");
+ printf (" i=%d, j=%d, k=%d, "
+ "dx=%d, dy=%d, dz=%d\n",
+ i, j, k, dx, dy, dz);
+ print_ref (nx, ny, nz);
+ printf ("\n Destination array is:\n");
+ print_array (dst, nx, ny, nz);
+ }
+ goto error;
+ }
+
+ /*
+ * Sum the entire array. It should be a fixed amount
+ * larger than the reference value since we added the
+ * border of 1's to the hyperslab.
+ */
+ acc = 0;
+ for (u=0; u<nx; u++) {
+ for (v=0; v<ny; v++) {
+ for (w=0; w<nz; w++) {
+ acc += dst[u*ny*nz + v*nz + w];
+ }
+ }
+ }
+ if (acc != ref_value + nx*ny*nz - dx*dy*dz) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ /*
+ * Print debugging info unless output is going
+ * directly to a terminal.
+ */
+ AT ();
+ printf (" acc != ref_value + nx*ny*nz - "
+ "dx*dy*dz\n");
+ printf (" i=%d, j=%d, k=%d, "
+ "dx=%d, dy=%d, dz=%d\n",
+ i, j, k, dx, dy, dz);
+ print_ref (nx, ny, nz);
+ printf ("\n Destination array is:\n");
+ print_array (dst, nx, ny, nz);
+ }
+ goto error;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ puts (" PASSED");
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return SUCCEED;
+
+ error:
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return FAIL;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_multifill
+ *
+ * Purpose: Tests the H5V_stride_copy() function by using it to fill a
+ * hyperslab by replicating a multi-byte sequence. This might
+ * be useful to initialize an array of structs with a default
+ * struct value, or to initialize an array of floating-point
+ * values with a default bit-pattern.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Saturday, October 11, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_multifill (int nx)
+{
+ int i, j;
+ size_t size;
+ intn src_stride;
+ intn dst_stride;
+ char s[64];
+
+ struct a_struct {
+ int left;
+ double mid;
+ int right;
+ } fill, *src=NULL, *dst=NULL;
+
+ printf ("%-70s", "Testing multi-byte fill value");
+ fflush (stdout);
+
+ /* Initialize the source and destination */
+ src = H5MM_xmalloc (nx * sizeof(*src));
+ dst = H5MM_xmalloc (nx * sizeof(*dst));
+ for (i=0; i<nx; i++) {
+ src[i].left = 1111111;
+ src[i].mid = 12345.6789;
+ src[i].right = 2222222;
+ dst[i].left = 3333333;
+ dst[i].mid = 98765.4321;
+ dst[i].right = 4444444;
+ }
+
+ /*
+ * Describe the fill value. The zero stride says to read the same thing
+ * over and over again.
+ */
+ fill.left = 55555555;
+ fill.mid = 3.1415927;
+ fill.right = 66666666;
+ src_stride = 0;
+
+ /*
+ * The destination stride says to fill in one value per array element
+ */
+ dst_stride = sizeof(fill);
+
+ /*
+ * Copy the fill value into each element
+ */
+ size = nx;
+ H5V_stride_copy (1, sizeof(double), &size,
+ &dst_stride, &(dst[0].mid), &src_stride, &(fill.mid));
+
+ /*
+ * Check
+ */
+ s[0] = '\0';
+ for (i=0; i<nx; i++) {
+ if (dst[i].left != 3333333) {
+ sprintf (s, "bad dst[%d].left", i);
+ } else if (dst[i].mid != fill.mid) {
+ sprintf (s, "bad dst[%d].mid", i);
+ } else if (dst[i].right != 4444444) {
+ sprintf (s, "bad dst[%d].right", i);
+ }
+ if (s[0]) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" fill={%d,%g,%d}\n ",
+ fill.left, fill.mid, fill.right);
+ for (j=0; j<sizeof(fill); j++) {
+ printf (" %02x", ((uint8*)&fill)[j]);
+ }
+ printf ("\n dst[%d]={%d,%g,%d}\n ",
+ i, dst[i].left, dst[i].mid, dst[i].right);
+ for (j=0; j<sizeof(dst[i]); j++) {
+ printf (" %02x", ((uint8*)(dst+i))[j]);
+ }
+ printf ("\n");
+ }
+ goto error;
+ }
+ }
+
+ puts (" PASSED");
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return SUCCEED;
+
+ error:
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_endian
+ *
+ * Purpose: Tests the H5V_stride_copy() function by using it to copy an
+ * array of integers and swap the byte ordering from little
+ * endian to big endian or vice versa depending on the hardware.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Saturday, October 11, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_endian (size_t nx)
+{
+ uint8 *src=NULL; /*source array */
+ uint8 *dst=NULL; /*destination array */
+ intn src_stride[2]; /*source strides */
+ intn dst_stride[2]; /*destination strides */
+ size_t size[2]; /*size vector */
+ int i, j;
+
+ printf ("%-70s", "Testing endian conversion by stride");
+ fflush (stdout);
+
+ /* Initialize arrays */
+ src = H5MM_xmalloc (nx*4);
+ init_full (src, nx, 4, 1);
+ dst = H5MM_xcalloc (nx, 4);
+
+ /* Initialize strides */
+ src_stride[0] = 0;
+ src_stride[1] = 1;
+ dst_stride[0] = 8;
+ dst_stride[1] = -1;
+ size[0] = nx;
+ size[1] = 4;
+
+ /* Copy the array */
+ H5V_stride_copy (2, 1, size, dst_stride, dst+3, src_stride, src);
+
+ /* Compare */
+ for (i=0; i<nx; i++) {
+ for (j=0; j<4; j++) {
+ if (src[i*4+j] != dst[i*4+3-j]) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ /*
+ * Print debugging info unless output is going directly to a
+ * terminal.
+ */
+ AT ();
+ printf (" i=%d, j=%d\n", i, j);
+ printf (" Source array is:\n");
+ print_array (src, nx, 4, 1);
+ printf ("\n Result is:\n");
+ print_array (dst, nx, 4, 1);
+ }
+ goto error;
+ }
+ }
+ }
+
+ puts (" PASSED");
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return SUCCEED;
+
+ error:
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return FAIL;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_transpose
+ *
+ * Purpose: Copy a 2d array from here to there and transpose the elements
+ * as it's copied.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Saturday, October 11, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_transpose (size_t nx, size_t ny)
+{
+ intn *src = NULL;
+ intn *dst = NULL;
+ int i, j;
+ intn src_stride[2], dst_stride[2];
+ size_t size[2];
+ char s[256];
+
+ sprintf (s, "Testing 2d transpose by stride %4dx%-4d", nx, ny);
+ printf ("%-70s", s);
+ fflush (stdout);
+
+ /* Initialize */
+ src = H5MM_xmalloc (nx*ny * sizeof(*src));
+ for (i=0; i<nx; i++) {
+ for (j=0; j<ny; j++) {
+ src[i*ny + j] = i*ny + j;
+ }
+ }
+ dst = H5MM_xcalloc (nx*ny, sizeof(*dst));
+
+ /* Build stride info */
+ size[0] = nx;
+ size[1] = ny;
+ src_stride[0] = 0;
+ src_stride[1] = sizeof(*src);
+ dst_stride[0] = (1 - nx*ny) * sizeof(*src);
+ dst_stride[1] = nx * sizeof(*src);
+
+ /* Copy and transpose */
+ if (nx==ny) {
+ H5V_stride_copy (2, sizeof(*src), size,
+ dst_stride, dst,
+ src_stride, src);
+ } else {
+ H5V_stride_copy (2, sizeof(*src), size,
+ dst_stride, dst,
+ src_stride, src);
+ }
+
+
+ /* Check */
+ for (i=0; i<nx; i++) {
+ for (j=0; j<ny; j++) {
+ if (src[i*ny + j] != dst[j*nx + i]) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" diff at i=%d, j=%d\n", i, j);
+ printf (" Source is:\n");
+ for (i=0; i<nx; i++) {
+ printf ("%3d:", i);
+ for (j=0; j<ny; j++) {
+ printf (" %6d", src[i*ny+j]);
+ }
+ printf ("\n");
+ }
+ printf ("\n Destination is:\n");
+ for (i=0; i<ny; i++) {
+ printf ("%3d:", i);
+ for (j=0; j<nx; j++) {
+ printf (" %6d", dst[i*nx+j]);
+ }
+ printf ("\n");
+ }
+ }
+ goto error;
+ }
+ }
+ }
+
+ puts (" PASSED");
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return SUCCEED;
+
+ error:
+ H5MM_xfree (src);
+ H5MM_xfree (dst);
+ return FAIL;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_sub_super
+ *
+ * Purpose: Tests H5V_stride_copy() to reduce the resolution of an image
+ * by copying half the pixels in the X and Y directions. Then
+ * we use the small image and duplicate every pixel to result in
+ * a 2x2 square.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, October 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_sub_super (size_t nx, size_t ny)
+{
+ uint8 *full = NULL; /*original image */
+ uint8 *half = NULL; /*image at 1/2 resolution */
+ uint8 *twice = NULL; /*2x2 pixels */
+ intn src_stride[4]; /*source stride info */
+ intn dst_stride[4]; /*destination stride info */
+ size_t size[4]; /*number of sample points */
+ int i, j;
+ char s[256];
+
+ sprintf (s, "Testing image sampling %4dx%-4d to %4dx%-4d ",
+ 2*nx, 2*ny, nx, ny);
+ printf ("%-70s", s);
+ fflush (stdout);
+
+ /* Initialize */
+ full = H5MM_xmalloc (4*nx*ny);
+ init_full (full, 2*nx, 2*ny, 1);
+ half = H5MM_xcalloc (nx*ny, 1);
+ twice = H5MM_xcalloc (4*nx*ny, 1);
+
+ /* Setup */
+ size[0] = nx;
+ size[1] = ny;
+ src_stride[0] = 2*ny;
+ src_stride[1] = 2;
+ dst_stride[0] = 0;
+ dst_stride[1] = 1;
+
+ /* Copy */
+ H5V_stride_copy (2, sizeof(uint8), size,
+ dst_stride, half, src_stride, full);
+
+ /* Check */
+ for (i=0; i<nx; i++) {
+ for (j=0; j<ny; j++) {
+ if (full[4*i*ny + 2*j] != half[i*ny+j]) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" full[%d][%d] != half[%d][%d]\n", i*2, j*2, i, j);
+ printf (" full is:\n");
+ print_array (full, 2*nx, 2*ny, 1);
+ printf ("\n half is:\n");
+ print_array (half, nx, ny, 1);
+ }
+ goto error;
+ }
+ }
+ }
+ puts (" PASSED");
+
+
+ /*
+ * Test replicating pixels to produce an image twice as large in each
+ * dimension.
+ */
+ sprintf (s, "Testing image sampling %4dx%-4d to %4dx%-4d ",
+ nx, ny, 2*nx, 2*ny);
+ printf ("%-70s", s);
+ fflush (stdout);
+
+ /* Setup stride */
+ size[0] = nx;
+ size[1] = ny;
+ size[2] = 2;
+ size[3] = 2;
+ src_stride[0] = 0;
+ src_stride[1] = 1;
+ src_stride[2] = 0;
+ src_stride[3] = 0;
+ dst_stride[0] = 2*ny;
+ dst_stride[1] = 2*sizeof(uint8) - 4*ny;
+ dst_stride[2] = 2*ny - 2*sizeof(uint8);
+ dst_stride[3] = sizeof(uint8);
+
+ /* Copy */
+ H5V_stride_copy (4, sizeof(uint8), size,
+ dst_stride, twice, src_stride, half);
+
+ /* Check */
+ s[0] = '\0';
+ for (i=0; i<nx; i++) {
+ for (j=0; j<ny; j++) {
+ if (half[i*ny+j] != twice[4*i*ny + 2*j]) {
+ sprintf (s, "half[%d][%d] != twice[%d][%d]", i, j, 2*i, 2*j);
+ } else if (half[i*ny+j] != twice[4*i*ny + 2*j + 1]) {
+ sprintf (s, "half[%d][%d] != twice[%d][%d]", i, j, 2*i, 2*j+1);
+ } else if (half[i*ny+j] != twice[(2*i+1)*2*ny + 2*j]) {
+ sprintf (s, "half[%d][%d] != twice[%d][%d]", i, j, 2*i+1, 2*j);
+ } else if (half[i*ny+j] != twice[(2*i+1)*2*ny + 2*j + 1]) {
+ sprintf (s, "half[%d][%d] != twice[%d][%d]", i, j, 2*i+1, 2*j+1);
+ }
+ if (s[0]) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" %s\n Half is:\n", s);
+ print_array (half, nx, ny, 1);
+ printf ("\n Twice is:\n");
+ print_array (twice, 2*nx, 2*ny, 1);
+ }
+ goto error;
+ }
+ }
+ }
+ puts (" PASSED");
+
+
+ H5MM_xfree (full);
+ H5MM_xfree (half);
+ H5MM_xfree (twice);
+ return SUCCEED;
+
+ error:
+ H5MM_xfree (full);
+ H5MM_xfree (half);
+ H5MM_xfree (twice);
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Test various hyperslab operations. Give the words
+ * `small' and/or `medium' on the command line or only `small'
+ * is assumed.
+ *
+ * Return: Success: exit(0)
+ *
+ * Failure: exit(non-zero)
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main (int argc, char *argv[])
+{
+ herr_t status;
+ int nerrors=0;
+ uintn size_of_test;
+
+ /* Parse arguments or assume `small' */
+ if (1==argc) {
+ size_of_test = TEST_SMALL;
+ } else {
+ intn i;
+ for (i=1,size_of_test=0; i<argc; i++) {
+ if (!strcmp (argv[i], "small")) {
+ size_of_test |= TEST_SMALL;
+ } else if (!strcmp (argv[i], "medium")) {
+ size_of_test |= TEST_MEDIUM;
+ } else {
+ printf ("unrecognized argument: %s\n", argv[i]);
+ exit (1);
+ }
+ }
+ }
+ printf ("Test sizes: ");
+ if (size_of_test & TEST_SMALL) printf (" SMALL");
+ if (size_of_test & TEST_MEDIUM) printf (" MEDIUM");
+ printf ("\n");
+
+
+
+ /*
+ *------------------------------
+ * TEST HYPERSLAB FILL OPERATION
+ *------------------------------
+ */
+ if (size_of_test & TEST_SMALL) {
+ status = test_fill (11, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_fill (11, 10, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_fill (3, 5, 5, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_fill (113, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_fill (15, 11, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_fill (5, 7, 7, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+
+ /*------------------------------
+ * TEST HYPERSLAB COPY OPERATION
+ *------------------------------
+ */
+
+ /* exhaustive, one-dimensional test */
+ if (size_of_test & TEST_SMALL) {
+ status = test_copy (VARIABLE_SRC, 11, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_DST, 11, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_BOTH, 11, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_copy (VARIABLE_SRC, 179, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_DST, 179, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_BOTH, 179, 0, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+ /* exhaustive, two-dimensional test */
+ if (size_of_test & TEST_SMALL) {
+ status = test_copy (VARIABLE_SRC, 11, 10, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_DST, 11, 10, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_BOTH, 11, 10, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_copy (VARIABLE_SRC, 13, 19, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_DST, 13, 19, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_BOTH, 13, 19, 0, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+ /* sparse, two-dimensional test */
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_copy (VARIABLE_SRC, 73, 67, 0, 7, 11, 1, 13, 11, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_DST, 73, 67, 0, 7, 11, 1, 13, 11, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_BOTH, 73, 67, 0, 7, 11, 1, 13, 11, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+
+ /* exhaustive, three-dimensional test */
+ if (size_of_test & TEST_SMALL) {
+ status = test_copy (VARIABLE_SRC, 3, 5, 5, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_DST, 3, 5, 5, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_BOTH, 3, 5, 5, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_copy (VARIABLE_SRC, 7, 9, 5, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_DST, 7, 9, 5, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ status = test_copy (VARIABLE_BOTH, 7, 9, 5, 1, 1, 1, 1, 1, 1);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+
+ /*---------------------
+ * TEST MULTI-BYTE FILL
+ *---------------------
+ */
+
+ if (size_of_test & TEST_SMALL) {
+ status = test_multifill (10);
+ nerrors += status<0 ? 1 : 0;
+ }
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_multifill (500000);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+
+ /*---------------------------
+ * TEST TRANSLATION OPERATORS
+ *---------------------------
+ */
+
+ if (size_of_test & TEST_SMALL) {
+ status = test_endian (10);
+ nerrors += status<0 ? 1 : 0;
+ status = test_transpose (9, 9);
+ nerrors += status<0 ? 1 : 0;
+ status = test_transpose (3, 11);
+ nerrors += status<0 ? 1 : 0;
+ }
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_endian (800000);
+ nerrors += status<0 ? 1 : 0;
+ status = test_transpose (1200, 1200);
+ nerrors += status<0 ? 1 : 0;
+ status = test_transpose (800, 1800);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+
+ /*-------------------------
+ * TEST SAMPLING OPERATIONS
+ *-------------------------
+ */
+
+ if (size_of_test & TEST_SMALL) {
+ status = test_sub_super (5, 10);
+ nerrors += status<0 ? 1 : 0;
+ }
+ if (size_of_test & TEST_MEDIUM) {
+ status = test_sub_super (480, 640);
+ nerrors += status<0 ? 1 : 0;
+ }
+
+
+
+ /*--- END OF TESTS ---*/
+
+ if (nerrors) {
+ printf ("***** %d HYPERSLAB TEST%s FAILED! *****\n",
+ nerrors, 1==nerrors?"":"S");
+ if (isatty (1)) {
+ printf ("(Redirect output to a pager or a file to see "
+ "debug output)\n");
+ }
+ exit (1);
+ }
+
+ printf ("All hyperslab tests passed.\n");
+ exit (0);
+}