mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-19 16:50:46 +08:00
[svn-r454] Changes since 19980702
---------------------- ./src/H5T.c Prints statistics for no-op conversions also. For now, hardware floating point conversions may or may not raise SIGFPE depending on the hardware, operating system, etc. Software conversions never raise SIGFPE and use +Inf or -Inf for overflow. ./test/dtypes.c Catches SIGFPE and causes the test to be skipped. Better test for NaN. ./config/irix5.3 Removed the -U_POSIX_SOURCE because it was removed from the main makefiles. ./bin/trace ./src/H5S.c Fixed a typo that prevented tracing info from being added to new API functions.
This commit is contained in:
parent
4d3351f1d7
commit
cf419d05ab
@ -157,10 +157,11 @@ sub rewrite_func ($$$$$) {
|
||||
}
|
||||
} elsif ($body =~ s/((\n[ \t]*)H5TRACE\d+\s*\(.*?\);)\n/"$2$trace"/es) {
|
||||
# Replaced an H5TRACE macro
|
||||
} elsif ($body=~s/((\n[ \t]*)FUNC_ENTER\s*\([ \t]*?\);)\n/"$1$2$trace"/es) {
|
||||
} elsif ($body=~s/((\n[ \t]*)FUNC_ENTER\s*\(.*?\);)\n/"$1$2$trace"/es) {
|
||||
# Added an H5TRACE macro after a FUNC_ENTER macro.
|
||||
} else {
|
||||
errmesg $file, $name, "unable to insert tracing information";
|
||||
print "body=\n>>>>>", $body, "<<<<<\n";
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ CC=cc
|
||||
RANLIB=:
|
||||
|
||||
# What must *always* be present for things to compile correctly?
|
||||
CFLAGS="$CFLAGS -U_POSIX_SOURCE -ansi -fullwarn -woff 799"
|
||||
CFLAGS="$CFLAGS -ansi -fullwarn -woff 799"
|
||||
#CPPFLAGS="$CPPFLAGS -I."
|
||||
|
||||
# What compiler flags should be used for code development?
|
||||
|
@ -1026,6 +1026,7 @@ H5Sset_extent_simple (hid_t sid, int rank, const hsize_t *dims, const hsize_t *m
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER(H5Sset_extent_simple, FAIL);
|
||||
H5TRACE4("e","iIs*h*h",sid,rank,dims,max);
|
||||
|
||||
/* Check args */
|
||||
if ((space = H5I_object(sid)) == NULL) {
|
||||
@ -1336,6 +1337,7 @@ H5Screate_simple (int rank, const hsize_t *dims, const hsize_t *maxdims)
|
||||
int i;
|
||||
|
||||
FUNC_ENTER(H5Screate, FAIL);
|
||||
H5TRACE3("i","Is*h*h",rank,dims,maxdims);
|
||||
|
||||
/* Check arguments */
|
||||
if (rank<0) {
|
||||
|
34
src/H5T.c
34
src/H5T.c
@ -679,6 +679,7 @@ H5T_term_interface(void)
|
||||
#ifdef H5T_DEBUG
|
||||
intn nprint=0;
|
||||
hsize_t nbytes;
|
||||
H5T_cdata_t *cdata;
|
||||
#endif
|
||||
|
||||
/* Unregister all conversion functions */
|
||||
@ -734,6 +735,39 @@ H5T_term_interface(void)
|
||||
H5T_path_g[i] = NULL;
|
||||
}
|
||||
|
||||
#ifdef H5T_DEBUG
|
||||
/* Print debugging infor for the `noop' conversion */
|
||||
if (H5T_conv_noop==H5T_find(NULL, NULL, H5T_BKG_NO, &cdata)) {
|
||||
if (cdata->stats->ncalls>0) {
|
||||
if (0==nprint++) {
|
||||
HDfprintf (stderr, "H5T: type conversion statistics "
|
||||
"accumulated over life of library:\n");
|
||||
HDfprintf (stderr, " %-*s %8s/%-5s %8s %8s %8s %15s\n",
|
||||
H5T_NAMELEN-1, "Name", "Elmts", "Calls", "User",
|
||||
"System", "Elapsed", "Bandwidth");
|
||||
HDfprintf (stderr, " %-*s %8s-%-5s %8s %8s %8s %15s\n",
|
||||
H5T_NAMELEN-1, "----", "-----", "-----", "----",
|
||||
"------", "-------", "---------");
|
||||
}
|
||||
nbytes = cdata->stats->nelmts;
|
||||
HDfprintf (stderr,
|
||||
" %-*s %8Hd/%-5d %8.2f %8.2f %8.2f",
|
||||
H5T_NAMELEN-1, "no-op",
|
||||
cdata->stats->nelmts,
|
||||
cdata->stats->ncalls,
|
||||
cdata->stats->timer.utime,
|
||||
cdata->stats->timer.stime,
|
||||
cdata->stats->timer.etime);
|
||||
if (cdata->stats->timer.etime>0) {
|
||||
HDfprintf (stderr, " %15g\n",
|
||||
nbytes / cdata->stats->timer.etime);
|
||||
} else {
|
||||
HDfprintf (stderr, " %15s\n", "Inf");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear conversion tables */
|
||||
H5T_apath_g = 0;
|
||||
H5T_npath_g = 0;
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <H5Eprivate.h>
|
||||
#include <H5MMprivate.h>
|
||||
#include <H5Tpkg.h>
|
||||
#include <float.h> /*for FLT_MAX and FLT_MIN */
|
||||
#include <math.h> /*for ceil() */
|
||||
|
||||
/* Conversion data for H5T_conv_struct() */
|
||||
@ -1350,19 +1349,8 @@ H5T_conv_double_float (hid_t __unused__ src_id, hid_t __unused__ dst_id,
|
||||
s = (double*)buf;
|
||||
d = (float*)buf;
|
||||
|
||||
/*
|
||||
* We have to watch out because some machines generate a SIGFPE if
|
||||
* the source has a larger magnitude than can be represented in the
|
||||
* destination.
|
||||
*/
|
||||
for (elmtno=0; elmtno<nelmts; elmtno++, d++, s++) {
|
||||
if (*s > FLT_MAX) {
|
||||
*d = FLT_MAX;
|
||||
} else if (*s < -FLT_MAX) {
|
||||
*d = -FLT_MAX;
|
||||
} else {
|
||||
*d = *s;
|
||||
}
|
||||
for (elmtno=0; elmtno<nelmts; elmtno++) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -182,7 +182,9 @@ dtypes.o: \
|
||||
../src/H5Tpkg.h \
|
||||
../src/H5HGprivate.h \
|
||||
../src/H5Fprivate.h \
|
||||
../src/H5private.h
|
||||
../src/H5private.h \
|
||||
../src/H5Tprivate.h \
|
||||
../src/H5Gprivate.h
|
||||
hyperslab.o: \
|
||||
hyperslab.c \
|
||||
../src/H5private.h \
|
||||
|
211
test/dtypes.c
211
test/dtypes.c
@ -8,12 +8,13 @@
|
||||
* Purpose: Tests the data type interface (H5T)
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <hdf5.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define H5T_PACKAGE
|
||||
@ -52,6 +53,39 @@ typedef enum flt_t {
|
||||
FLT_FLOAT, FLT_DOUBLE, FLT_LDOUBLE, FLT_OTHER
|
||||
} flt_t;
|
||||
|
||||
/*
|
||||
* Some machines generate SIGFPE on floating point overflows. According to
|
||||
* the Posix standard, we cannot assume that we can continue from such a
|
||||
* signal. Therefore, if the following constant is defined then tests that
|
||||
* might raise SIGFPE are executed in a child process.
|
||||
*/
|
||||
#define HANDLE_SIGFPE
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: fpe_handler
|
||||
*
|
||||
* Purpose: Exit with 255
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Monday, July 6, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifdef HANDLE_SIGFPE
|
||||
static void
|
||||
fpe_handler(int __unused__ signo)
|
||||
{
|
||||
puts(" -SKIP-");
|
||||
puts(" Test skipped due to SIGFPE from probable overflow.");
|
||||
exit(255);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: cleanup
|
||||
@ -673,6 +707,74 @@ test_conv_int (void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: my_isnan
|
||||
*
|
||||
* Purpose: Determines whether VAL points to NaN.
|
||||
*
|
||||
* Return: TRUE or FALSE
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Monday, July 6, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
my_isnan(flt_t type, void *val)
|
||||
{
|
||||
int retval;
|
||||
char s[256];
|
||||
|
||||
switch (type) {
|
||||
case FLT_FLOAT:
|
||||
retval = (*((float*)val)!=*((float*)val));
|
||||
break;
|
||||
|
||||
case FLT_DOUBLE:
|
||||
retval = (*((double*)val)!=*((double*)val));
|
||||
break;
|
||||
|
||||
case FLT_LDOUBLE:
|
||||
retval = (*((long double*)val)!=*((long double*)val));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sometimes NaN==NaN (e.g., DEC Alpha) so we try to print it and see if
|
||||
* the result contains a NaN string.
|
||||
*/
|
||||
if (!retval) {
|
||||
switch (type) {
|
||||
case FLT_FLOAT:
|
||||
sprintf(s, "%g", *((float*)val));
|
||||
break;
|
||||
|
||||
case FLT_DOUBLE:
|
||||
sprintf(s, "%g", *((double*)val));
|
||||
break;
|
||||
|
||||
case FLT_LDOUBLE:
|
||||
sprintf(s, "%Lg", *((long double*)val));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strstr(s, "NaN") || !strstr(s, "NAN") || !strstr(s, "nan")) {
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_conv_flt_1
|
||||
@ -714,6 +816,39 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
||||
size_t i, j, k; /*counters */
|
||||
int endian; /*machine endianess */
|
||||
|
||||
#ifdef HANDLE_SIGFPE
|
||||
pid_t child_pid; /*process ID of child */
|
||||
int status; /*child exit status */
|
||||
|
||||
/*
|
||||
* Some systems generage SIGFPE during floating point overflow and we
|
||||
* cannot assume that we can continue from such a signal. Therefore, we
|
||||
* fork here and let the child run the test and return the number of
|
||||
* failures with the exit status.
|
||||
*/
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
if ((child_pid=fork())<0) {
|
||||
perror("fork");
|
||||
return 1;
|
||||
} else if (child_pid>0) {
|
||||
while (child_pid!=waitpid(child_pid, &status, 0)) /*void*/;
|
||||
if (WIFEXITED(status) && 255==WEXITSTATUS(status)) {
|
||||
return 0; /*child exit after catching SIGFPE*/
|
||||
} else if (WIFEXITED(status)) {
|
||||
return WEXITSTATUS(status);
|
||||
} else {
|
||||
puts(" Child didn't exit normally.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The remainder of this function is executed only by the child.
|
||||
*/
|
||||
signal(SIGFPE,fpe_handler);
|
||||
#endif
|
||||
|
||||
/* What are the names of the source and destination types */
|
||||
if (H5Tequal(src, H5T_NATIVE_FLOAT)) {
|
||||
src_type_name = "float";
|
||||
@ -785,6 +920,9 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
||||
|
||||
/* Check the software results against the hardware */
|
||||
for (j=0; j<nelmts; j++) {
|
||||
hw_f = 911.0;
|
||||
hw_d = 911.0;
|
||||
hw_ld = 911.0;
|
||||
|
||||
/* The hardware conversion */
|
||||
if (FLT_FLOAT==src_type) {
|
||||
@ -800,14 +938,7 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
||||
}
|
||||
} else if (FLT_DOUBLE==src_type) {
|
||||
if (FLT_FLOAT==dst_type) {
|
||||
/* Watch out for that FPE on overflow! */
|
||||
if (((double*)saved)[j] > FLT_MAX) {
|
||||
hw_f = FLT_MAX;
|
||||
} else if (((double*)saved)[j] < -FLT_MAX) {
|
||||
hw_f = -FLT_MAX;
|
||||
} else {
|
||||
hw_f = ((double*)saved)[j];
|
||||
}
|
||||
hw_f = ((double*)saved)[j];
|
||||
hw = (unsigned char*)&hw_f;
|
||||
} else if (FLT_DOUBLE==dst_type) {
|
||||
hw_d = ((double*)saved)[j];
|
||||
@ -818,24 +949,10 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
||||
}
|
||||
} else {
|
||||
if (FLT_FLOAT==dst_type) {
|
||||
/* Watch out for that FPE on overflow! */
|
||||
if (((long double*)saved)[j] > FLT_MAX) {
|
||||
hw_f = FLT_MAX;
|
||||
} else if (((long double*)saved)[j] < -FLT_MAX) {
|
||||
hw_f = -FLT_MAX;
|
||||
} else {
|
||||
hw_f = ((long double*)saved)[j];
|
||||
}
|
||||
hw_f = ((long double*)saved)[j];
|
||||
hw = (unsigned char*)&hw_f;
|
||||
} else if (FLT_DOUBLE==dst_type) {
|
||||
/* Watch out for that FPE! */
|
||||
if (((long double*)saved)[j] > DBL_MAX) {
|
||||
hw_d = DBL_MAX;
|
||||
} else if (((long double*)saved)[j] < -DBL_MAX) {
|
||||
hw_d = -DBL_MAX;
|
||||
} else {
|
||||
hw_d = ((long double*)saved)[j];
|
||||
}
|
||||
hw_d = ((long double*)saved)[j];
|
||||
hw = (unsigned char*)&hw_d;
|
||||
} else {
|
||||
hw_ld = ((long double*)saved)[j];
|
||||
@ -857,16 +974,16 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
||||
* pattern for NaN by setting the significand to all ones.
|
||||
*/
|
||||
if (FLT_FLOAT==dst_type &&
|
||||
((float*)buf)[j]!=((float*)buf)[j] &&
|
||||
((float*)hw)[0]!=((float*)hw)[0]) {
|
||||
my_isnan(dst_type, (float*)buf+j) &&
|
||||
my_isnan(dst_type, hw)) {
|
||||
continue;
|
||||
} else if (FLT_DOUBLE==dst_type &&
|
||||
((double*)buf)[j]!=((double*)buf)[j] &&
|
||||
((double*)hw)[0]!=((double*)hw)[0]) {
|
||||
my_isnan(dst_type, (double*)buf+j) &&
|
||||
my_isnan(dst_type, hw)) {
|
||||
continue;
|
||||
} else if (FLT_LDOUBLE==dst_type &&
|
||||
((long double*)buf)[j]!=((long double*)buf)[j] &&
|
||||
((long double*)hw)[0]!=((long double*)hw)[0]) {
|
||||
my_isnan(dst_type, (long double*)buf+j) &&
|
||||
my_isnan(dst_type, hw)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@ -877,16 +994,7 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
||||
* hardware conversions on some machines return NaN instead of
|
||||
* overflowing to +Inf or -Inf or underflowing to +0 or -0.
|
||||
*/
|
||||
if (FLT_FLOAT==dst_type &&
|
||||
*((float*)hw)!=*((float*)hw)) {
|
||||
continue;
|
||||
} else if (FLT_DOUBLE==dst_type &&
|
||||
*((double*)hw)!=*((double*)hw)) {
|
||||
continue;
|
||||
} else if (FLT_LDOUBLE==dst_type &&
|
||||
*((long double*)hw)!=*((long double*)hw)) {
|
||||
continue;
|
||||
}
|
||||
if (my_isnan(dst_type, hw)) continue;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
@ -970,12 +1078,20 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
||||
done:
|
||||
if (buf) free (buf);
|
||||
if (saved) free (saved);
|
||||
#ifdef HANDLE_SIGFPE
|
||||
exit(MIN((int)fails_all_tests, 254));
|
||||
#else
|
||||
return (int)fails_all_tests;
|
||||
#endif
|
||||
|
||||
error:
|
||||
if (buf) free (buf);
|
||||
if (saved) free (saved);
|
||||
return (int)MIN(1, fails_all_tests);
|
||||
#ifdef HANDLE_SIGFPE
|
||||
exit(MIN(MAX((int)fails_all_tests, 1), 254));
|
||||
#else
|
||||
return MAX((int)fails_all_tests, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1000,10 +1116,6 @@ main(void)
|
||||
{
|
||||
unsigned long nerrors = 0;
|
||||
|
||||
#if 0
|
||||
signal(SIGFPE,SIG_IGN);
|
||||
#endif
|
||||
|
||||
/* Set the error handler */
|
||||
H5Eset_auto (display_error_cb, NULL);
|
||||
|
||||
@ -1015,12 +1127,6 @@ main(void)
|
||||
nerrors += test_named ()<0 ? 1 : 0;
|
||||
nerrors += test_conv_int ()<0 ? 1 : 0;
|
||||
|
||||
#ifndef LATER
|
||||
/*
|
||||
* NOT READY FOR TESTING YET BECAUSE SOME SYSTEMS GENERATE A SIGFPE WHEN
|
||||
* AN OVERFLOW OCCURS CASTING A DOUBLE TO A FLOAT.
|
||||
*/
|
||||
#else
|
||||
/* Test degenerate cases */
|
||||
nerrors += test_conv_flt_1("noop", H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT);
|
||||
nerrors += test_conv_flt_1("noop", H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE);
|
||||
@ -1038,7 +1144,6 @@ main(void)
|
||||
nerrors += test_conv_flt_1("sw", H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE);
|
||||
nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT);
|
||||
nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE);
|
||||
#endif
|
||||
|
||||
if (nerrors) {
|
||||
printf("***** %lu FAILURE%s! *****\n",
|
||||
|
Loading…
x
Reference in New Issue
Block a user