aboutsummaryrefslogtreecommitdiff
path: root/math
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@redhat.com>2013-04-06 16:22:47 -0400
committerCarlos O'Donell <carlos@redhat.com>2013-04-06 16:22:47 -0400
commit26510bdda1ab999041292737d1fad6aa25f9e06d (patch)
tree71297531eeb946e15b07748b7ad4fab6de816228 /math
parenta01f19c8fb12eef419d4112879bc715e2ab6f6d7 (diff)
downloadglibc-26510bdda1ab999041292737d1fad6aa25f9e06d.zip
glibc-26510bdda1ab999041292737d1fad6aa25f9e06d.tar.gz
glibc-26510bdda1ab999041292737d1fad6aa25f9e06d.tar.bz2
New Makefile target `regen-ulps'.
The wiki "Regeneration" page has this to say about update ULPs. "The libm-test-ulps files are semiautomatically updated. To update an ulps baseline, run each of the failing tests (test-float, test-double, etc.) with -u; this will generate a file called ULPs; concatenate each of those files with the existing libm-test-ulps file, after removing any entries for particularly huge numbers of ulps that you do not want to mark as expected. Then run gen-libm-test.pl -n -u FILE where FILE is the concatenated file produced in the previous step. This generates a file called NewUlps which is the new sorted version of libm-test-ulps." The same information is listed in math/README.libm-test, and is a lot of manual work that you often want to run over-and-over again while working on a particular test. The `regen-ulps' convenience target does this automatically for developers. We strictly assume the source tree is readonly and add a new --output-dir option to libm-test.inc to allow for writing out ULPs to $(objpfx). When run the new target does the following: * Starts with the baseline ULPs file. * Runs each of the libm math tests with -u. * Adds new changes seen with -u to the baseline. * Sorts and prepares the test output with gen-libm-test.pl. * Leaves math/NewUlps in your build tree to copy to your source tree, cleanup, and checkin. The math test documentation in math/README.libm-test is updated document the new Makefile target. --- 2013-04-06 Carlos O'Donell <carlos@redhat.com> * Makefile.in (regen-ulps): New target. * math/Makefile [ifneq (no,$(PERL)]: Declare regen-ulps with .PHONY. [ifneq (no,$(PERL)] (run-regen-ulps): New variable. [ifneq (no,$(PERL)] (regen-ulps): New target. [ifeq (no,$(PERL)] (regen-ulps): New target. * math/libm-test.inc (ulps_file_name): Define. (output_dir): New variable. (options): Add "output-dir" option. (parse_opt): Handle 'o' case. (main): If output_dir is non-NULL use it as a prefix otherwise use "". * math/README.libm-test: Update `How can I generate "libm-test-ulps"?'
Diffstat (limited to 'math')
-rw-r--r--math/Makefile27
-rw-r--r--math/README.libm-test41
-rw-r--r--math/libm-test.inc29
3 files changed, 78 insertions, 19 deletions
diff --git a/math/Makefile b/math/Makefile
index f396ba2..ee5b582 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -150,6 +150,33 @@ extra-objs += libieee.a ieee-math.o
include ../Rules
+ifneq (no,$(PERL))
+# Run the math programs to automatically generate ULPs files.
+.PHONY: regen-ulps
+
+run-regen-ulps = $(test-wrapper-env) \
+ GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
+ $($*-ENV) $(run-via-rtld-prefix) $${run}
+
+regen-ulps: $(addprefix $(objpfx),$(libm-tests))
+ rm -f $(objpfx)ULPs; rm -f $(objpfx)NewUlps; \
+ cp $(ulps-file) $(objpfx)libm-test-ulps; \
+ for run in $^; do \
+ echo "Regenerating ULPs for $${run}"; \
+ $(run-regen-ulps) -u -o $(objpfx); \
+ cat $(objpfx)ULPs >> $(objpfx)libm-test-ulps; \
+ rm $(objpfx)ULPs; \
+ done; \
+ $(PERL) gen-libm-test.pl -o $(objpfx) -n -u $(objpfx)libm-test-ulps; \
+ echo "Automatic regeneration of ULPs complete."; \
+ echo "Difference between the current baseline and the new baseline is:";\
+ diff -urN $(ulps-file) $(objpfx)NewUlps; \
+ echo "Copy $(objpfx)NewUlps to $(ulps-file) (relative to source)."
+else
+regen-ulps:
+ @echo "Automatic regeneration of ULPs requires perl."; \
+ exit 1;
+endif
# The generated sysd-rules file defines rules like this for sources
# coming from sysdeps/ directories. These rules find the generic sources.
diff --git a/math/README.libm-test b/math/README.libm-test
index 7a46155..2929499 100644
--- a/math/README.libm-test
+++ b/math/README.libm-test
@@ -39,24 +39,33 @@ platform specific sysdep directory.
How can I generate "libm-test-ulps"?
====================================
-The test drivers have an option "-u" to output an unsorted list of all
-epsilons that the functions have. The output can be read in directly
-but it's better to pretty print it first. "gen-libm-test.pl" has an option
-to generate a pretty-printed and sorted new ULPs file from the output
-of the test drivers.
-
-To generate a new "libm-test-ulps" file, first remove "ULPs" file in the
-current directory, then you can execute for example:
-test-double -u --ignore-max-ulp=yes
+To automatically generate a new "libm-test-ulps" run "make regen-ulps".
+This generates the file "math/NewUlps" in the build directory. The file
+contains the sorted results of all the tests. You can use the "NewUlps"
+file as the machine's updated "libm-test-ulps" file. Copy "NewUlps" to
+"libm-test-ulps" in the appropriate machine sysdep directory. Verify
+the changes, post your patch, and check it in after review.
+
+To manually generate a new "libm-test-ulps" file, first remove "ULPs"
+file in the current directory, then you can execute for example:
+ /build/elf/ld.so --library--path /build/:/build/elf:/build/math \
+ test-double -u --ignore-max-ulp=yes
This generates a file "ULPs" with all double ULPs in it, ignoring any
-previous calculated ULPs.
-Now generate the ULPs for all other formats, the tests will be appending
-the data to the "ULPs" file. As final step run "gen-libm-test.pl" with the
-file as input and ask to generate a pretty printed output in the file "NewUlps":
+previously calculated ULPs, and running with the newly built dynamic
+loader and math library (assumes you didn't install your build). Now
+generate the ULPs for all other formats, the tests will be appending the
+data to the "ULPs" file. As final step run "gen-libm-test.pl" with the
+file as input and ask to generate a pretty printed output in the file
+"NewUlps":
gen-libm-test.pl -u ULPs -n
-
-Now you can rename "NewUlps" to "libm-test-ulps" and move it into
-sysdeps.
+Copy "NewUlps" to "libm-test-ulps" in the appropriate machine sysdep
+directory.
+
+Note that the test drivers have an option "-u" to output an unsorted
+list of all epsilons that the functions have. The output can be read
+in directly but it's better to pretty print it first.
+"gen-libm-test.pl" has an option to generate a pretty-printed and
+sorted new ULPs file from the output of the test drivers.
Contents of libm-test-ulps
==========================
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 92fa6a2..78d2107 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -210,8 +210,10 @@
#define M_PI_LOG10El M_PIl * M_LOG10El
#define M_SQRT_2_2 0.70710678118654752440084436210484903L /* sqrt (2) / 2 */
-static FILE *ulps_file; /* File to document difference. */
-static int output_ulps; /* Should ulps printed? */
+#define ulps_file_name "ULPs" /* Name of the ULPs file. */
+static FILE *ulps_file; /* File to document difference. */
+static int output_ulps; /* Should ulps printed? */
+static char *output_dir; /* Directory where generated files will be written. */
static int noErrors; /* number of errors */
static int noTests; /* number of tests (without testing exceptions) */
@@ -12985,6 +12987,8 @@ static const struct argp_option options[] =
"Don't output results of functions invocations"},
{ "ignore-max-ulp", 'i', "yes/no", 0,
"Ignore given maximal errors"},
+ { "output-dir", 'o', "DIR", 0,
+ "Directory where generated files will be placed"},
{ NULL, 0, NULL, 0, NULL }
};
@@ -13016,6 +13020,13 @@ parse_opt (int key, char *arg, struct argp_state *state)
else if (strcmp (arg, "no") == 0)
ignore_max_ulp = 0;
break;
+ case 'o':
+ output_dir = (char *) malloc (strlen (arg) + 1);
+ if (output_dir != NULL)
+ strcpy (output_dir, arg);
+ else
+ return errno;
+ break;
case 'p':
output_points = 0;
break;
@@ -13065,11 +13076,14 @@ main (int argc, char **argv)
{
int remaining;
+ char *ulps_file_path;
+ size_t dir_len = 0;
verbose = 1;
output_ulps = 0;
output_max_error = 1;
output_points = 1;
+ output_dir = NULL;
/* XXX set to 0 for releases. */
ignore_max_ulp = 0;
@@ -13085,7 +13099,16 @@ main (int argc, char **argv)
if (output_ulps)
{
- ulps_file = fopen ("ULPs", "a");
+ if (output_dir != NULL)
+ dir_len = strlen (output_dir);
+ ulps_file_path = (char *) malloc (dir_len + strlen (ulps_file_name) + 1);
+ if (ulps_file_path == NULL)
+ {
+ perror ("can't allocate path for `ULPs' file: ");
+ exit (1);
+ }
+ sprintf (ulps_file_path, "%s%s", output_dir == NULL ? "" : output_dir, ulps_file_name);
+ ulps_file = fopen (ulps_file_path, "a");
if (ulps_file == NULL)
{
perror ("can't open file `ULPs' for writing: ");