2
0
mirror of https://github.com/HDFGroup/hdf5.git synced 2025-03-25 17:00:45 +08:00
Robb Matzke 254ae8d43d [svn-r859] Changes since 19981030
----------------------

./MANIFEST
	Added new Pablo files HDF5record_RT.h and ProcIDs.h

./acconfig.h
./configure		[REGENERATED]
./configure.in
./src/H5.c
./src/H5Vprivate.h
./src/H5config.h.in	[REGENERATED]
./src/H5private.h
./src/H5public.h
./test/big.c
	Added more configuration stuff for the Win32 environment. Removed all
	the #ifdef WIN32 from the source and replaced them with OS-independent
	stuff.  Specifics follow:

	Check for non-Posix.1 `st_blocks' field in `struct stat' which is used
	by the big file test to decide if the file system supports holes.  If
	the st_blocks field isn't present then we just skip the test.

	Configure checks for <io.h> <sys/resource.h> <sys/time.h> and
	<winsock.h> and defines HAVE_IO_H, HAVE_SYS_RESOURCE_H,
	HAVE_SYS_TIME_H and HAVE_WINSOCK_H when they're found.

	Configure checks whether both <sys/time.h> and <time.h> can be
	included and defines SYS_TIME_WITH_TIME if so.  Otherwise include only
	<sys/time.h> or <time.h> even if both exist.

	Configure checks sizeof(__int64) and defines SIZEOF___INT64 to the
	result or to zero if __int64 isn't defined.  The source uses `long
	long' in preference to `__int64'.

	Removed null WIN32 definition for `inline' since such a definition
	already exists in H5config.h

	Protected gettimeofday() calls in debugging code with
	HAVE_GETTIMEOFDAY instead of WIN32.

./src/H5F.c
./src/H5Flow.c
./src/H5Fmpio.c
./src/H5Fsec2.c
./src/H5Fstdio.h
./src/H5P.c
./src/H5Tconv.c
./src/H5private.h
	Removed #include of system files from library source files and
	consolodated them into H5private.h where they're protected by various
	configuration macros (most of them were duplicated there already
	anyway).

./test/big.c
./test/chunk.c
./test/cmpd_dset.c
./test/dsets.c
./test/dtypes.c
./test/extend.c
./test/external.c
./test/fillval.c
./test/flush1.c
./test/flush2.c
./test/iopipe.c
./test/links.c
./test/mount.c
./test/mtime.c
./test/overhead.c
./test/ragged.c
./test/shtype.c
./test/unlink.c
	Protected system #include's with #ifdef's from H5config.h.

	Undefined NDEBUG since some of the tests rely on assert() to check
	return values.

	Removed WIN32 definitions for __unused__ since this can be controlled
	by the definition of HAVE_ATTRIBUTE in H5config.h

./test/testhdf5.h
	Removed the CLEAN_CMD definition because we no longer use it.
	Albert's cleanup() functions replaced it.

./test/fillval.c
	Initialized auto hid_t variables to fix warnings in error recovery
	code when data flow analysis is turned on in compilers.

./test/h5tools.c
	Initialized an auto variable to fix a compiler warning.

./test/chunk.c
./test/ragged.c
	The WIN32 had some unsigned variables changed to signed because the
	compiler generates warnings when coercing unsigned to double(?).  I
	changed them back to unsigned because they really are unsigned
	quantities. If this the change was just to shut up extraneous warnings
	then perhaps a compiler flag can do the same; otherwise if the
	compiler generates bad code then we should supply a patch file instead
	messing up source code with bug work-arounds.

./src/H5detect.c
	Protected system #include's with #ifdef's from H5config.h thereby
	removing a WIN32.

	If getpwuid() doesn't exist (HAVE_GETPWUID) then we assume that
	`struct passwd' doesn't exist either (we don't really need it in that
	case).

	The H5T_NATIVE_LLONG and H5T_NATIVE_ULLONG are defined in terms of
	`long long' or else `__int64' or else `long' depending on what's
	available.

./src/H5Flow.c
./src/H5Ofill.c
	Added __unused__ to some function arguments that aren't used when
	assertions are turned off.

./src/H5V.c
	Changed an auto variable name in some hand-inlined code to get rid of
	a warning about the variable shadowing a previous auto.
1998-11-02 12:58:28 -05:00

651 lines
17 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright © 1998 Spizella Software
* All rights reserved.
*
* Programmer: Robb Matzke <robb@arborea.spizella.com>
* Tuesday, August 25, 1998
*/
/* See H5private.h for how to include headers */
#undef NDEBUG
#include <H5config.h>
#ifdef STDC_HEADERS
# include <assert.h>
# include <signal.h>
# include <stdlib.h>
#endif
#include <hdf5.h>
#include <H5private.h> /*for performance monitoring*/
#define NOTIFY_INTERVAL 2 /*seconds*/
#define TIME_LIMIT 60 /*seconds*/
#define CH_SIZE 8192*8 /*approx chunk size in bytes*/
#define MAX_NELMTS 3000000
#define C_MTYPE unsigned int /*type in memory */
#define H_MTYPE H5T_NATIVE_UINT /*type in memory */
#define H_FTYPE H5T_NATIVE_UINT /*type in file */
typedef struct {
double percent;
size_t lo, hi;
size_t nhits;
} quant_t;
#if 1
/* Typical VBT sizes */
static quant_t quant_g[] = {
{10.00, 1, 5},
{89.00, 6, 20},
{ 0.90, 21, 100},
{ 0.09, 101, 1000},
{ 0.01, 1001, 10000},
};
#elif 0
/* Sizes for testing */
static quant_t quant_g[] = {
{10.0, 1, 5},
{80.0, 6, 15},
{10.0, 16, 20},
};
#elif 0
/* Larger I/O */
static quant_t quant_g[] = {
{10.0, 1, 1000},
{80.0, 1001, 5000},
{10.0, 5001, 10000},
};
#else
/* All same size */
static quant_t quant_g[] = {
{100.0, 1000, 1000}
};
#endif
static volatile sig_atomic_t alarm_g = 0;
static volatile sig_atomic_t timeout_g = 0;
/*-------------------------------------------------------------------------
* Function: catch_alarm
*
* Purpose: Increments the global `alarm_g' and resets the alarm for
* another few seconds.
*
* Return: void
*
* Programmer: Robb Matzke
* Wednesday, August 26, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static void
catch_alarm(int __unused__ signum)
{
static int ncalls=0;
ncalls++;
if (0==ncalls % NOTIFY_INTERVAL) {
alarm_g++;
}
if (timeout_g>0) --timeout_g;
alarm(1);
}
/*-------------------------------------------------------------------------
* Function: display_error_cb
*
* Purpose: Displays the error stack after printing "*FAILED*".
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Wednesday, March 4, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
display_error_cb (void __unused__ *client_data)
{
putchar('\n');
H5Eprint (stdout);
return 0;
}
/*-------------------------------------------------------------------------
* Function: rand_nelmts
*
* Purpose: Returns a the length of a 1-d array according to the
* probabilities described above.
*
* Return: Success: Number of elements
*
* Failure: never fails
*
* Programmer: Robb Matzke
* Thursday, August 20, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static size_t
rand_nelmts(int reset_counters)
{
double p = (rand() % 1000000)/1000000.0;
double total = 0.0;
size_t size=0, i;
static size_t ncalls=0;
if (reset_counters) {
printf(" %9s %8s %8s\n", "Length", "Requsted", "Actual");
printf(" --------------- -------- --------\n");
for (i=0; i<NELMTS(quant_g); i++) {
printf(" [%6lu,%6lu] %7.3f%% %7.3f%%\n",
(unsigned long)(quant_g[i].lo),
(unsigned long)(quant_g[i].hi),
quant_g[i].percent,
100.0*(double)(quant_g[i].nhits)/(double)ncalls);
quant_g[i].nhits = 0;
}
printf(" --------------- -------- --------\n");
ncalls = 0;
size = 0;
} else {
for (i=0; i<NELMTS(quant_g); i++) {
total += quant_g[i].percent/100.0;
if (p<total) {
size = rand()%(1+(quant_g[i].hi-quant_g[i].lo)) +
quant_g[i].lo;
quant_g[i].nhits++;
break;
}
}
assert(i<NELMTS(quant_g));
ncalls++;
}
return size;
}
/*-------------------------------------------------------------------------
* Function: ragged_write_all
*
* Purpose: Writes rows to the ragged array RA.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, August 27, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
ragged_write_all(hid_t ra, hsize_t rows_at_once)
{
int *dd, total_nelmts=0;
hssize_t row; /*current row number */
hsize_t i; /*counter */
hsize_t max_width = quant_g[NELMTS(quant_g)-1].hi;
hsize_t interval_nelmts; /*elmts/interval timer */
hsize_t *size=NULL; /*size of each row */
void **buf=NULL; /*buffer for each row */
H5_timer_t timer, timer_total; /*performance timers */
char s[64]; /*tempory string buffer */
char testname[80];
sprintf(testname, "Testing write all, units of %lu",
(unsigned long)rows_at_once);
printf("%s...\n", testname);
fflush(stdout);
timeout_g = TIME_LIMIT;
/* Create the ragged array row in memory */
if (NULL==(dd = malloc(max_width*sizeof(C_MTYPE))) ||
NULL==(size = malloc(rows_at_once*sizeof(*size))) ||
NULL==(buf = malloc(rows_at_once*sizeof(*buf)))) {
puts("Memory allocation failed");
goto error;
}
for (i=0; i<max_width; i++) dd[i] = i+1;
/*
* Describe a few rows then add them to the ragged array. Print a status
* report every once in a while too.
*/
printf(" %8s %8s %8s %10s\n",
"Row", "Nelmts", "Complete", "Bandwidth");
printf(" -------- -------- -------- ----------\n");
H5_timer_reset(&timer_total);
H5_timer_begin(&timer);
interval_nelmts = 0;
for (row=0; total_nelmts<MAX_NELMTS && timeout_g>0; row+=i) {
for (i=0; i<rows_at_once && total_nelmts<MAX_NELMTS; i++) {
size[i] = rand_nelmts(0);
total_nelmts += size[i];
buf[i] = dd;
interval_nelmts += size[i];
}
if (H5RAwrite(ra, row, i, H_MTYPE, size, buf)<0) goto error;
if (0==row || alarm_g || 0==timeout_g) {
alarm_g = 0;
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE),
timer.etime);
printf(" %8lu %8lu %7.3f%% %10s%s\n",
(unsigned long)(row+i), (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s,
0==timeout_g?" (aborting)":"");
interval_nelmts = 0;
H5_timer_begin(&timer);
}
}
/* Conclusions */
if (timeout_g) { /*a minor race condition, but who really cares?*/
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s\n",
(unsigned long)row, (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s);
}
printf(" -------- -------- -------- ----------\n");
H5_bandwidth(s, (double)total_nelmts*sizeof(C_MTYPE), timer_total.etime);
printf(" %27s%10s\n", "", s);
/* Cleanup */
free(dd);
free(size);
free(buf);
printf("%-70s PASSED\n\n", testname);
return 0;
error:
printf("%-70s*FAILED*\n\n", testname);
return -1;
}
/*-------------------------------------------------------------------------
* Function: ragged_read_all
*
* Purpose: Reads all rows of a ragged array in row order a few rows at a
* time.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, August 27, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
ragged_read_all(hid_t ra, hsize_t rows_at_once)
{
int total_nelmts=0;
hsize_t i, j; /*counters */
hssize_t row; /*current row number */
hsize_t interval_nelmts; /*elmts/interval timer */
hsize_t *size=NULL; /*size of each row */
C_MTYPE **buf=NULL; /*buffer for each row */
H5_timer_t timer, timer_total; /*performance timers */
char s[64]; /*tempory string buffer */
char testname[80];
sprintf(testname, "Testing read all, units of %lu",
(unsigned long)rows_at_once);
printf("%s...\n", testname);
fflush(stdout);
timeout_g = TIME_LIMIT;
/* Create the ragged array row in memory */
if (NULL==(size = malloc(rows_at_once*sizeof(*size))) ||
NULL==(buf = malloc(rows_at_once*sizeof(*buf)))) {
puts("Memory allocation failed");
goto error;
}
/*
* Read a few rows at a time from the ragged array. Print a status report
* every once in a while too.
*/
printf(" %8s %8s %8s %10s\n",
"Row", "Nelmts", "Complete", "Bandwidth");
printf(" -------- -------- -------- ----------\n");
H5_timer_reset(&timer_total);
H5_timer_begin(&timer);
interval_nelmts = 0;
for (row=0; total_nelmts<MAX_NELMTS && timeout_g>0; row+=i) {
/* Clear data then read */
HDmemset(size, 0, rows_at_once*sizeof(*size));
HDmemset(buf, 0, rows_at_once*sizeof(*buf));
if (H5RAread(ra, row, rows_at_once, H_MTYPE, size,
(void**)buf)<0) {
goto error;
}
/* Check values read */
for (i=0; i<rows_at_once && size[i]; i++) {
interval_nelmts += size[i];
total_nelmts += size[i];
for (j=0; j<size[i]; j++) {
if (buf[i][j]!=j+1) {
printf("Wrong value(s) read for row %ld.\n",
(long)(row+i));
for (j=0; j<size[i]; j++) {
printf("%s%d", j?",":"", buf[i][j]);
}
putchar('\n');
goto error;
}
}
free(buf[i]);
buf[i] = NULL;
}
/* Print statistics? */
if (0==row || alarm_g || 0==timeout_g) {
alarm_g = 0;
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE),
timer.etime);
printf(" %8lu %8lu %7.3f%% %10s%s\n",
(unsigned long)(row+i), (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s,
0==timeout_g?" (aborting)":"");
interval_nelmts = 0;
H5_timer_begin(&timer);
}
if (0==size[rows_at_once-1]) {
/* Reached the end of the array */
if (total_nelmts<MAX_NELMTS) {
puts(" * Short read, previous write probably aborted");
}
row += i;
break;
}
}
/* Conclusions */
if (timeout_g) { /*a minor race condition, but who really cares?*/
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s\n",
(unsigned long)row, (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s);
}
printf(" -------- -------- -------- ----------\n");
H5_bandwidth(s, (double)total_nelmts*sizeof(C_MTYPE), timer_total.etime);
printf(" %27s%10s\n", "", s);
/* Cleanup */
free(size);
free(buf);
printf("%-70s PASSED\n\n", testname);
return 0;
error:
printf("%-70s*FAILED*\n\n", testname);
return -1;
}
/*-------------------------------------------------------------------------
* Function: ragged_read_short
*
* Purpose: Reads all the data but only the part that is in the `raw'
* dataset. We should see a nice speed increase because we
* don't have to perform the little reads into the overflow
* array.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Friday, August 28, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
ragged_read_short(hid_t ra, hsize_t rows_at_once, hsize_t width)
{
int total_nelmts=0;
hsize_t i, j;
hssize_t row; /*current row number */
hsize_t interval_nelmts; /*elmts/interval timer */
hsize_t read_nelmts=0; /*total elements read */
hsize_t *size=NULL; /*size of each row */
C_MTYPE **buf=NULL; /*buffer for each row */
H5_timer_t timer, timer_total; /*performance timers */
char s[64]; /*tempory string buffer */
char testname[80];
sprintf(testname, "Testing read short, units of %lu",
(unsigned long)rows_at_once);
printf("%s...\n", testname);
fflush(stdout);
timeout_g = TIME_LIMIT;
/* Create the ragged array row in memory */
if (NULL==(size = malloc(rows_at_once*sizeof(*size))) ||
NULL==(buf = malloc(rows_at_once*sizeof(*buf)))) {
puts("Memory allocation failed");
goto error;
}
for (i=0; i<rows_at_once; i++) {
if (NULL==(buf[i] = malloc(width*sizeof(C_MTYPE)))) {
puts("Memory allocation failed");
goto error;
}
}
/*
* Read a few rows at a time from the ragged array. Print a status report
* every once in a while too.
*/
printf(" %8s %8s %8s %10s\n",
"Row", "Nelmts", "Complete", "Bandwidth");
printf(" -------- -------- -------- ----------\n");
H5_timer_reset(&timer_total);
H5_timer_begin(&timer);
interval_nelmts = 0;
for (row=0; total_nelmts<MAX_NELMTS && timeout_g>0; row+=i) {
/* Read data */
for (i=0; i<rows_at_once; i++) size[i] = width;
if (H5RAread(ra, row, rows_at_once, H_MTYPE, size,
(void**)buf)<0) {
goto error;
}
/* Check values read */
for (i=0; i<rows_at_once && size[i]; i++) {
/*
* Number of useful elements actually read in this timing
* interval. This is used to calculate bandwidth.
*/
interval_nelmts += MIN(width, size[i]);
/*
* Total number of elements actually read for rows so far.
*/
read_nelmts += MIN(width, size[i]);
/*
* Total number of elements attributed to the rows read so far.
* This is used to calculate the percent done.
*/
total_nelmts += size[i];
/* Check the values */
for (j=0; j<MIN(width, size[i]); j++) {
if (buf[i][j]!=j+1) {
printf("Wrong value(s) read for row %ld.\n",
(long)(row+i));
for (j=0; j<MIN(width, size[i]); j++) {
printf("%s%d", j?",":"", buf[i][j]);
}
putchar('\n');
goto error;
}
}
}
/* Print statistics? */
if (0==row || alarm_g || 0==timeout_g) {
alarm_g = 0;
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE),
timer.etime);
printf(" %8lu %8lu %7.3f%% %10s%s\n",
(unsigned long)(row+i), (unsigned long)read_nelmts,
100.0*total_nelmts/MAX_NELMTS, s,
0==timeout_g?" (aborting)":"");
interval_nelmts = 0;
H5_timer_begin(&timer);
}
if (0==size[rows_at_once-1]) {
/* Reached the end of the array */
if (total_nelmts<MAX_NELMTS) {
puts(" * Short read, previous write probably aborted");
}
row += i;
break;
}
}
/* Conclusions */
if (timeout_g) { /*a minor race condition, but who really cares?*/
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s\n",
(unsigned long)row, (unsigned long)read_nelmts,
100.0*total_nelmts/MAX_NELMTS, s);
}
printf(" -------- -------- -------- ----------\n");
H5_bandwidth(s, (double)read_nelmts*sizeof(C_MTYPE), timer_total.etime);
printf(" %27s%10s\n", "", s);
/* Cleanup */
for (i=0; i<rows_at_once; i++) free(buf[i]);
free(size);
free(buf);
printf("%-70s PASSED\n\n", testname);
return 0;
error:
printf("%-70s*FAILED*\n\n", testname);
return -1;
}
/*-------------------------------------------------------------------------
* Function: main
*
* Purpose:
*
* Return: Success:
*
* Failure:
*
* Programmer: Robb Matzke
* Friday, August 21, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
int
main(int argc, char *argv[])
{
hid_t file, dcpl, ra;
hsize_t ch_size[2]; /*chunk size */
hsize_t rows_at_once=100; /*row aggregation */
int argno=1;
/* Parse command line options */
if (argno<argc) {
rows_at_once = strtol(argv[argno++], NULL, 0);
}
/* Display HDF5 API errors in a special way */
H5Eset_auto(display_error_cb, NULL);
/* Get a SIGALRM every few seconds */
#ifdef HAVE_SIGACTION
{
struct sigaction act;
act.sa_handler = catch_alarm;
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
alarm(1);
}
#else
puts("No sigaction(). This test may run for a *long* time.");
#endif
/* Create the file and ragged array */
if ((file=H5Fcreate("ragged.h5", H5F_ACC_TRUNC, H5P_DEFAULT,
H5P_DEFAULT))<0) goto error;
if ((dcpl=H5Pcreate(H5P_DATASET_CREATE))<0) goto error;
ch_size[1] = 20;
ch_size[0] = MAX(1, CH_SIZE/(ch_size[1]*sizeof(C_MTYPE))); /*length*/
printf("Chunk size is %lu by %lu\n",
(unsigned long)(ch_size[0]), (unsigned long)(ch_size[1]));
if (H5Pset_chunk(dcpl, 2, ch_size)<0) goto error;
if ((ra=H5RAcreate(file, "ra", H_FTYPE, dcpl))<0) goto error;
if (H5Pclose(dcpl)<0) goto error;
/* The tests */
if (ragged_write_all(ra, rows_at_once)<0) goto error;
if (ragged_read_all(ra, rows_at_once)<0) goto error;
if (ragged_read_short(ra, rows_at_once, ch_size[1])<0) goto error;
/* The tests again */
if (ragged_write_all(ra, rows_at_once)<0) goto error;
if (ragged_read_all(ra, rows_at_once)<0) goto error;
if (ragged_read_short(ra, rows_at_once, ch_size[1])<0) goto error;
/* Conclusions */
printf("\n\nDistribution of row lengths:\n");
rand_nelmts(1);
/* Cleanup */
if (H5RAclose(ra)<0) goto error;
if (H5Fclose(file)<0) goto error;
puts("All ragged array tests passed.");
return 0;
error:
puts("*** RAGGED ARRAY TEST(S) FAILED ***");
return -1;
}