summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2010-06-28 22:49:13 -0700
committerDavid Schleef <ds@schleef.org>2010-06-28 22:49:13 -0700
commit27b37e8aa7faff838b86fdf9857f9ad81497f1b5 (patch)
treea6ac073b4bf542c92d3fde0bb68096d12bed8a3a
parentb4827cb58bef287d341e6f7518d3354550d0e3b9 (diff)
downloadorc-27b37e8aa7faff838b86fdf9857f9ad81497f1b5.tar.gz
tests: better float comparison
Allow denormals to be flushed to 0. Check for NaNs.
-rw-r--r--orc-test/orcarray.c10
-rw-r--r--orc-test/orctest.c32
2 files changed, 35 insertions, 7 deletions
diff --git a/orc-test/orcarray.c b/orc-test/orcarray.c
index da19a65..4c21be2 100644
--- a/orc-test/orcarray.c
+++ b/orc-test/orcarray.c
@@ -58,11 +58,12 @@ orc_array_set_random (OrcArray *array, OrcRandomContext *context)
orc_random_bits (context, array->alloc_data, array->alloc_len);
}
+#define MIN_NONDENORMAL (1.1754944909521339405e-38)
int
orc_array_compare (OrcArray *array1, OrcArray *array2, int flags)
{
- if (flags & ORC_TEST_FLAGS_FLOAT && array1->element_size == 4) {
+ if ((flags & ORC_TEST_FLAGS_FLOAT) && array1->element_size == 4) {
int j;
for(j=0;j<array1->m;j++){
float *a, *b;
@@ -72,9 +73,10 @@ orc_array_compare (OrcArray *array1, OrcArray *array2, int flags)
b = ORC_PTR_OFFSET (array2->data, j*array2->stride);
for (i=0;i<array1->n;i++){
- if (!((isnan(a[i]) && isnan(b[i])) || a[i] == b[i])) {
- return FALSE;
- }
+ if (isnan(a[i]) && isnan(b[i])) continue;
+ if (a[i] == b[i]) continue;
+ if (fabs(a[i] - b[i]) < MIN_NONDENORMAL) continue;
+ return FALSE;
}
}
return TRUE;
diff --git a/orc-test/orctest.c b/orc-test/orctest.c
index 90e2cc7..2a1373a 100644
--- a/orc-test/orctest.c
+++ b/orc-test/orctest.c
@@ -18,6 +18,8 @@
#define isnan(x) _isnan(x)
#endif
+#define MIN_NONDENORMAL (1.1754944909521339405e-38)
+
void _orc_profile_init(void);
OrcRandomContext rand_context;
@@ -454,6 +456,27 @@ print_array_val_float (OrcArray *array, int i, int j)
}
}
+int
+float_compare (OrcArray *array1, OrcArray *array2, int i, int j)
+{
+ void *ptr1 = ORC_PTR_OFFSET (array1->data,
+ i*array1->element_size + j*array1->stride);
+ void *ptr2 = ORC_PTR_OFFSET (array2->data,
+ i*array2->element_size + j*array2->stride);
+
+ switch (array1->element_size) {
+ case 4:
+ if (isnan(*(float *)ptr1) && isnan(*(float *)ptr2)) return TRUE;
+ if (*(float *)ptr1 == *(float *)ptr2) return TRUE;
+ if (fabs(*(float *)ptr1 - *(float *)ptr2) < MIN_NONDENORMAL) return TRUE;
+ return FALSE;
+ case 8:
+ /* FIXME */
+ return FALSE;
+ }
+ return FALSE;
+}
+
OrcTestResult
orc_test_compare_output (OrcProgram *program)
{
@@ -617,12 +640,15 @@ orc_test_compare_output_full (OrcProgram *program, int flags)
if (flags & ORC_TEST_FLAGS_FLOAT) {
a = print_array_val_float (dest_emul[l-ORC_VAR_D1], i, j);
b = print_array_val_float (dest_exec[l-ORC_VAR_D1], i, j);
+ if (!float_compare (dest_emul[l-ORC_VAR_D1], dest_exec[l-ORC_VAR_D1], i, j) != 0) {
+ line_bad = TRUE;
+ }
} else {
a = print_array_val_hex (dest_emul[l-ORC_VAR_D1], i, j);
b = print_array_val_hex (dest_exec[l-ORC_VAR_D1], i, j);
- }
- if (a != b) {
- line_bad = TRUE;
+ if (a != b) {
+ line_bad = TRUE;
+ }
}
}
}