diff options
author | Robb Matzke <matzke@llnl.gov> | 1997-10-20 23:22:19 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1997-10-20 23:22:19 (GMT) |
commit | cca9fb56f7e3f94cf4588a6f7214a2170862f49d (patch) | |
tree | be647cceddb5c65f8755d7332ca27fdc8cf3bf09 | |
parent | b1ba4bff394bd787c5c418f5c99f56b9533b8676 (diff) | |
download | hdf5-cca9fb56f7e3f94cf4588a6f7214a2170862f49d.zip hdf5-cca9fb56f7e3f94cf4588a6f7214a2170862f49d.tar.gz hdf5-cca9fb56f7e3f94cf4588a6f7214a2170862f49d.tar.bz2 |
[svn-r131] Tests hyperslabs.
-rw-r--r-- | test/hyperslab.c | 1192 |
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); +} |