summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-07-06 23:02:32 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-07-06 23:02:32 (GMT)
commitcf419d05ab65b423bc4ce395972e84522ca3eec5 (patch)
tree6f689a9e56f4e251f51aacec02a067b9f8d232a1
parent4d3351f1d777bc3cb891443b6165a87251d4e643 (diff)
downloadhdf5-cf419d05ab65b423bc4ce395972e84522ca3eec5.zip
hdf5-cf419d05ab65b423bc4ce395972e84522ca3eec5.tar.gz
hdf5-cf419d05ab65b423bc4ce395972e84522ca3eec5.tar.bz2
[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.
-rwxr-xr-xbin/trace3
-rw-r--r--config/irix5.32
-rw-r--r--src/H5S.c2
-rw-r--r--src/H5T.c34
-rw-r--r--src/H5Tconv.c16
-rw-r--r--test/.distdep4
-rw-r--r--test/dtypes.c211
7 files changed, 202 insertions, 70 deletions
diff --git a/bin/trace b/bin/trace
index a124d5c..f190857 100755
--- a/bin/trace
+++ b/bin/trace
@@ -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;
}
diff --git a/config/irix5.3 b/config/irix5.3
index c0064ef..acc375e 100644
--- a/config/irix5.3
+++ b/config/irix5.3
@@ -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?
diff --git a/src/H5S.c b/src/H5S.c
index ad4cb1a..7ebf490 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -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) {
diff --git a/src/H5T.c b/src/H5T.c
index 4fe6078..8026516 100644
--- a/src/H5T.c
+++ b/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;
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 800a9ea..930b330 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -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;
diff --git a/test/.distdep b/test/.distdep
index a2fcc62..5706161 100644
--- a/test/.distdep
+++ b/test/.distdep
@@ -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 \
diff --git a/test/dtypes.c b/test/dtypes.c
index 2cab029..e9e8f06 100644
--- a/test/dtypes.c
+++ b/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
@@ -675,6 +709,74 @@ test_conv_int (void)
/*-------------------------------------------------------------------------
+ * 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
*
* Purpose: Test conversion of random floating point values from SRC to
@@ -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",