From aa3767e7910105cf641ceea2351786d424cfd8d2 Mon Sep 17 00:00:00 2001 From: Massimiliano Fasi Date: Sun, 2 Jun 2024 08:11:45 +0100 Subject: [PATCH 1/2] Fix inconsistencies and speed in C tests * Delete unused macros * Delete mostly unused types * Replace format binary16 with E5M2 * Split overly large tests * Fix duplicate test names * Remove in-place tests that use same array as input --- test/cpfloat_test.ts | 48 ++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/test/cpfloat_test.ts b/test/cpfloat_test.ts index fb3d791..233775b 100644 --- a/test/cpfloat_test.ts +++ b/test/cpfloat_test.ts @@ -35,17 +35,15 @@ typedef union { #define CONST_PI 3.14159265358979323846 #define CONST_SQRT2 1.41421356237309504880 -#define MINFORMAT 0 -#define MAXFORMAT 2 #define MINMODE -1 #define MAXMODE 8 #define NREPS 1000 /* Define default target formats. */ -// binary16, bfloat16, TensorFloat-32 -static size_t precision [] = {11, 8, 11}; -static size_t emax [] = {15, 127, 127}; -static size_t emin [] = {-14, -126, -126}; +// E5M2, bfloat16 +static size_t precision [] = {3, 8}; +static size_t emax [] = {15, 127}; +static size_t emin [] = {-14, -126}; static size_t nformats = 2; /* Structure for options and fixtures. */ @@ -324,7 +322,7 @@ void check_equality_double(double *x, double *y, size_t n) { for (size_t j = 0; j < n; j++) { if (!nan_safe_compare_double(x[j], y[j])) { printf("DOUBLE\n"); - printf("***\nj = %ld\nx = %23.15e [%" PRIu64 "]\ny = %23.15e [%" PRIu64 "]\n", + printf("***\nj = %ld\nx = %23.15e [%" PRIu64 "]\ny = %23.15e [%" PRIu64 "]\n", j, x[j], *(uint64_t *)(x + j), y[j], *(uint64_t *)(y + j)); @@ -338,7 +336,7 @@ void check_equality_double_int(double *x, int *y, size_t n) { for (size_t j = 0; j < n; j++) { if (!nan_safe_compare_double(x[j], y[j])) { printf("DOUBLE\n"); - printf("***\nj = %ld\nx = %23.15e [%" PRIu64 "]\ny = %23.15e\n", + printf("***\nj = %ld\nx = %23.15e [%" PRIu64 "]\ny = %23.15e\n", j, x[j], *(uint64_t *)(x + j), (double)y[j]); } ck_assert(nan_safe_compare_double(x[j], (double)y[j])); @@ -916,7 +914,7 @@ for (size_t mode = 1; mode < 3; mode++) { double *zd = alloc_init_array_double(xd, n); double *yd = allocate_array_double(xd, n, mode); select_tests_det_double(yd, xd, zd, n, fpopts, - MINMODE, MAXMODE, 0, 2, -1, -1); + MINMODE, MAXMODE, 0, nformats - 1, -1, -1); free(zd); free_array_double(yd, mode); @@ -924,7 +922,7 @@ for (size_t mode = 1; mode < 3; mode++) { float *zf = alloc_init_array_float(xf, n); float *yf = allocate_array_float(xf, n, mode); select_tests_det_float(yf, xf, zf, n, fpopts, - MINMODE, MAXMODE, 0, 2, -1, -1); + MINMODE, MAXMODE, 0, nformats - 1, -1, -1); free(zf); free_array_float(yf, mode); } @@ -2624,13 +2622,16 @@ free(onef); free(exp); free(lexp); -#test enumeration_floating_point_numbers -printf("4c. Next and previous floating-point number\n"); +#test floating_point_enumeration_subnormal_numbers +printf("4c. Next and previous floating-point number: subnormal numbers\n"); +fpopts->infinity = CPFLOAT_INF_USE; fpopts->explim = CPFLOAT_EXPRANGE_TARG; +fpopts->saturation = CPFLOAT_SAT_NO; fpopts->subnormal = CPFLOAT_SUBN_USE; -// Subnormals -for (size_t mode = 2; mode < 3; mode++) { +fpopts->round = CPFLOAT_RND_NE; +for (size_t mode = 3; mode < 3; mode++) { for (size_t i = 0; i < nformats; i++) { + fpopts->precision = precision[i]; fpopts->emax = emax[i]; fpopts->emin = emin[i]; @@ -2653,8 +2654,10 @@ for (size_t mode = 2; mode < 3; mode++) { copy_array_double(ad, refd, n); cpf_nexttoward(xd, ad, infl, n-1, fpopts); check_equality_double(xd, refd+1, n-1); + csign_intarray_double((uint64_t *)infd, n); - for (size_t j = 0; j < n; j++) infl[j] = -infl[j]; + for (size_t j = 0; j < n; j++) + infl[j] = -infl[j]; copy_array_double(ad, refd, n); cpf_nextafter(xd, ad+1, infd, n-1, fpopts); check_equality_double(xd, refd, n-1); @@ -2669,8 +2672,10 @@ for (size_t mode = 2; mode < 3; mode++) { copy_array_double(ad, refd, n); cpf_nexttoward(xd, ad+1, infl, n-1, fpopts); check_equality_double(xd, refd, n-1); + csign_intarray_double((uint64_t *) infd, n); - for (size_t j = 0; j < n; j++) infl[j] = -infl[j]; + for (size_t j = 0; j < n; j++) + infl[j] = -infl[j]; copy_array_double(ad, refd, n); cpf_nextafter(xd, ad, infd, n-1, fpopts); check_equality_double(xd, refd+1, n-1); @@ -2729,8 +2734,9 @@ for (size_t mode = 2; mode < 3; mode++) { } } -// Normals -for (size_t mode = 2; mode < 3; mode++) { +#test floating_point_enumeration_normal_numbers +printf("4d. Next and previous floating-point number: normal numbers\n"); +for (size_t mode = 3; mode < 3; mode++) { for (size_t i = 0; i < nformats; i++) { fpopts->precision = precision[i]; fpopts->emax = emax[i]; @@ -2839,12 +2845,10 @@ for (size_t mode = 2; mode < 3; mode++) { } #test integer_rounding -printf("4c. Integer rounding\n"); - +printf("4e. Integer rounding\n"); fpopts->emax = emax[1]; fpopts->emin = emin[1]; fpopts->precision = precision[1]; - size_t n = 32; double *xd = malloc(n * sizeof(*xd)); int *xi = malloc(n * sizeof(*xi)); @@ -3012,7 +3016,7 @@ check_equality_double_long_long(rd7, xll, n-3); #test arithmetic_operations_large -printf("4d. Arithmetic operations on large arrays\n"); +printf("4f. Arithmetic operations on large arrays\n"); size_t i = 0; fpopts->precision = precision[i]; fpopts->emax = emax[i]; From 43a882f4a951f904b54f9c8528b3a568cea4c8c3 Mon Sep 17 00:00:00 2001 From: Massimiliano Fasi Date: Tue, 4 Jun 2024 10:48:33 +0100 Subject: [PATCH 2/2] Fix bug in tests to deal with non-IEEE exponent ranges --- test/cpfloat_test.ts | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/test/cpfloat_test.ts b/test/cpfloat_test.ts index 233775b..074f6f2 100644 --- a/test/cpfloat_test.ts +++ b/test/cpfloat_test.ts @@ -496,7 +496,9 @@ void check_array_stoc_double(double *tmpin, double *tmpout, ck_abort_msg("Not rounding to either closest number."); fpopts->round = mode; if (fabs(counter[0]/NREPS - prounddown[i % 3]) > 0.1) { - printf("%e\n", fabs(counter[0]/NREPS - prounddown[i % 3])); + printf("DOUBLE\n"); + printf("***\ni = %ld\nexp = %23.15e\nact = %23.15e\n", + i, counter[0]/NREPS, prounddown[i % 3]); ck_abort_msg("Error in stochasting rounding."); } } @@ -527,7 +529,9 @@ void check_array_stoc_float(float *tmpin, float *tmpout, ck_abort_msg("Not rounding to either closest number."); fpopts->round = mode; if (fabs(counter[0]/(double)NREPS - prounddown[i % 3]) > 0.1) { - printf("%e\n", fabs(counter[0]/NREPS - prounddown[i % 3])); + printf("FLOAT\n"); + printf("***\ni = %ld\nexp = %23.15e\nact = %23.15e\n", + i, counter[0]/NREPS, prounddown[i % 3]); ck_abort_msg("Error in stochasting rounding."); } } @@ -548,7 +552,9 @@ void check_array_equi_double(double *tmpin, double *tmpout, else counter[0]++; if (fabs(counter[0]/NREPS - *prounddown) > 0.1) { - printf("%e\n", fabs(counter[0]/NREPS - prounddown[i % 3])); + printf("DOUBLE\n"); + printf("***\ni = %ld\nexp = %23.15e\nact = %23.15e\n", + i, counter[0]/NREPS, prounddown[i % 3]); ck_abort_msg("Error in stochasting rounding."); } } @@ -569,7 +575,9 @@ void check_array_equi_float(float *tmpin, float *tmpout, else counter[0]++; if (fabs(counter[0]/(double)NREPS - *prounddown) > 0.1) { - printf("%e\n", fabs(counter[0]/NREPS - prounddown[i % 3])); + printf("FLOAT\n"); + printf("***\ni = %ld\nexp = %23.15e\nact = %23.15e\n", + i, counter[0]/NREPS, prounddown[i % 3]); ck_abort_msg("Error in stochasting rounding."); } } @@ -974,7 +982,8 @@ for (size_t mode = 1; mode < 3; mode++) { fpopts->precision = precision[i]; fpopts->emax = emax[i]; fpopts->emin = emin[i]; - size_t n = ldexp(1., fpopts->precision-1) * 2 * fpopts->emax; + size_t n = ldexp(1., fpopts->precision-1) * + (fpopts->emax - fpopts->emin + 1); uint64_t *xd = malloc(n * sizeof(*xd)); init_intarray_double(xd, n, intminnormal_double(fpopts), 1ul << (52-fpopts->precision + 1)); @@ -1690,7 +1699,8 @@ for (size_t mode = 1; mode < 3; mode++) { fpopts->precision = precision[i]; fpopts->emax = emax[i]; fpopts->emin = emin[i]; - size_t n = 3 * (ldexp(1., fpopts->precision-1) * 2 * fpopts->emax - 1); + size_t n = 3 * + (ldexp(1., fpopts->precision-1) * (fpopts->emax - fpopts->emin + 1) - 1); uint64_t *xd_imm = malloc(n * sizeof(*xd_imm)); uint64_t *refd = malloc(n * sizeof(*refd)); double *xd = malloc(n * sizeof(*xd)); @@ -2103,7 +2113,8 @@ for (size_t mode = 1; mode < 3; mode++ ) { fpopts->emax = emax[i]; fpopts->emin = emin[i]; - size_t n = 3 * (ldexp(1., fpopts->precision-1) * 2 * fpopts->emax - 1); + size_t n = 3 * (ldexp(1., fpopts->precision-1) + * (fpopts->emax - fpopts->emin +1) - 1); uint64_t *xd = malloc(n * sizeof(*xd)); double xmin = minnormal(fpopts); uint64_t stepd = 1ul << (52-fpopts->precision + 1); @@ -2742,7 +2753,8 @@ for (size_t mode = 3; mode < 3; mode++) { fpopts->emax = emax[i]; fpopts->emin = emin[i]; - size_t n = ldexp(1., fpopts->precision-1) * 2 * fpopts->emax + 2; + size_t n = ldexp(1., fpopts->precision-1) * + (fpopts->emax - fpopts->emin + 1) + 2; double *ad = malloc(n * sizeof(*ad)); double *xd = allocate_array_double(ad, n, mode); double *refd = malloc(n * sizeof(*refd));