This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add convenience target to automatically update ULPs for your machine.


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 following convenience target does this automatically for
developers (with some tweaks to libm-test.inc to support read-only
source directories).

When run it does the following:
* Start with the baseline ULPs file.
* Run each of the libm math tests with -u.
* Add new changes seen with -u to the baseline.
* Sort and prepare the tests with gen-libm-test.pl.
* Leave math/NewUlps for you to copy to your source
  tree, cleanup, and checkin.

It looks like this if you don't have perl installed:
~~~
...
Automatic regeneration of ULPs requires perl.
make[1]: *** [regenulps] Error 1
make[1]: Leaving directory `/home/carlos/src/glibc/math'
make: *** [regenulps] Error 2
~~~

It looks like this if you have perl installed and nothing has changed:
~~~
[carlos@koi glibc]$ make regenulps
make -C /home/carlos/src/glibc/math  objdir=`pwd` regenulps
make[1]: Entering directory `/home/carlos/src/glibc/math'
make[1]: Leaving directory `/home/carlos/src/glibc/math'
make[1]: Entering directory `/home/carlos/src/glibc/math'
rm -f /home/carlos/build/glibc/math/ULPs; rm -f /home/carlos/build/glibc/math/NewUlps; \
cp ../sysdeps/x86_64/fpu/libm-test-ulps /home/carlos/build/glibc/math/libm-test-ulps; \
for run in /home/carlos/build/glibc/math/test-float /home/carlos/build/glibc/math/test-double /home/carlos/build/glibc/math/test-ldouble /home/carlos/build/glibc/math/test-ildoubl /home/carlos/build/glibc/math/test-ifloat /home/carlos/build/glibc/math/test-idouble; do \
  echo "Regenerating ULPs for ${run}"; \
  eval  env GCONV_PATH=/home/carlos/build/glibc/iconvdata LC_ALL=C   /home/carlos/build/glibc/elf/ld-linux-x86-64.so.2 --library-path /home/carlos/build/glibc:/home/carlos/build/glibc/math:/home/carlos/build/glibc/elf:/home/carlos/build/glibc/dlfcn:/home/carlos/build/glibc/nss:/home/carlos/build/glibc/nis:/home/carlos/build/glibc/rt:/home/carlos/build/glibc/resolv:/home/carlos/build/glibc/crypt:/home/carlos/build/glibc/nptl /home/carlos/build/glibc/math/test-double  -u -o /home/carlos/build/glibc/math/; \
  cat /home/carlos/build/glibc/math/ULPs >> /home/carlos/build/glibc/math/libm-test-ulps; \
  rm /home/carlos/build/glibc/math/ULPs; \
done; \
/usr/bin/perl gen-libm-test.pl -o /home/carlos/build/glibc/math/ -n -u /home/carlos/build/glibc/math/libm-test-ulps; \
diff -urN ../sysdeps/x86_64/fpu/libm-test-ulps /home/carlos/build/glibc/math/NewUlps; \
echo "Automatic regeneration of ULPs complete."; \
echo "Copy /home/carlos/build/glibc/math/NewUlps to ../sysdeps/x86_64/fpu/libm-test-ulps, clean up, and checkin changes."
Regenerating ULPs for /home/carlos/build/glibc/math/test-float
testing double (without inline functions)

Test suite completed:
  7928 test cases plus 7308 tests for exception flags executed.
  All tests passed successfully.
Regenerating ULPs for /home/carlos/build/glibc/math/test-double
testing double (without inline functions)

Test suite completed:
  7928 test cases plus 7308 tests for exception flags executed.
  All tests passed successfully.
Regenerating ULPs for /home/carlos/build/glibc/math/test-ldouble
testing double (without inline functions)

Test suite completed:
  7928 test cases plus 7308 tests for exception flags executed.
  All tests passed successfully.
Regenerating ULPs for /home/carlos/build/glibc/math/test-ildoubl
testing double (without inline functions)

Test suite completed:
  7928 test cases plus 7308 tests for exception flags executed.
  All tests passed successfully.
Regenerating ULPs for /home/carlos/build/glibc/math/test-ifloat
testing double (without inline functions)

Test suite completed:
  7928 test cases plus 7308 tests for exception flags executed.
  All tests passed successfully.
Regenerating ULPs for /home/carlos/build/glibc/math/test-idouble
testing double (without inline functions)

Test suite completed:
  7928 test cases plus 7308 tests for exception flags executed.
  All tests passed successfully.
Automatic regeneration of ULPs complete.
Copy /home/carlos/build/glibc/math/NewUlps to ../sysdeps/x86_64/fpu/libm-test-ulps, clean up, and checkin changes.
make[1]: Leaving directory `/home/carlos/src/glibc/math'
~~~

It looks like this if you have perl installed and ULPs is not up to date:
~~~
[carlos@koi glibc]$ make regenulps
make -C /home/carlos/src/glibc/math  objdir=`pwd` regenulps
make[1]: Entering directory `/home/carlos/src/glibc/math'
...
echo "Automatic regeneration of ULPs complete."; \
echo "Copy /home/carlos/build/glibc/math/NewUlps to ../sysdeps/x86_64/fpu/libm-test-ulps, clean up, and checkin changes."
Regenerating ULPs for /home/carlos/build/glibc/math/test-float
testing double (without inline functions)
Failure: Test: Imaginary part of: cpow (-1 - 0 i, -1 - 0 i) == -1.0 - 0.0 i
Result:
 is:         -1.22464679914735320717e-16  -0x1.1a62633145c070000000p-53
 should be:  -0.00000000000000000000e+00  -0x0.00000000000000000000p+0
 difference:  1.22464679914735320717e-16   0x1.1a62633145c070000000p-53
 ulp       :  0.5515
 max.ulp   :  0.0000
Failure: Test: Imaginary part of: cpow (-1 + +0 i, -1 + +0 i) == -1.0 - 0.0 i
Result:
 is:         -1.22464679914735320717e-16  -0x1.1a62633145c070000000p-53
 should be:  -0.00000000000000000000e+00  -0x0.00000000000000000000p+0
 difference:  1.22464679914735320717e-16   0x1.1a62633145c070000000p-53
 ulp       :  0.5515
 max.ulp   :  0.0000

Test suite completed:
  7928 test cases plus 7308 tests for exception flags executed.
  2 errors occurred.
...
--- ../sysdeps/x86_64/fpu/libm-test-ulps	2013-04-04 18:50:39.882446238 -0400
+++ /home/carlos/build/glibc/math/NewUlps	2013-04-04 18:51:14.704157971 -0400
@@ -4901,6 +4901,10 @@
 ldouble: 1
 
 # cpow
+Test "Imaginary part of: cpow (-1 + +0 i, -1 + +0 i) == -1.0 - 0.0 i":
+double: 1
+Test "Imaginary part of: cpow (-1 - 0 i, -1 - 0 i) == -1.0 - 0.0 i":
+double: 1
 Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
 float: 1
 ifloat: 1
Automatic regeneration of ULPs complete.
Copy /home/carlos/build/glibc/math/NewUlps to ../sysdeps/x86_64/fpu/libm-test-ulps, clean up, and checkin changes.
make[1]: Leaving directory `/home/carlos/src/glibc/math'
[carlos@koi glibc]$ 
~~~

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).

OK to checkin?

2013-04-04  Carlos O'Donell  <carlos@redhat.com>

	* Makefile.in (regenulps): New target.
	* math/Makefile (regenulps): 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 "".

diff --git a/Makefile.in b/Makefile.in
index df75b8f..1c96974 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -14,3 +14,8 @@ install:
 
 bench:
        $(MAKE) -C $(srcdir)/benchtests $(PARALLELMFLAGS) objdir=`pwd` $@
+
+# Convenience target to rebuild ULPs for all math tests.
+regenulps:
+       $(MAKE) -C $(srcdir)/math $(PARALLELMFLAGS) objdir=`pwd` $@
+
diff --git a/math/Makefile b/math/Makefile
index f396ba2..0544c8b 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -150,6 +150,27 @@ extra-objs += libieee.a ieee-math.o
 
 include ../Rules
 
+ifneq (no,$(PERL))
+# Run the math programs to automatically generate ULPs files.
+.PHONY: regenulps
+regenulps: $(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}"; \
+         eval $(make-test-out) -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; \
+       diff -urN $(ulps-file) $(objpfx)NewUlps; \
+       echo "Automatic regeneration of ULPs complete."; \
+       echo "Copy $(objpfx)NewUlps to $(ulps-file), clean up, and checkin changes."
+else
+regenulps:
+       @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/libm-test.inc b/math/libm-test.inc
index 08c80fa..c745db9 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) */
@@ -12960,6 +12965,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 }
 };
 
@@ -12991,6 +12998,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;
@@ -13040,11 +13054,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;
 
@@ -13060,7 +13077,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: ");
---

Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]