diff options
author | David Schleef <ds@schleef.org> | 2010-06-28 22:49:13 -0700 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2010-06-28 22:49:13 -0700 |
commit | 27b37e8aa7faff838b86fdf9857f9ad81497f1b5 (patch) | |
tree | a6ac073b4bf542c92d3fde0bb68096d12bed8a3a /orc-test | |
parent | b4827cb58bef287d341e6f7518d3354550d0e3b9 (diff) |
tests: better float comparison
Allow denormals to be flushed to 0. Check for NaNs.
Diffstat (limited to 'orc-test')
-rw-r--r-- | orc-test/orcarray.c | 10 | ||||
-rw-r--r-- | orc-test/orctest.c | 32 |
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; + } } } } |