diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2010-08-17 09:10:13 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2010-08-17 09:10:13 +0000 |
commit | c9583bdfe064e1069828e518533f7bc29a8fdddb (patch) | |
tree | 2400842d4095628b8486fbeabaf7bc7b8af4ed02 /tools | |
parent | 50ac5b5985174201c7fa6e20496cd2b096107001 (diff) | |
download | mpfr-c9583bdfe064e1069828e518533f7bc29a8fdddb.tar.gz |
Source reorganization. In short:
* Added directories and moved related files into them:
- src for the MPFR source files (to build the library).
- doc for documentation files (except INSTALL, README...).
- tools for various tools (scripts) and mbench.
- tune for tuneup-related source files.
- other for other source files (not distributed in tarballs).
Existing directories:
- tests for the source files of the test suite (make check).
- examples for examples.
- m4 for m4 files.
* Renamed configure.in to configure.ac.
* Added/updated Makefile.am files where needed.
* Updated acinclude.m4 and configure.ac (AC_CONFIG_FILES line).
* Updated the documentation (INSTALL, README, doc/README.dev and
doc/mpfr.texi).
* Updated NEWS and TODO.
* Updated the scripts now in tools.
The following script was used:
#!/usr/bin/env zsh
svn mkdir doc other src tools tune
svn mv ${${(M)$(sed -n '/libmpfr_la_SOURCES/,/[^\]$/p' \
Makefile.am):#*.[ch]}:#get_patches.c} mparam_h.in \
round_raw_generic.c jyn_asympt.c src
svn mv mbench check_inits_clears coverage get_patches.sh mpfrlint \
nightly-test update-patchv update-version tools
svn mv bidimensional_sample.c speed.c tuneup.c tune
svn mv *.{c,h} other
svn mv FAQ.html README.dev algorithm* faq.xsl fdl.texi mpfr.texi \
update-faq doc
svn mv configure.in configure.ac
svn cp Makefile.am src/Makefile.am
svn rm replace_all
[Modifying some files, see above]
svn add doc/Makefile.am
svn add tune/Makefile.am
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@7087 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/check_inits_clears | 29 | ||||
-rwxr-xr-x | tools/coverage | 77 | ||||
-rwxr-xr-x | tools/get_patches.sh | 34 | ||||
-rw-r--r-- | tools/mbench/Makefile | 128 | ||||
-rw-r--r-- | tools/mbench/README | 31 | ||||
-rw-r--r-- | tools/mbench/generate.c | 103 | ||||
-rw-r--r-- | tools/mbench/mfv5-arprec.cc | 109 | ||||
-rw-r--r-- | tools/mbench/mfv5-cln.cc | 126 | ||||
-rw-r--r-- | tools/mbench/mfv5-crlibm.cc | 142 | ||||
-rw-r--r-- | tools/mbench/mfv5-libc.cc | 194 | ||||
-rw-r--r-- | tools/mbench/mfv5-lidia.cc | 131 | ||||
-rw-r--r-- | tools/mbench/mfv5-mpf.cc | 136 | ||||
-rw-r--r-- | tools/mbench/mfv5-mpfr.cc | 237 | ||||
-rw-r--r-- | tools/mbench/mfv5-ntl.cc | 115 | ||||
-rw-r--r-- | tools/mbench/mfv5-pari.cc | 123 | ||||
-rw-r--r-- | tools/mbench/mfv5-void.cc | 21 | ||||
-rw-r--r-- | tools/mbench/mfv5.cc | 174 | ||||
-rw-r--r-- | tools/mbench/mfv5.h | 119 | ||||
-rw-r--r-- | tools/mbench/mpfr-gfx.c | 447 | ||||
-rw-r--r-- | tools/mbench/mpfr-v4.c | 300 | ||||
-rw-r--r-- | tools/mbench/mpfr-v6.c | 379 | ||||
-rw-r--r-- | tools/mbench/timp.h | 127 | ||||
-rwxr-xr-x | tools/mpfrlint | 93 | ||||
-rwxr-xr-x | tools/nightly-test | 30 | ||||
-rwxr-xr-x | tools/update-patchv | 46 | ||||
-rwxr-xr-x | tools/update-version | 59 |
26 files changed, 3510 insertions, 0 deletions
diff --git a/tools/check_inits_clears b/tools/check_inits_clears new file mode 100755 index 000000000..f65ed8f39 --- /dev/null +++ b/tools/check_inits_clears @@ -0,0 +1,29 @@ +#!/usr/bin/env perl + +# Check that a cast is performed for the last argument of +# mpfr_inits, mpfr_inits2 and mpfr_clears. + +use strict; +use warnings; +use File::Find; +use Cwd; + +my $err = 0; +find(\&wanted, -d 'src' || getcwd() !~ m,/tools$, ? '.' : '..'); +exit $err; + +sub wanted + { + /\.c$/ or return; + my $ctr = 0; + open FILE, '<', $_ or die; + while (<FILE>) + { + /^ +mpfr_(init|clear)s/ && ! /\(mpfr_ptr\) *(0|NULL)/ or next; + /, *$/ and $_ .= <FILE>, redo; + $ctr++ or print "Error found in $File::Find::name\n"; + print; + $err = 1; + } + close FILE or die; + } diff --git a/tools/coverage b/tools/coverage new file mode 100755 index 000000000..e8df6d780 --- /dev/null +++ b/tools/coverage @@ -0,0 +1,77 @@ +#!/bin/bash + +# First Build MPFR in /tmp/ +echo "Erasing previous /tmp/ompfr-gcov" +rm -rf /tmp/ompfr-gcov +mkdir /tmp/ompfr-gcov +echo "Copying MPFR sources to /tmp/ompfr-gcov" +cp -r . /tmp/ompfr-gcov +cd /tmp/ompfr-gcov +echo "Building MPFR" +./configure --enable-assert --disable-shared --enable-static \ + CFLAGS="-fprofile-arcs -ftest-coverage -g" +make check -j2 + +# Check version of gcov: +# 3.3 outputs like this: +# 100.00% of 36 lines executed in function mpfr_add +# 100.00% of 36 lines executed in file add.c +# Creating add.c.gcov. +# It doesn't support gcov *.c +# +# gcov (GCC) 3.4 outputs like this: +# Function `mpfr_add' +# Lines executed:100.00% of 36 +# +# File `add.c' +# Lines executed:100.00% of 36 +# add.c:creating `add.c.gcov' +# It supports gcov *.c + +# Setup the parser depending on gcov +gcov --version > coverage-tmp +if grep "gcov (GCC) 3.4" coverage-tmp ; then + echo "#!/bin/bash +while true ; do + if read x ; then + case \$x in + Function*) + read y + case \$y in + *100.00*) + ;; + *) + echo \$x \$y + ;; + esac + ;; + esac + else + exit 0 + fi +done +" > coverage.subscript +else + echo "#!/bin/bash +while true ; do + if read x ; then + case \$x in + 100.00*) + ;; + *function*) + echo \$x + ;; + esac + else + exit 0 + fi +done +" > coverage.subscript +fi + +# Do "gcov" for all files and parse the output +find . -name '*.c' -exec gcov -f '{}' ';' | \ + bash coverage.subscript > coverage.mpfr + +rm -f coverage.subscript coverage-tmp +echo "Coverage summary saved in file /tmp/ompfr-gcov/coverage.mpfr" diff --git a/tools/get_patches.sh b/tools/get_patches.sh new file mode 100755 index 000000000..44347e23b --- /dev/null +++ b/tools/get_patches.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +cat <<EOF +/* mpfr_get_patches -- Patches that have been applied + +Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +Contributed by the Arenaire and Caramel projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mpfr-impl.h" + +const char * +mpfr_get_patches (void) +{ +EOF + +echo ' return "'`cat PATCHES`'";' +echo '}' diff --git a/tools/mbench/Makefile b/tools/mbench/Makefile new file mode 100644 index 000000000..f9728903a --- /dev/null +++ b/tools/mbench/Makefile @@ -0,0 +1,128 @@ +# Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# Contributed by Patrick Pelissier, INRIA. +# +# This file is part of the MPFR Library. +# +# The MPFR Library is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# The MPFR Library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with the MPFR Library; see the file COPYING.LESSER. If not, write to +# the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. + +AR=ar +CC=gcc +CXX=g++ +RANLIB=ranlib +CFLAGS=-O2 -fomit-frame-pointer -Wall -g +RM=rm -f +CP=cp -f +MV=mv -f + +GMP=/usr +MPFR=$(PWD)/.. +PARI=$(GMP) +NTL=$(GMP) +CLN=$(GMP) +MAPM=$(GMP) +ARPREC=$(GMP) +CRLIBM=$(GMP) +LIDIA=/localdisk/lidia/ + +MPFR_INCLUDE=$(MPFR)/include +MPFR_LIB=$(MPFR)/lib + +######################################################## +VERSION=0.6.1 +NAME=mbench + +######################################################### +.SUFFIXES: .c .o + +# add -I$(MPFR) and -I$(GMP) if GMP/MPFR build directories are given +# Warning! If $(MPFR) and/or $(GMP) is regarded as a "system directory", +# this may give unexpected results[*]; in particular, with GCC, the option +# is ignored in such a case. +# [*] http://austingroupbugs.net/view.php?id=187 +ifeq ($(CC),gcc) +INCLUDES=`test -f $(GMP_INCLUDE)/gmp.h && echo "-include $(GMP_INCLUDE)/gmp.h"` `test -f $(GMP)/gmp.h && echo "-include $(GMP)/gmp.h"` `test -f $(MPFR_INCLUDE)/mpfr.h && echo "-include $(MPFR_INCLUDE)/mpfr.h"` `test -f $(MPFR)/mpfr.h && echo "-include $(MPFR)/mpfr.h"` -I. -I$(MPFR_INCLUDE) -I$(MPFR) -I$(GMP)/include/ -I$(GMP) +else +INCLUDES=-I. -I$(MPFR_INCLUDE) -I$(MPFR) -I$(GMP)/include/ -I$(GMP) +endif + +# search first for real install, then for build directory +LIBS=`(test -f $(MPFR_LIB)/libmpfr.a && echo $(MPFR_LIB)/libmpfr.a)` `(test -f $(MPFR)/.libs/libmpfr.a && echo $(MPFR)/.libs/libmpfr.a)` `(test -f $(GMP)/lib/libgmp.a && echo $(GMP)/lib/libgmp.a)` `(test -f $(GMP)/.libs/libgmp.a && echo $(GMP)/.libs/libgmp.a)` + +XLIBS=`test -f $(PARI)/lib/libpari.a && echo $(PARI)/lib/libpari.a` \ + `test -f $(NTL)/lib/libntl.a && echo $(NTL)/lib/libntl.a` \ + `test -f $(CLN)/lib/libcln.a && echo $(CLN)/lib/libcln.a` \ + `test -f $(ARPREC)/lib/libmp.a && echo $(ARPREC)/lib/libmp.a` \ + `test -f $(CRLIBM)/lib/libcrlibm.a && echo $(CRLIBM)/lib/libcrlibm.a` \ + -lm + +TARGETS=mpfr-v4 mpfr-v6 mpfr-gfx mfv5 +DIST=Makefile mpfr-v4.c mpfr-v6.c mpfr-gfx.c generate.c timp.h mfv5-arprec.cc mfv5-cln.cc mfv5-mpfr.cc mfv5-pari.cc mfv5.cc mfv5-mpf.cc mfv5-ntl.cc mfv5-lidia.cc mfv5.h mfv5-void.cc mfv5-libc.cc mfv5-crlibm.cc + +############################################################## + +.c.o: + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +.cc.o: + $(CXX) $(INCLUDES) $(CFLAGS) -c $< + +all: mfv5 + +clean: + $(RM) *.o *~ $(TARGETS) float.data + +mpfr-v4: mpfr-v4.o + $(CC) $(CFLAGS) mpfr-v4.o $(LIBS) -o mpfr-v4 + +mpfr-v6: mpfr-v6.o float.data + $(CC) $(CFLAGS) mpfr-v6.o $(LIBS) -lm -o mpfr-v6 + +mpfr-gfx: mpfr-gfx.o + $(CC) $(CFLAGS) mpfr-gfx.o $(LIBS) -o mpfr-gfx + +float.data: generate.o + $(CC) $(CFLAGS) generate.o $(LIBS) -o generate-float-data + ./generate-float-data + $(RM) generate-float-data + +mfv5-ntl.o: mfv5-ntl.cc mfv5.h + @(test -f $(NTL)/lib/libntl.a && $(CXX) $(INCLUDES) -I$(NTL)/include/ $(CFLAGS) -c $< && echo "Using NTL.") || ($(CXX) -c mfv5-void.cc -o mfv5-ntl.o && echo "NTL not found.") + +mfv5-arprec.o: mfv5-arprec.cc mfv5.h + @(test -f $(ARPREC)/lib/libmp.a && $(CXX) $(INCLUDES) -I$(ARPREC)/include/ $(CFLAGS) -c $< && echo "Using ARPREC.") || ($(CXX) -c mfv5-void.cc -o mfv5-arprec.o && echo "Arprec not found.") + +mfv5-pari.o: mfv5-pari.cc mfv5.h + @(test -f $(PARI)/lib/libpari.a && $(CXX) $(INCLUDES) -I$(PARI)/include/ $(CFLAGS) -c $< && echo "Using PARI.") || ($(CXX) -c mfv5-void.cc -o mfv5-pari.o && echo "PARI not found.") + +mfv5-cln.o: mfv5-cln.cc mfv5.h + @(test -f $(CLN)/lib/libcln.a && $(CXX) $(INCLUDES) -I$(CLN)/include/ $(CFLAGS) -c $< && echo "Using CLN.") || ($(CXX) -c mfv5-void.cc -o mfv5-cln.o && echo "CLN not found.") + +mfv5-lidia.o: mfv5-lidia.cc mfv5.h + @(test -f $(LIDIA)/lib/liblidia.a && $(CXX) $(INCLUDES) -I$(LIDIA)/include/ $(CFLAGS) -c $< && echo "Using LIDIA.") || ($(CXX) -c mfv5-void.cc -o mfv5-lidia.o && echo "LIDIA not found.") + +mfv5-crlibm.o: mfv5-crlibm.cc mfv5.h + @(test -f $(CRLIBM)/lib/libcrlibm.a && $(CXX) $(INCLUDES) -I$(CRLIBM)/include/ $(CFLAGS) -c $< && echo "Using CRLIBM.") || ($(CXX) -c mfv5-void.cc -o mfv5-crlibm.o && echo "CRLIBM not found.") + +mfv5: mfv5.o mfv5-mpfr.o mfv5-mpf.o mfv5-ntl.o mfv5-arprec.o mfv5-pari.o mfv5-cln.o mfv5-libc.o mfv5-crlibm.o + $(CXX) $(CFLAGS) mfv5.o mfv5-mpfr.o mfv5-mpf.o mfv5-ntl.o mfv5-arprec.o mfv5-pari.o mfv5-cln.o mfv5-libc.o mfv5-crlibm.o $(XLIBS) $(LIBS) -o mfv5 + +dist: $(DIST) + rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar $(NAME)-$(VERSION).tar.bz2 + mkdir $(NAME)-$(VERSION) + cp $(DIST) $(NAME)-$(VERSION) + tar cf $(NAME)-$(VERSION).tar $(NAME)-$(VERSION) + bzip2 $(NAME)-$(VERSION).tar + rm -fr $(NAME)-$(VERSION) diff --git a/tools/mbench/README b/tools/mbench/README new file mode 100644 index 000000000..fa3823235 --- /dev/null +++ b/tools/mbench/README @@ -0,0 +1,31 @@ +This directory contains 'mbench', a program written by Patrick Pélissier +(INRIA) to bench MPFR for low precisions. + +It is distributed under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +To use the mbench program: + Build it: + make GMP=/dir/to/gmp MPFR=/dir/to/mpfr + Run it by specifying the functions you want to bench: + ./mfv5 mpfr_add mpfr_mul mpfr_sub mpfr_div mpfr_sqrt + To have the lists of the available functions: + ./mfv5 -l + Help usage: + ./mfv5 -h + To build MFV5 with PARI/NTL/CLN/MAPM/ARPREC/CRLIBM support, build it with: + make GMP=/dir/to/gmp MPFR=/dir/to/mpfr PARI=/dir/to/pari ... + (It autodetects which library is available.) + Then use ./mfv5 -l to have the lists of the available functions. + To add a new function in MPFR (mpfr_toto), edit mfv5-mpfr.cc and add: + +class mpfr_toto_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_toto (a,b,r); + } +}; +static mpfr_test<mpfr_toto_test> testtoto ("mpfr_toto"); + + Rebuild it and that's all. diff --git a/tools/mbench/generate.c b/tools/mbench/generate.c new file mode 100644 index 000000000..1cccf8b8a --- /dev/null +++ b/tools/mbench/generate.c @@ -0,0 +1,103 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __MPFR_H +# define NEED_MAIN +# include "gmp.h" +# include "mpfr.h" +#endif + +#define fp_t mpfr_t +#define fp_set_fr(dest,src) mpfr_set (dest, src, GMP_RNDN) + +#define MAX_PREC 10000 +#define BASE 16 + +void gnumb_read (const char *filename, fp_t *dest, int n) +{ + mpfr_t x; + int i; + FILE *f = fopen(filename, "r"); + if (!f) {printf ("File not found: %s\n", filename); exit (1);} + + mpfr_init2 (x, MAX_PREC); + for (i = 0 ; i < n ; i++) + { + if (mpfr_inp_str (x, f, 16, GMP_RNDN) == 0) + { + printf ("Error reading entry %d/%d\n", i, n); + mpfr_clear (x); + fclose (f); + exit (2); + } + fp_set_fr (*dest++, x); + } + mpfr_clear (x); + fclose (f); +} + +void gnumb_generate (const char *filename, int n, unsigned long seed) +{ + mpfr_t x; + gmp_randstate_t state; + int i; + FILE *f; + + f = fopen (filename, "w"); + if (!f) {printf ("Can't create file: %s\n", filename); exit (1);} + mpfr_init2 (x, MAX_PREC); + gmp_randinit_lc_2exp_size (state, 128); + gmp_randseed_ui (state, seed); + + for (i = 0 ; i < n ; i++) + { + mpfr_urandomb (x, state); + if ((i & 2) == 0) + mpfr_mul_2si (x, x, (rand()%(2*GMP_NUMB_BITS))-GMP_NUMB_BITS, + GMP_RNDN); + mpfr_out_str (f, 16, 0, x, GMP_RNDN); + fputc ('\n', f); + } + + gmp_randclear(state); + mpfr_clear (x); + fclose (f); +} + +#ifdef NEED_MAIN +int main (int argc, char *argv[]) +{ + const char *filename = "float.data"; + int num = 1100; + unsigned long seed = 12345679; + if (argc >= 2) + filename = argv[1]; + if (argc >= 3) + num = atoi (argv[2]); + if (argc >= 4) + seed = atol (argv[3]); + gnumb_generate (filename, num, seed); + return 0; +} +#endif diff --git a/tools/mbench/mfv5-arprec.cc b/tools/mbench/mfv5-arprec.cc new file mode 100644 index 000000000..51cd291af --- /dev/null +++ b/tools/mbench/mfv5-arprec.cc @@ -0,0 +1,109 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" + +#include "mp/mpreal.h" + +#include "timp.h" + +using namespace std; + +/* Register New Test */ +template <class T> +class arprec_test : public registered_test { +private: + unsigned long size; + mp_real *table; + timming *tim; +public: + arprec_test (const char *n) : registered_test (n), size (0) {} + ~arprec_test () { + if (size != 0) { + delete tim; + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class arprec_add_test { +public: + void func (mp_real &a, const mp_real &b, const mp_real &c) { + a = b + c; + } +}; +class arprec_sub_test { +public: + void func (mp_real &a, const mp_real &b, const mp_real &c) { + a = b - c; + } +}; +class arprec_mul_test { +public: + void func (mp_real &a, const mp_real &b, const mp_real &c) { + a = b * c; + } +}; +class arprec_div_test { +public: + void func (mp_real &a, const mp_real &b, const mp_real &c) { + a = b / c; + } +}; + +static arprec_test<arprec_add_test> test1 ("arprec_add"); +static arprec_test<arprec_sub_test> test2 ("arprec_sub"); +static arprec_test<arprec_mul_test> test3 ("arprec_mul"); +static arprec_test<arprec_div_test> test4 ("arprec_div"); + + +/* Do the test */ +template <class T> bool +arprec_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + + /* Init and set tables if first call */ + if (size == 0) { + size = base.size (); + mp::mp_init (opt.prec); + tim = new timming (size); + table = new mp_real[size]; + for (i = 0 ; i < size ; i++) + table[i] = base[i].c_str (); + } + mp_real a, b, c; + + /* Do Measure */ + for(i = 0 ; i < (size-1) ; i++) { + b = table[i]; + c = table[i+1]; + TIMP_OVERHEAD (); + m = TIMP_MEASURE(f.func (a, b, c) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-cln.cc b/tools/mbench/mfv5-cln.cc new file mode 100644 index 000000000..b01f4a70a --- /dev/null +++ b/tools/mbench/mfv5-cln.cc @@ -0,0 +1,126 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" + +#include "cln/cln.h" + +#include "timp.h" + +using namespace std; +using namespace cln; + +/* Register New Test */ +template <class T> +class cln_test : public registered_test { +private: + unsigned long size; + cl_F **table; + timming *tim; +public: + cln_test (const char *n) : registered_test (n), size (0) {} + ~cln_test () { + if (size != 0) { + delete tim; + for (unsigned long i = 0 ; i < size ; i++) { + delete table[i]; + } + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class cln_add_test { +public: + void func (cl_F &a, const cl_F &b, const cl_F &c) { + a = b + c; + } +}; +class cln_sub_test { +public: + void func (cl_F &a, const cl_F &b, const cl_F &c) { + a = b - c; + } +}; +class cln_mul_test { +public: + void func (cl_F &a, const cl_F &b, const cl_F &c) { + a = b * c; + } +}; +class cln_div_test { +public: + void func (cl_F &a, const cl_F &b, const cl_F &c) { + a = b / c; + } +}; + +static cln_test<cln_add_test> test1 ("cln_add"); +static cln_test<cln_sub_test> test2 ("cln_sub"); +static cln_test<cln_mul_test> test3 ("cln_mul"); +static cln_test<cln_div_test> test4 ("cln_div"); + +static bool prec_print = false; + +/* Do the test */ +template <class T> +bool cln_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + + /* Init and set tables if first call */ + if (size == 0) { + unsigned long prec=(unsigned long)(((double)opt.prec)*0.3010299956639811); + if (opt.verbose && !prec_print) { + cout << " Decimal Prec[CLN]=" << prec << endl; + prec_print = true; + } + size = base.size (); + tim = new timming (size); + table = new cl_F *[size]; + // (cl_float (0.0, float_format_t (opt.prec))); + for (i = 0 ; i < size ; i++) { + char * Buffer = new char[base[i].size () + 100]; + sprintf (Buffer, "%s_%lu", base[i].c_str (), prec); + table[i] = new cl_F (Buffer); + delete[] Buffer; + } + } + + cl_F a = cl_float(0.0, float_format_t(opt.prec)); + cl_F b = cl_float(0.0, float_format_t(opt.prec)); + cl_F c = cl_float(0.0, float_format_t(opt.prec)); + + /* Do Measure */ + for(i = 0 ; i < (size-1) ; i++) { + b = *table[i]; + c = *table[i+1]; + TIMP_OVERHEAD (); + m = TIMP_MEASURE (f.func (a, b, c) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-crlibm.cc b/tools/mbench/mfv5-crlibm.cc new file mode 100644 index 000000000..d898941af --- /dev/null +++ b/tools/mbench/mfv5-crlibm.cc @@ -0,0 +1,142 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" +#include "timp.h" + +#include <math.h> +#include <float.h> +#include "crlibm.h" +#include "mpfr.h" + +using namespace std; + +/* Register New Test */ +template <class T> +class crlibm_test : public registered_test { +private: + unsigned long size; + double *table; + timming *tim; +public: + crlibm_test (const char *n) : registered_test (n), size (0) {} + ~crlibm_test () { + if (size != 0) { + delete tim; + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class crlibm_exp_test { +public: + double func (double a) { + return exp_rn (a); + } +}; +class crlibm_log_test { +public: + double func (double a) { + return log_rn (a); + } +}; +class crlibm_cos_test { +public: + double func (double a) { + return cos_rn (a); + } +}; +class crlibm_sin_test { +public: + double func (double a) { + return sin_rn (a); + } +}; +class crlibm_tan_test { +public: + double func (double a) { + return tan_rn (a); + } +}; +class crlibm_atan_test { +public: + double func (double a) { + return atan_rn (a); + } +}; +class crlibm_cosh_test { +public: + double func (double a) { + return cosh_rn (a); + } +}; +class crlibm_sinh_test { +public: + double func (double a) { + return sinh_rn (a); + } +}; +static crlibm_test<crlibm_exp_test> test7 ("crlibm_exp"); +static crlibm_test<crlibm_log_test> test8 ("crlibm_log"); + +static crlibm_test<crlibm_cos_test> testA ("crlibm_cos"); +static crlibm_test<crlibm_sin_test> testB ("crlibm_sin"); +static crlibm_test<crlibm_tan_test> testC ("crlibm_tan"); +static crlibm_test<crlibm_atan_test> testF ("crlibm_atan"); +static crlibm_test<crlibm_cosh_test> testAh ("crlibm_cosh"); +static crlibm_test<crlibm_sinh_test> testBh ("crlibm_sinh"); + +/* Do the test */ +template <class T> +bool crlibm_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + volatile double a, b; + + /* Init and set tables if first call */ + if (size == 0) { + mpfr_t x; + size = base.size (); + tim = new timming (size); + table = new double[size]; + mpfr_init2 (x, 530); + for (i = 0 ; i < size ; i++) { + mpfr_set_str (x, base[i].c_str(), 10, GMP_RNDN); + table[i] = mpfr_get_d (x, GMP_RNDN); + } + mpfr_clear (x); + } + + /* Do Measure */ + TIMP_OVERHEAD (); + for(i = 0 ; i < (size-1) ; i++) { + b = table[i]; + TIMP_OVERHEAD (); + m = TIMP_MEASURE (a = f.func (b) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-libc.cc b/tools/mbench/mfv5-libc.cc new file mode 100644 index 000000000..301ab36a3 --- /dev/null +++ b/tools/mbench/mfv5-libc.cc @@ -0,0 +1,194 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <math.h> +#include <float.h> + +#include "mpfr.h" + +#include "mfv5.h" +#include "timp.h" + + +using namespace std; + +/* Register New Test */ +template <class T> +class libc_test : public registered_test { +private: + unsigned long size; + double *table; + timming *tim; +public: + libc_test (const char *n) : registered_test (n), size (0) {} + ~libc_test () { + if (size != 0) { + delete tim; + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class libc_sqrt_test { +public: + inline double func (double a) { + return sqrt (a); + } +}; +class libc_exp_test { +public: + inline double func (double a) { + return exp (a); + } +}; +class libc_log_test { +public: + inline double func (double a) { + return log (a); + } +}; +class libc_cos_test { +public: + inline double func (double a) { + return cos (a); + } +}; +class libc_sin_test { +public: + inline double func (double a) { + return sin (a); + } +}; +class libc_tan_test { +public: + inline double func (double a) { + return tan (a); + } +}; +class libc_acos_test { +public: + inline double func (double a) { + return acos (a); + } +}; +class libc_asin_test { +public: + inline double func (double a) { + return asin (a); + } +}; +class libc_atan_test { +public: + inline double func (double a) { + return atan (a); + } +}; +class libc_cosh_test { +public: + inline double func (double a) { + return cosh (a); + } +}; +class libc_sinh_test { +public: + inline double func (double a) { + return sinh (a); + } +}; +class libc_tanh_test { +public: + inline double func (double a) { + return tanh (a); + } +}; +class libc_acosh_test { +public: + inline double func (double a) { + return acosh (a); + } +}; +class libc_asinh_test { +public: + inline double func (double a) { + return asinh (a); + } +}; +class libc_atanh_test { +public: + inline double func (double a) { + return atanh (a); + } +}; + + +static libc_test<libc_sqrt_test> test6 ("libc_sqrt"); +static libc_test<libc_exp_test> test7 ("libc_exp"); +static libc_test<libc_log_test> test8 ("libc_log"); + +static libc_test<libc_cos_test> testA ("libc_cos"); +static libc_test<libc_sin_test> testB ("libc_sin"); +static libc_test<libc_tan_test> testC ("libc_tan"); +static libc_test<libc_acos_test> testD ("libc_acos"); +static libc_test<libc_asin_test> testE ("libc_asin"); +static libc_test<libc_atan_test> testF ("libc_atan"); + +static libc_test<libc_cosh_test> testAh ("libc_cosh"); +static libc_test<libc_sinh_test> testBh ("libc_sinh"); +static libc_test<libc_tanh_test> testCh ("libc_tanh"); +static libc_test<libc_acosh_test> testDh ("libc_acosh"); +static libc_test<libc_asinh_test> testEh ("libc_asinh"); +static libc_test<libc_atanh_test> testFh ("libc_atanh"); + +/* Do the test */ +template <class T> +bool libc_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + volatile double a, b; + + /* Init and set tables if first call */ + if (size == 0) { + mpfr_t x; + size = base.size (); + tim = new timming (size); + table = new double[size]; + mpfr_init2 (x, 530); + for (i = 0 ; i < size ; i++) { + mpfr_set_str (x, base[i].c_str(), 10, GMP_RNDN); + table[i] = mpfr_get_d (x, GMP_RNDN); + } + mpfr_clear (x); + } + + /* Do Measure */ + for(i = 0 ; i < (size-1) ; i++) { + b = table[i]; + TIMP_OVERHEAD (); + m = TIMP_MEASURE(a = f.func (b) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-lidia.cc b/tools/mbench/mfv5-lidia.cc new file mode 100644 index 000000000..bfba2fc4b --- /dev/null +++ b/tools/mbench/mfv5-lidia.cc @@ -0,0 +1,131 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" + +#include "LiDIA/bigfloat.h" + +#include "timming.h" + +using namespace std; +using namespace LiDIA; + +/* Register New Test */ +template <class T> +class lidia_test : public registered_test { +private: + unsigned long size; + bigfloat *table; + bigfloat a, b, c; + timming *tim; +public: + lidia_test (const char *n) : registered_test (n), size (0) {} + ~lidia_test () { + if (size != 0) { + delete tim; + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class lidia_add_test { +public: + void func (bigfloat &a, const bigfloat &b, const bigfloat &c) { + add (a, b, c); + } +}; +class lidia_sub_test { +public: + void func (bigfloat &a, const bigfloat &b, const bigfloat &c) { + subtract (a, b, c); + } +}; +class lidia_mul_test { +public: + void func (bigfloat &a, const bigfloat &b, const bigfloat &c) { + multiply (a, b, c); + } +}; +class lidia_div_test { +public: + void func (bigfloat &a, const bigfloat &b, const bigfloat &c) { + divide (a, b, c); + } +}; +class lidia_sqrt_test { +public: + void func (bigfloat &a, const bigfloat &b, const bigfloat &c) { + sqrt (a, b); + } +}; +class lidia_exp_test { +public: + void func (bigfloat &a, const bigfloat &b, const bigfloat &c) { + exp (a, b); + } +}; + + +static lidia_test<lidia_add_test> test1 ("lidia_add"); +static lidia_test<lidia_sub_test> test2 ("lidia_sub"); +static lidia_test<lidia_mul_test> test3 ("lidia_mul"); +static lidia_test<lidia_div_test> test4 ("lidia_div"); +static lidia_test<lidia_sqrt_test> test5 ("lidia_sqrt"); +static lidia_test<lidia_exp_test> test6 ("lidia_exp"); + + +/* Do the test */ +template <class T> +bool lidia_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + + /* Init and set tables if first call */ + if (size == 0) { + unsigned long prec=(unsigned long)(((double)opt.prec)*0.3010299956639811); + bigfloat::set_mode (MP_RND); + bigfloat::set_precision (prec); + size = base.size (); + tim = new timming (size); + table = new bigfloat[size]; + for (i = 0 ; i < size ; i++) + string_to_bigfloat ((char*) base[i].c_str(), table[i]); + a.set_precision (prec); + b.set_precision (prec); + c.set_precision (prec); + } + + /* Do Measure */ + CALCUL_OVERHEAD; + for(i = 0 ; i < (size-1) ; i++) { + b = table[i]; + c = table[i+1]; + CALCUL_OVERHEAD ; + m = MEASURE(f.func (a, b, c) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-mpf.cc b/tools/mbench/mfv5-mpf.cc new file mode 100644 index 000000000..a9048f834 --- /dev/null +++ b/tools/mbench/mfv5-mpf.cc @@ -0,0 +1,136 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" +#include "gmp.h" +#include "timp.h" + +using namespace std; + +/* Register New Test */ +template <class T> +class mpf_test : public registered_test { +private: + unsigned long size; + mpf_t *table; + mpf_t a, b, c; + timming *tim; +public: + mpf_test (const char *n) : registered_test (n), size (0) {} + ~mpf_test () { + if (size != 0) { + unsigned long i; + delete tim; + mpf_clear (a); + mpf_clear (b); + mpf_clear (c); + for (i = 0 ; i < size ; i++) + mpf_clear (table[i]); + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class mpf_add_test { +public: + void func (mpf_ptr a, mpf_srcptr b, mpf_srcptr c) { + return mpf_add (a,b,c); + } +}; + +class mpf_sub_test { +public: + void func (mpf_ptr a, mpf_srcptr b, mpf_srcptr c) { + return mpf_sub (a,b,c); + } +}; + +class mpf_mul_test { +public: + void func (mpf_ptr a, mpf_srcptr b, mpf_srcptr c) { + return mpf_mul (a,b,c); + } +}; + +class mpf_div_test { +public: + void func (mpf_ptr a, mpf_srcptr b, mpf_srcptr c) { + return mpf_div (a,b,c); + } +}; + +class mpf_set_test { +public: + void func (mpf_ptr a, mpf_srcptr b, mpf_srcptr c) { + return mpf_set (a,b); + } +}; + +class mpf_sqrt_test { +public: + void func (mpf_ptr a, mpf_srcptr b, mpf_srcptr c) { + return mpf_sqrt (a,b); + } +}; + +static mpf_test<mpf_add_test> test1 ("mpf_add"); +static mpf_test<mpf_sub_test> test2 ("mpf_sub"); +static mpf_test<mpf_mul_test> test3 ("mpf_mul"); +static mpf_test<mpf_div_test> test4 ("mpf_div"); +static mpf_test<mpf_set_test> test5 ("mpf_set"); +static mpf_test<mpf_sqrt_test> test6 ("mpf_sqrt"); + + +/* Do the test */ +template <class T> +bool mpf_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + + /* Init and set tables if first call */ + if (size == 0) { + size = base.size (); + tim = new timming (size); + table = new mpf_t[size]; + for (i = 0 ; i < size ; i++) { + mpf_init2 (table[i], opt.prec); + mpf_set_str (table[i], base[i].c_str(), 10); + } + mpf_init2 (a, opt.prec); + mpf_init2 (b, opt.prec); + mpf_init2 (c, opt.prec); + } + + /* Do Measure */ + for(i = 0 ; i < (size-1) ; i++) { + mpf_set (b, table[i]); + mpf_set (c, table[i+1]); + TIMP_OVERHEAD (); + m = TIMP_MEASURE(f.func (a, b, c) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-mpfr.cc b/tools/mbench/mfv5-mpfr.cc new file mode 100644 index 000000000..83b5edb56 --- /dev/null +++ b/tools/mbench/mfv5-mpfr.cc @@ -0,0 +1,237 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" +#include "mpfr.h" +#include "timp.h" + +using namespace std; + +/* Register New Test */ +template <class T> +class mpfr_test : public registered_test { +private: + unsigned long size; + mpfr_t *table; + mpfr_t a, b, c; + timming *tim; +public: + mpfr_test (const char *n) : registered_test (n), size (0) {} + ~mpfr_test () { + if (size != 0) { + unsigned long i; + delete tim; + mpfr_clears (a, b, c, NULL); + for (i = 0 ; i < size ; i++) + mpfr_clear (table[i]); + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class mpfr_add_test { +public: + int func(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_add (a,b,c,r); + } +}; + +class mpfr_sub_test { +public: + int func(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_sub (a,b,c,r); + } +}; + +class mpfr_mul_test { +public: + int func(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_mul (a,b,c,r); + } +}; +class mpfr_div_test { +public: + int func(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_div (a,b,c,r); + } +}; +class mpfr_set_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_set (a,b,r); + } +}; +class mpfr_sqrt_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_sqrt (a,b,r); + } +}; +class mpfr_exp_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_exp (a,b,r); + } +}; +class mpfr_log_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_log (a,b,r); + } +}; +class mpfr_erf_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_erf (a,b,r); + } +}; +class mpfr_cos_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_cos (a,b,r); + } +}; +class mpfr_sin_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_sin (a,b,r); + } +}; +class mpfr_tan_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_tan (a,b,r); + } +}; +class mpfr_acos_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_acos (a,b,r); + } +}; +class mpfr_asin_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_asin (a,b,r); + } +}; +class mpfr_atan_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_atan (a,b,r); + } +}; +class mpfr_cosh_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_cosh (a,b,r); + } +}; +class mpfr_sinh_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_sinh (a,b,r); + } +}; +class mpfr_tanh_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_tanh (a,b,r); + } +}; +class mpfr_acosh_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_acosh (a,b,r); + } +}; +class mpfr_asinh_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_asinh (a,b,r); + } +}; +class mpfr_atanh_test { +public: + int func (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t r) { + return mpfr_atanh (a,b,r); + } +}; + + +static mpfr_test<mpfr_add_test> test1 ("mpfr_add"); +static mpfr_test<mpfr_sub_test> test2 ("mpfr_sub"); +static mpfr_test<mpfr_mul_test> test3 ("mpfr_mul"); +static mpfr_test<mpfr_div_test> test4 ("mpfr_div"); +static mpfr_test<mpfr_set_test> test5 ("mpfr_set"); + +static mpfr_test<mpfr_sqrt_test> test6 ("mpfr_sqrt"); +static mpfr_test<mpfr_exp_test> test7 ("mpfr_exp"); +static mpfr_test<mpfr_log_test> test8 ("mpfr_log"); +static mpfr_test<mpfr_log_test> test9 ("mpfr_erf"); + +static mpfr_test<mpfr_cos_test> testA ("mpfr_cos"); +static mpfr_test<mpfr_sin_test> testB ("mpfr_sin"); +static mpfr_test<mpfr_tan_test> testC ("mpfr_tan"); +static mpfr_test<mpfr_acos_test> testD ("mpfr_acos"); +static mpfr_test<mpfr_asin_test> testE ("mpfr_asin"); +static mpfr_test<mpfr_atan_test> testF ("mpfr_atan"); + +static mpfr_test<mpfr_cosh_test> testAh ("mpfr_cosh"); +static mpfr_test<mpfr_sinh_test> testBh ("mpfr_sinh"); +static mpfr_test<mpfr_tanh_test> testCh ("mpfr_tanh"); +static mpfr_test<mpfr_acosh_test> testDh ("mpfr_acosh"); +static mpfr_test<mpfr_asinh_test> testEh ("mpfr_asinh"); +static mpfr_test<mpfr_atanh_test> testFh ("mpfr_atanh"); + +/* Do the test */ +template <class T> +bool mpfr_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + + /* Init and set tables if first call */ + if (size == 0) { + size = base.size (); + tim = new timming (size); + table = new mpfr_t[size]; + for (i = 0 ; i < size ; i++) { + mpfr_init2 (table[i], opt.prec); + mpfr_set_str (table[i], base[i].c_str(), 10, GMP_RNDN); + } + mpfr_inits2 (opt.prec, a, b, c, NULL); + } + + /* Do Measure */ + for(i = 0 ; i < (size-1) ; i++) { + mpfr_set (b, table[i], GMP_RNDN); + mpfr_set (c, table[i+1], GMP_RNDN); + TIMP_OVERHEAD (); + m = TIMP_MEASURE (f.func (a, b, c, GMP_RNDN) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-ntl.cc b/tools/mbench/mfv5-ntl.cc new file mode 100644 index 000000000..7c32fcf11 --- /dev/null +++ b/tools/mbench/mfv5-ntl.cc @@ -0,0 +1,115 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" + +#define NTL_STD_CXX +#include "NTL/RR.h" + +#include "timp.h" + +using namespace std; +using namespace NTL; + +/* Register New Test */ +template <class T> +class ntl_test : public registered_test { +private: + unsigned long size; + RR *table; + RR a, b, c; + timming *tim; +public: + ntl_test (const char *n) : registered_test (n), size (0) {} + ~ntl_test () { + if (size != 0) { + delete tim; + delete[] table; + } + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class ntl_add_test { +public: + void func (RR &a, const RR &b, const RR &c) { + a = b + c; + } +}; +class ntl_sub_test { +public: + void func (RR &a, const RR &b, const RR &c) { + a = b - c; + } +}; +class ntl_mul_test { +public: + void func (RR &a, const RR &b, const RR &c) { + a = b * c; + } +}; +class ntl_div_test { +public: + void func (RR &a, const RR &b, const RR &c) { + a = b / c; + } +}; + +static ntl_test<ntl_add_test> test1 ("ntl_add"); +static ntl_test<ntl_sub_test> test2 ("ntl_sub"); +static ntl_test<ntl_mul_test> test3 ("ntl_mul"); +static ntl_test<ntl_div_test> test4 ("ntl_div"); + +/* Do the test */ +template <class T> +bool ntl_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + + /* Init and set tables if first call */ + if (size == 0) { + size = base.size (); + tim = new timming (size); + table = new RR[size]; + for (i = 0 ; i < size ; i++) + { + table[i].SetPrecision (opt.prec); + table[i] = to_RR (base[i].c_str()); + } + a.SetPrecision (opt.prec); + b.SetPrecision (opt.prec); + c.SetPrecision (opt.prec); + } + + /* Do Measure */ + for(i = 0 ; i < (size-1) ; i++) { + b = table[i]; + c = table[i+1]; + TIMP_OVERHEAD (); + m = TIMP_MEASURE (f.func (a, b, c) ); + cont = tim->update (i, m) || cont; + } + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-pari.cc b/tools/mbench/mfv5-pari.cc new file mode 100644 index 000000000..ce020054f --- /dev/null +++ b/tools/mbench/mfv5-pari.cc @@ -0,0 +1,123 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mfv5.h" +#include "timp.h" + +#include "pari/pari.h" + +using namespace std; + +static int pari_init_cpt = 0; + +/* Register New Test */ +template <class T> +class pari_test : public registered_test { +private: + unsigned long size; + GEN *table; + GEN a, b, c; + timming *tim; +public: + pari_test (const char *n) : registered_test (n), size (0) { + if (pari_init_cpt == 0) + pari_init (40000000, 10000); + pari_init_cpt ++; + } + ~pari_test () { + if (size != 0) + delete[] table; + if (-- pari_init_cpt == 0) + (void) 0; // pari_clear (); + } + bool test (const vector<string> &base, const option_test &opt); +}; + +class pari_add_test { +public: + void func (GEN a, GEN b, GEN c) { + mpaddz (b, c, a); + } +}; + +class pari_sub_test { +public: + void func (GEN a, GEN b, GEN c) { + mpsubz (b, c, a); + } +}; + +class pari_mul_test { +public: + void func (GEN a, GEN b, GEN c) { + mpmulz (b, c, a); + } +}; + +class pari_div_test { +public: + void func (GEN a, GEN b, GEN c) { + mpdivz (b, c, a); + } +}; + +static pari_test<pari_add_test> test1 ("pari_add"); +static pari_test<pari_sub_test> test2 ("pari_sub"); +static pari_test<pari_mul_test> test3 ("pari_mul"); +static pari_test<pari_div_test> test4 ("pari_div"); + + +/* Do the test */ +template <class T> +bool pari_test<T>::test (const vector<string> &base, const option_test &opt) { + unsigned long i; + unsigned long long m; + T f; + bool cont = false; + GEN stck; + + /* Init and set tables if first call */ + if (size == 0) { + size = base.size (); + tim = new timming (size); + table = new GEN[size]; + /* FIXME: How to really fix the size of table[i]? */ + for (i = 0 ; i < size ; i++) + table[i] = flisexpr((char *) base[i].c_str()); + a = gsqrt(stoi(3), (opt.prec - 1)/BITS_IN_LONG + 1 + 2); + b = gsqrt(stoi(5), (opt.prec - 1)/BITS_IN_LONG + 1 + 2); + c = gsqrt(stoi(7), (opt.prec - 1)/BITS_IN_LONG + 1 + 2); + } + + /* Do Measure */ + stck = (GEN) avma; + for(i = 0 ; i < (size-1) ; i++) { + mpaff (table[i], b); + mpaff (table[i+1], c); + TIMP_OVERHEAD (); + m = TIMP_MEASURE(f.func (a, b, c) ); + cont = tim->update (i, m) || cont; + } + avma = (ulong) stck; + + tim->print (get_name(), opt); + return cont; +} diff --git a/tools/mbench/mfv5-void.cc b/tools/mbench/mfv5-void.cc new file mode 100644 index 000000000..0372f9857 --- /dev/null +++ b/tools/mbench/mfv5-void.cc @@ -0,0 +1,21 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + diff --git a/tools/mbench/mfv5.cc b/tools/mbench/mfv5.cc new file mode 100644 index 000000000..eaa2a76c1 --- /dev/null +++ b/tools/mbench/mfv5.cc @@ -0,0 +1,174 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <mpfr.h> + +#include "timp.h" + +#include "mfv5.h" + +#define USAGE \ + "Bench functions for Pentium (V5++).\n" \ + __FILE__" " __DATE__" " __TIME__" GCC "__VERSION__ "\n" \ + "Usage: mfv5 [-pPREC] [-sSEED] [-mSIZE] [-iPRIO] [-lLIST] tests ...\n" + +using namespace std; + +registered_test *first_registered_test = 0; + +bool +do_test (const char *n, const vector<string> &base, const option_test &opt) { + registered_test *p; + int all = strcmp (n, "all") == 0; + bool ret = false; + + TIMP_OVERHEAD (); + + p = first_registered_test; + while (p) { + if (all || p->is (n)) + ret = p->test (base, opt) || ret; + p = p->next (); + } + return ret; +} + +void +list_test (void) { + registered_test *p; + + p = first_registered_test; + while (p) { + cout << p->get_name () << endl; + p = p->next (); + } + cout << "all\n"; + return; +} + +void +build_base (vector<string> &base, const option_test &opt) +{ + unsigned long i, n = opt.stat; + mpfr_t x; + gmp_randstate_t state; + const char *str; + mpfr_exp_t e; + char *buffer; + + mpfr_init2 (x, opt.prec); + gmp_randinit_lc_2exp_size (state, 128); + gmp_randseed_ui (state, opt.seed); + + for (i = 0 ; i < n ; i++) { + mpfr_urandomb (x, state); + mpfr_mul_2si (x, x, (rand()%GMP_NUMB_BITS)-(GMP_NUMB_BITS/2), GMP_RNDN); + str = mpfr_get_str (NULL, &e, 10, 0, x, GMP_RNDN); + if (str == 0) + abort (); + buffer = (char *) malloc (strlen(str)+50); + if (buffer == 0) + abort (); + sprintf (buffer, "%sE%ld", str, (unsigned long) e-strlen(str)+1); + base.push_back (buffer); + if (opt.verbose) + cout << "[" << i << "] = " << buffer << endl; + free (buffer); + mpfr_free_str ((char*)str); + } + + gmp_randclear(state); + mpfr_clear (x); +} + + +int main (int argc, const char *argv[]) +{ + option_test options; + vector<string> base; + int i, j, cont, prio; + + /* Parse option */ + prio = 19; + for(i = 1 ; i < argc ; i++) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'h': + cout << USAGE; + exit (0); + break; + case 'p': + options.prec = atol (argv[i]+2); + break; + case 's': + options.seed = atol (argv[i]+2); + break; + case 'm': + options.stat = atol (argv[i]+2); + break; + case 'v': + options.verbose = true; + break; + case 'i': + prio = atol (argv[i]+2); + break; + case 'l': + list_test (); + exit (0); + break; + default: + cerr << "Unkwown option:" << argv[i] << endl; + exit (1); + break; + } + } + } + + if (options.verbose) + cout << USAGE; + + /* Set low priority */ + setpriority(PRIO_PROCESS, 0, prio); + + /* Build Used Base */ + if (options.verbose) + cout << "Building DATA Base\n"; + mp_set_memory_functions (NULL, NULL, NULL); + build_base (base, options); + + /* Do test */ + for (j = 1, cont = 5 ; cont ; j++, cont--) { + cout << "Pass " << j << endl; + for(i = 1 ; i < argc ; i++) + if (argv[i][0] != '-') + if (do_test (argv[i], base, options)) + cont = 5; + } + + /* Final */ + if (options.verbose) + cout << "Used precision: " << options.prec << endl; + + return 0; +} diff --git a/tools/mbench/mfv5.h b/tools/mbench/mfv5.h new file mode 100644 index 000000000..253d2e23d --- /dev/null +++ b/tools/mbench/mfv5.h @@ -0,0 +1,119 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef __MPFR_T_LOW_BENCHMARCH_H__ +#define __MPFR_T_LOW_BENCHMARCH_H__ + +#include <iostream> +#include <stdio.h> /* for printf and putchar */ +#include <cstring> +#include <cstdlib> +#include <climits> +#include <algorithm> +#include <cstddef> +#include <vector> +#include <string> + +#include <sys/time.h> +#include <sys/resource.h> + +struct option_test { + unsigned long prec; + unsigned long seed; + unsigned long stat; + bool verbose; + option_test () : prec (53), seed (14528596), stat (100), verbose (false) {} +}; + +class registered_test; +extern registered_test *first_registered_test; + +class registered_test { + private: + const char *name; + registered_test *next_test; + public: + registered_test (const char *n) : name (n) { + next_test = first_registered_test; + first_registered_test = this; + } + virtual ~registered_test () {} + registered_test *next (void) { + return next_test; + } + const char *get_name (void) { + return name; + } + bool is (const char *n) { + return strcmp (n, name) == 0; + } + virtual bool test (const std::vector<std::string> &base, const option_test &opt) { + return false; + } +}; + +class timming { + private: + unsigned long size; + unsigned long long *besttime; + + public: + timming (unsigned long s) : size (s) { + besttime = new unsigned long long[size]; + for (unsigned long i = 0 ; i < size ; i++) + besttime[i] = 0xFFFFFFFFFFFFFFFLL; + } + + ~timming () { + delete[] besttime; + } + + bool update (unsigned long i, unsigned long long m) { + if (size <= i) + abort (); + if (m < besttime[i]) { + besttime[i] = m; + return true; + } else + return false; + } + + void print (const char *name, const option_test &opt) { + unsigned long long min, max, moy; + unsigned long imin = 0, imax = 0; + min = 0xFFFFFFFFFFFFFFFLL; + max = moy = 0; + for(unsigned long i = 0 ; i < (size-1) ; i++) { + if (besttime[i] < min) + { min = besttime[i]; imin = i; } + if (besttime[i] > max) + { max = besttime[i]; imax = i; } + moy += besttime[i]; + } + printf (" %s:\t %5Lu / %5Lu.%02Lu / %5Lu", name, + min, moy/(size-1), (moy*100/(size-1))%100, max); + if (opt.verbose) + printf ("\t Imin=%3lu Imax=%3lu", imin, imax); + putchar ('\n'); + } +}; + +#endif diff --git a/tools/mbench/mpfr-gfx.c b/tools/mbench/mpfr-gfx.c new file mode 100644 index 000000000..aa66adc85 --- /dev/null +++ b/tools/mbench/mpfr-gfx.c @@ -0,0 +1,447 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier and Paul Zimmermann, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <string.h> +#include <limits.h> +#include <sys/time.h> +#include <sys/resource.h> + +#include "timp.h" + +/* To avoid __gmpf_cmp to be declared as pure */ +#define __GMP_NO_ATTRIBUTE_CONST_PURE +#include "gmp.h" +#include "mpfr.h" + +#ifdef SCS_SUPPORT +# define SCS(x) x +# include "scs.h" +# define EXTRA_TEST_LIST \ + BENCH("SCSLIB( Compiled var ):::::::::::", ; ); \ + BENCH("scs_add", scs_add(sc1,sc2,sc3)); \ + BENCH("scs_sub", scs_sub(sc1,sc2,sc3)); \ + BENCH("scs_mul", scs_mul(sc1,sc2,sc3)); \ + BENCH("scs_div", scs_div(sc1,sc2,sc3)); \ + BENCH("scs_set", scs_set(sc1,sc2)); \ + BENCH("scs_set0", scs_set_si(sc1,0)); \ + BENCH("scs_set1", scs_set_si(sc1,1)); +#else +# define SCS(x) ((void) 0) +# define EXTRA_TEST_LIST ((void)0); +#endif + +#undef EXTRA_TEST_LIST +# define EXTRA_TEST_LIST \ + BENCH("mpfr_exp", mpfr_exp(a,b,GMP_RNDN)); \ + BENCH("mpfr_log", mpfr_log(a,b,GMP_RNDN)); \ + BENCH("mpfr_sin", mpfr_sin(a,b,GMP_RNDN)); \ + BENCH("mpfr_cos", mpfr_cos(a,b,GMP_RNDN)); \ + BENCH("mpfr_tan", mpfr_tan(a,b,GMP_RNDN)); \ + BENCH("mpfr_asin", mpfr_asin(a,b,GMP_RNDN)); \ + BENCH("mpfr_acos", mpfr_acos(a,b,GMP_RNDN)); \ + BENCH("mpfr_atan", mpfr_atan(a,b,GMP_RNDN)); \ + BENCH("mpfr_agm", mpfr_agm(a,b,c,GMP_RNDN)); \ + BENCH("mpfr_const_log2", (mpfr_const_log2) (a, GMP_RNDN)); \ + BENCH("mpfr_const_pi", (mpfr_const_pi)(a, GMP_RNDN)); \ + BENCH("mpfr_sinh", mpfr_sinh(a,b,GMP_RNDN)); \ + BENCH("mpfr_cosh", mpfr_cosh(a,b,GMP_RNDN)); \ + BENCH("mpfr_tanh", mpfr_tanh(a,b,GMP_RNDN)); \ + BENCH("mpfr_asinh", mpfr_asinh(a,b,GMP_RNDN)); \ + BENCH("mpfr_acosh", mpfr_acosh(a,b,GMP_RNDN)); \ + BENCH("mpfr_atanh", mpfr_atanh(a,b,GMP_RNDN)); + + + +/* Theses macros help the compiler to determine if a test is likely*/ +/* or unlikely. */ +#if __GNUC__ >= 3 +# define LIKELY(x) (__builtin_expect(!!(x),1)) +# define UNLIKELY(x) (__builtin_expect((x),0)) +#else +# define LIKELY(x) (x) +# define UNLIKELY(x) (x) +#endif + +/* + * List of all the tests to do. + * Macro "BENCH" is defined below. + */ +#define TEST_LIST \ + BENCH("MPFR::::::::::", ; ); \ + BENCH("mpfr_add", mpfr_add(a,b,c,GMP_RNDN)); \ + BENCH("mpfr_sub", mpfr_sub(a,b,c,GMP_RNDN)); \ + BENCH("mpfr_mul", mpfr_mul(a,b,c,GMP_RNDN)); \ + BENCH("mpfr_div", mpfr_div(a,b,c,GMP_RNDN)); \ + BENCH("mpfr_sqrt", mpfr_sqrt(a,b,GMP_RNDN)); \ + BENCH("mpfr_cmp", mpfr_cmp(b,c)); \ + BENCH("mpfr_sgn", mpfr_sgn(b)); \ + BENCH("mpfr_set", mpfr_set(a,b, GMP_RNDN)); \ + BENCH("mpfr_set0", mpfr_set_si(a,0,GMP_RNDN)); \ + BENCH("mpfr_set1", mpfr_set_si(a,1,GMP_RNDN)); \ + BENCH("mpfr_swap", mpfr_swap(b,c)); \ + BENCH("MPF:::::::::::", ; ); \ + BENCH("mpf_add", mpf_add(x,y,z)); \ + BENCH("mpf_sub", mpf_sub(x,y,z)); \ + BENCH("mpf_mul", mpf_mul(x,y,z)); \ + BENCH("mpf_div", mpf_div(x,y,z)); \ + BENCH("mpf_sqrt", mpf_sqrt(x,y)); \ + BENCH("mpf_cmp", mpf_cmp(y,z)); \ + BENCH("mpf_set", mpf_set(x,y)); \ + BENCH("mpf_set0", mpf_set_si(x,0)); \ + BENCH("mpf_set1", mpf_set_si(x,1)); \ + BENCH("mpf_swap", mpf_swap(y,z)); \ + EXTRA_TEST_LIST + +#define USAGE \ + "Get the graph of the low-level functions of Mpfr (gnuplot).\n" \ + __FILE__" " __DATE__" " __TIME__" GCC "__VERSION__ "\n" \ + "Usage: mpfr-gfx [-bPREC_BEGIN] [-ePREC_END] [-sPREC_STEP] [-rPREC_RATIO]\n" \ + " [-mSTAT_SIZE] [-oFILENAME] [-xFUNCTION_NUM] [-yFUNCTION_NUM] [-c]\n" \ + " [-fSMOOTH] [-p]\n" + +unsigned long num; +mpf_t *xt, *yt, *zt; +int smooth = 3; /* (default) minimal number of routine calls for each number */ + +void lets_start(unsigned long n, mpfr_prec_t p) +{ + unsigned long i; + gmp_randstate_t state; + + num = n; + xt = malloc(sizeof(mpf_t) * num); + yt = malloc(sizeof(mpf_t) * num); + zt = malloc(sizeof(mpf_t) * num); + if (xt==NULL || yt==NULL || zt==NULL) + { + fprintf(stderr, "Can't allocate tables!\n"); + abort(); + } + + gmp_randinit_lc_2exp_size (state, 128); + gmp_randseed_ui (state, 1452369); + for(i = 0 ; i < num ; i++) + { + mpf_init2(xt[i], p); + mpf_init2(yt[i], p); + mpf_init2(zt[i], p); + mpf_urandomb(yt[i], state, p); + mpf_urandomb(zt[i], state, p); + } + gmp_randclear(state); +} + +void lets_end(void) +{ + unsigned long i; + + for(i = 0 ; i < num ; i++) + { + mpf_clear(xt[i]); + mpf_clear(yt[i]); + mpf_clear(zt[i]); + } + free (xt); + free (yt); + free (zt); +} + +double get_speed(mpfr_prec_t p, int select) +{ + unsigned long long mc[num], m; + mpfr_t a,b,c; + mpf_t x,y,z; + unsigned long long moy; + int i,j=0, op, cont, print_done = 0; + const char *str = "void"; + SCS(( scs_t sc1, sc2, sc3 )); + + mpf_init2(x, p); mpf_init2(y, p); mpf_init2(z, p); + mpfr_init2(a, p); mpfr_init2(b, p); mpfr_init2(c, p); + + for(i = 0 ; i < num ; i++) + { + // yt[i][0]._mp_exp = (rand() % p) / GMP_NUMB_BITS; + //zt[i][0]._mp_exp = (rand() % p) / GMP_NUMB_BITS; + mc[i] = 0xFFFFFFFFFFFFFFFLL; + } + + TIMP_OVERHEAD (); + + /* we perform at least smooth loops */ + for(j = 0, cont = smooth ; cont ; j++, cont--) + { + /* we loop over each of the num random numbers */ + for(i = 0 ; i < num ; i++) + { + /* Set var for tests */ + mpf_set(y, yt[i]); + mpf_set(z, zt[i]); + mpfr_set_f(b, yt[i], GMP_RNDN); + mpfr_set_f(c, zt[i], GMP_RNDN); + SCS(( scs_set_mpfr(sc2, b), scs_set_mpfr(sc3, c) )); + /* if the measured time m is smaller than the smallest one + observed so far mc[i] for the i-th random number, we start + again the smooth loops */ +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (op++ == select) { \ + m = TIMP_MEASURE(TEST); \ + str = TEST_STR; \ + if (m < mc[i]) {mc[i] = m; cont = smooth;}\ + } + op = 0; + TEST_LIST; + if (print_done == 0 && strcmp (str, "void") != 0 ) + { + printf("Prec=%4.4lu Func=%20.20s", p, str); + fflush (stdout); + print_done = 1; + } + } + } + mpfr_clear(a); mpfr_clear(b); mpfr_clear(c); + mpf_clear(x); mpf_clear(y); mpf_clear(z); + /* End */ + /* Save result */ + moy = mc[0]; + for(i = 1 ; i < num ; i++) moy += mc[i]; + printf(" Pass=%4.4d..................%Lu.%Lu\n", + j+1, moy/num, (moy*100LL/num)%100LL); + return (double) (moy) / (double) num; +} + +/* compares two functions given by indices select1 and select2 + (by default select1 refers to mpfr and select2 to mpf). + + If postscript=0, output is plain gnuplot; + If postscript=1, output is postscript. +*/ +int +write_data (const char *filename, + unsigned long num, + mpfr_prec_t p1, mpfr_prec_t p2, mpfr_prec_t ps, float pr, + int select1, int select2, int postscript) +{ + char strf[256], strg[256]; + FILE *f, *g; + mpfr_prec_t p, step; + int op = 0; + + lets_start (num, p2); + strcpy (strf, filename); + strcat (strf, ".data"); + f = fopen (strf, "w"); + if (f == NULL) + { + fprintf (stderr, "Can't open %s!\n", strf); + lets_end (); + abort (); + } + strcpy (strg, filename); + strcat (strg, ".gnuplot"); + g = fopen (strg, "w"); + if (g == NULL) + { + fprintf (stderr, "Can't open %s!\n", strg); + lets_end (); + abort (); + } + fprintf (g, "set data style lines\n"); + if (postscript) + fprintf (g, "set terminal postscript\n"); +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (++op == select1) \ + fprintf (g, "plot \"%s\" using 1:2 title \"%s\", \\\n", strf, \ + TEST_STR); \ + else if (op == select2) \ + fprintf (g, " \"%s\" using 1:3 title \"%s\"\n", strf, TEST_STR); + op = -1; + TEST_LIST; + + step = ps; + for (p = p1 ; p < p2 ; p+=step) + { + fprintf(f, "%lu\t%1.20e\t%1.20e\n", p, + get_speed(p, select1), + get_speed(p, select2)); + if (pr != 0.0) + { + step = (mpfr_prec_t) (p * pr - p); + if (step < 1) + step = 1; + } + } + + fclose (f); + fclose (g); + lets_end (); + if (postscript == 0) + fprintf (stderr, "Now type: gnuplot -persist %s.gnuplot\n", filename); + else + fprintf (stderr, "Now type: gnuplot %s.gnuplot > %s.ps\n", filename, + filename); + return 0; +} + +/* this function considers all functions from s_begin to s_end */ +int +write_data2 (const char *filename, + unsigned long num, + mpfr_prec_t p_begin, mpfr_prec_t p_end, mpfr_prec_t p_step, float p_r, + int s_begin, int s_end) +{ + FILE *f; + mpfr_prec_t p, step; + int s; + + lets_start (num, p_end); + f = fopen (filename, "w"); + if (f == NULL) + { + fprintf (stderr, "Can't open %s!\n", filename); + lets_end (); + exit (1); + } + + step = p_step; + for (p = p_begin ; p < p_end ; p += step) + { + fprintf (f, "%lu", p); + for (s = s_begin ; s <= s_end ; s++) + fprintf (f, "\t%1.20e", get_speed (p, s)); + fprintf (f, "\n"); + if (p_r != 0.0) + { + step = (mpfr_prec_t) (p * p_r - p); + if (step < 1) + step = 1; + } + } + fclose (f); + lets_end (); + return 0; +} + +int op_num (void) +{ + int op; +#undef BENCH +#define BENCH(TEST_STR, TEST) op++; + op = 0; + TEST_LIST; + return op; +} + +int main(int argc, const char *argv[]) +{ + mpfr_prec_t p1, p2, ps; + float pr; + int i; + unsigned long stat; + const char *filename = "plot"; + int select1, select2, max_op, conti; + int postscript = 0; + + printf (USAGE); + + max_op = op_num (); + select1 = 1; select2 = 13; + p1 = 2; p2 = 500; ps = 4; pr = 0.0; + stat = 500; /* number of different random numbers */ + conti = 0; + + for(i = 1 ; i < argc ; i++) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'b': + p1 = atol(argv[i]+2); + break; + case 'e': + p2 = atol(argv[i]+2); + break; + case 's': + ps = atol(argv[i]+2); + break; + case 'r': + pr = atof (argv[i]+2); + if (pr <= 1.0) + { + fprintf (stderr, "-rPREC_RATIO must be > 1.0\n"); + exit (1); + } + break; + case 'm': + stat = atol(argv[i]+2); + break; + case 'x': + select1 = atoi (argv[i]+2); + select2 = select1 + 12; + break; + case 'y': + select2 = atoi (argv[i]+2); + break; + case 'o': + filename = argv[i]+2; + break; + case 'c': + conti = 1; + break; + case 'p': + postscript = 1; + break; + case 'f': + smooth = atoi (argv[i]+2); + break; + default: + fprintf(stderr, "Unkwown option: %s\n", argv[i]); + abort (); + } + } + } + /* Set low priority */ + setpriority(PRIO_PROCESS,0,14); + if (pr == 0.0) + printf("GMP:%s MPFR:%s From p=%lu to %lu by %lu Output: %s N=%ld\n", + gmp_version, mpfr_get_version(), p1,p2,ps, filename, stat); + else + printf("GMP:%s MPFR:%s From p=%lu to %lu by %f Output: %s N=%ld\n", + gmp_version, mpfr_get_version(), p1, p2, pr, filename, stat); + + if (select2 >= max_op) + select2 = max_op-1; + if (select1 >= max_op) + select1 = max_op-1; + + if (conti == 0) + write_data (filename, stat, p1, p2, ps, pr, select1, select2, postscript); + else + write_data2 (filename, stat, p1, p2, ps, pr, select1, select2); + + return 0; +} diff --git a/tools/mbench/mpfr-v4.c b/tools/mbench/mpfr-v4.c new file mode 100644 index 000000000..5a53ad10e --- /dev/null +++ b/tools/mbench/mpfr-v4.c @@ -0,0 +1,300 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <limits.h> +#include <sys/time.h> +#include <sys/resource.h> + +#include "timp.h" + +/* To avoid __gmpf_cmp to be declared as pure */ +#define __GMP_NO_ATTRIBUTE_CONST_PURE +#include "gmp.h" +#include "mpfr.h" + +/* Theses macros help the compiler to determine if a test is likely*/ +/* or unlikely. */ +#if __GNUC__ >= 3 +# define LIKELY(x) (__builtin_expect(!!(x),1)) +# define UNLIKELY(x) (__builtin_expect((x),0)) +#else +# define LIKELY(x) (x) +# define UNLIKELY(x) (x) +#endif + +/* + * List of all the tests to do. + * Macro "Bench" is defined futhermore + */ +#define TEST_LIST \ + BENCH("MPFR::::::::::", ; ); \ + BENCH("add", mpfr_add(a,b,c,GMP_RNDN)); \ + BENCH("sub", mpfr_sub(a,b,c,GMP_RNDN)); \ + BENCH("mul", mpfr_mul(a,b,c,GMP_RNDN)); \ + BENCH("div", mpfr_div(a,b,c,GMP_RNDN)); \ + BENCH("sqrt", mpfr_sqrt(a,b,GMP_RNDN)); \ + BENCH("cmp", mpfr_cmp(b,c)); \ + BENCH("set", mpfr_set(a,b, GMP_RNDN)); \ + BENCH("set0", mpfr_set_ui(a,0,GMP_RNDN)); \ + BENCH("set1", mpfr_set_ui(a,1,GMP_RNDN)); \ + BENCH("setz", mpfr_set_z(a,zz,GMP_RNDN)); \ + BENCH("swap", mpfr_swap(b,c)); \ + BENCH("MPF:::::::::::", ; ); \ + BENCH("add", mpf_add(x,y,z)); \ + BENCH("sub", mpf_sub(x,y,z)); \ + BENCH("mul", mpf_mul(x,y,z)); \ + BENCH("div", mpf_div(x,y,z)); \ + BENCH("sqrt", mpf_sqrt(x,y)); \ + BENCH("cmp", mpf_cmp(y,z)); \ + BENCH("set", mpf_set(x,y)); \ + BENCH("set0", mpf_set_ui(x,0)); \ + BENCH("set1", mpf_set_ui(x,1)); \ + BENCH("swap", mpf_swap(y,z)); + + +#define USAGE \ + "Bench the low-level functions of Mpfr (V4).\n" \ + __FILE__" " __DATE__" " __TIME__" GCC "__VERSION__ "\n" \ + "Usage: mpfr_bench [-pPRECISION] [-sRANDSEED] [-mSTAT_SIZE] [-v]\n" \ + " [-paPREC_RESULT] [-pbPREC_OP1] [-pcPREC_OP2] [-bOP1_VALUE] [-cOP2_VALUE]\n" + +int verbose = 0; + +void mpfr_bench(mpfr_prec_t prec_a, mpfr_prec_t prec_b, mpfr_prec_t prec_c, + const char *b_str, const char *c_str, unsigned long seed) +{ + mpfr_t a,b,c; + mpf_t x,y,z; + mpz_t zz; + gmp_randstate_t state; + + gmp_randinit_lc_2exp_size (state, 128); + gmp_randseed_ui (state, seed); + + mpfr_init2(a, prec_a); + mpfr_init2(b, prec_b); + mpfr_init2(c, prec_c); + + mpf_init2(x, prec_a); + mpf_init2(y, prec_b); + mpf_init2(z, prec_c); + + if (b_str) + mpf_set_str(y, b_str, 10); + else + mpf_urandomb(y, state, prec_b); + if (c_str) + mpf_set_str(z, c_str, 10); + else + mpf_urandomb(z, state, prec_c); + mpfr_set_f(b, y, GMP_RNDN); + mpfr_set_f(c, z, GMP_RNDN); + mpz_init (zz); + mpz_urandomb (zz, state, 2*prec_b); + + if (verbose) + { + printf("B="); mpfr_out_str(stdout, 10, 0, b, GMP_RNDD); + printf("\nC="); mpfr_out_str(stdout, 10, 0, c, GMP_RNDD); + putchar('\n'); + } + TIMP_OVERHEAD (); +#undef BENCH +#define BENCH(TEST_STR, TEST) printf(" "TEST_STR": %Lu\n", TIMP_MEASURE(TEST)) + TEST_LIST; + + mpz_clear (zz); + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + mpf_clear (x); + mpf_clear (y); + mpf_clear (z); + gmp_randclear (state); +} + +#define MAX_OP 40 +void mpfr_stats (unsigned long num, mpfr_prec_t prec_a, mpfr_prec_t prec_b, + mpfr_prec_t prec_c, unsigned long seed) +{ + mpf_t xt[num],yt[num],zt[num]; + unsigned long long mc[num][MAX_OP], m; + mpfr_t a, b, c; + mpf_t x, y, z; + mpz_t zz; + unsigned long long min,max,moy; + gmp_randstate_t state; + int i,j=0, op, cont; + int imin=0, imax=0; + + mpf_init2(x, prec_a); + mpf_init2(y, prec_b); + mpf_init2(z, prec_c); + + mpfr_init2(a, prec_a); + mpfr_init2(b, prec_b); + mpfr_init2(c, prec_c); + + gmp_randinit_lc_2exp_size (state, 128); + gmp_randseed_ui (state, seed); + + mpz_init (zz); + mpz_urandomb (zz, state, 2*prec_b); + + TIMP_OVERHEAD (); + + for(i = 0 ; i < num ; i++) + { + mpf_init2(xt[i], prec_a); + mpf_init2(yt[i], prec_b); + mpf_init2(zt[i], prec_c); + mpf_urandomb(yt[i], state, prec_b); + yt[i][0]._mp_exp += (rand() % prec_b) / GMP_NUMB_BITS; + mpf_urandomb(zt[i], state, prec_c); + /* zt[i][0]._mp_exp += (rand() % prec_c) / GMP_NUMB_BITS; */ + for(op = 0 ; op < MAX_OP ; op++) + mc[i][op] = 0xFFFFFFFFFFFFFFFLL; + } + + for(j = 0, cont = 5 ; cont ; j++, cont--) + { + printf("Pass %d...\n", j+1); + for(i = 0 ; i < num ; i++) + { + op = 0; + mpf_set(y,yt[i]); + mpf_set(z,zt[i]); + mpfr_set_f(b, yt[i], GMP_RNDN); + mpfr_set_f(c, zt[i], GMP_RNDN); +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + m = TIMP_MEASURE(TEST); if (m < mc[i][op]) {mc[i][op] = m; cont = 4;} op++; + TEST_LIST; + } + +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + min = 0xFFFFFFFFFFFFFFFLL; max = 0LL; moy = 0LL; \ + for(i = 0 ; i < num ; i++) { \ + if (mc[i][op] < min) imin = i, min = mc[i][op]; \ + if (mc[i][op] > max) imax = i, max = mc[i][op]; \ + moy += mc[i][op]; \ + } \ + printf(" %s: %Lu / %Lu.%02Lu / %Lu", TEST_STR, min, \ + (unsigned long long) moy/num, (moy*100LL/num)%100LL, max); \ + if (verbose) printf ("\tMIN:%e,%e\tMAX:%e,%e", mpf_get_d(yt[imin]),\ + mpf_get_d(zt[imin]), mpf_get_d(yt[imax]), \ + mpf_get_d(zt[imax])); \ + putchar ('\n'); \ + op++; + + op =0; + TEST_LIST; + } + + printf("End\n"); + mpz_clear (zz); + mpfr_clear(a); + mpfr_clear(b); + mpfr_clear(c); + mpf_clear(x); + mpf_clear(y); + mpf_clear(z); + for(i = 0 ; i < num ; i++) + { + mpf_clear(xt[i]); + mpf_clear(yt[i]); + mpf_clear(zt[i]); + } + gmp_randclear(state); +} + +int main(int argc, const char *argv[]) +{ + mpfr_prec_t prec_a, prec_b, prec_c; + unsigned long seed, stat; + int i; + const char *b_strptr, *c_strptr; + + printf(USAGE); + + prec_a = prec_b = prec_c = 53; + b_strptr = c_strptr = NULL; + seed = 14528596; + stat = 0; + + for(i = 1 ; i < argc ; i++) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'b': + b_strptr = (const char *) (argv[i]+2); + break; + case 'c': + c_strptr = (const char *) (argv[i]+2); + break; + case 'p': + switch (argv[i][2]) + { + case 'a': + prec_a = atol(argv[i]+3); + break; + case 'b': + prec_b = atol(argv[i]+3); + break; + case 'c': + prec_c = atol(argv[i]+3); + break; + default: + prec_a = prec_b = prec_c = atol(argv[i]+2); + break; + } + break; + case 's': + seed = atol(argv[i]+2); + break; + case 'm': + stat = atol(argv[i]+2); + break; + case 'v': + verbose = 1; + break; + default: + fprintf(stderr, "Unkwown option: %s\n", argv[i]); + break; + } + } + } + /* Set low priority */ + setpriority(PRIO_PROCESS,0,15); + + if (stat) + mpfr_stats(stat, prec_a, prec_b, prec_c, seed); + else + mpfr_bench(prec_a, prec_b, prec_c, b_strptr, c_strptr, seed); + + return 0; +} diff --git a/tools/mbench/mpfr-v6.c b/tools/mbench/mpfr-v6.c new file mode 100644 index 000000000..8a1854c00 --- /dev/null +++ b/tools/mbench/mpfr-v6.c @@ -0,0 +1,379 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <float.h> +#include <math.h> +#include <sys/time.h> +#include <sys/resource.h> + +#include "gmp.h" +#include "mpfr.h" + +#ifndef mpfr_version +# define mpfr_version "< 2.1.0" +#endif + +#include "timp.h" +#include "generate.c" + +#ifdef SCS_SUPPORT +# define SCS(x) x +# include "scs.h" +# define EXTRA_TEST_LIST \ + BENCH("SCSLIB( Compiled var ):::::::::::", ; ); \ + BENCH("add", scs_add(sc1,sc2,sc3)); \ + BENCH("sub", scs_sub(sc1,sc2,sc3)); \ + BENCH("mul", scs_mul(sc1,sc2,sc3)); \ + BENCH("div", scs_div(sc1,sc2,sc3)); \ + BENCH("set", scs_set(sc1,sc2)); \ + BENCH("set0", scs_set_si(sc1,0)); \ + BENCH("set1", scs_set_si(sc1,1)); +#else +# define SCS(x) (void) 0 +# define EXTRA_TEST_LIST (void)0; +#endif + +/* + * List of all the tests to do. + * Macro "Bench" is defined futhermore + */ +#define TEST_LIST1 \ + BENCH("MPFR::::::::::", ; ); \ + BENCH("add", mpfr_add(a,b,c,GMP_RNDN)); \ + BENCH("sub", mpfr_sub(a,b,c,GMP_RNDN)); \ + BENCH("mul", mpfr_mul(a,b,c,GMP_RNDN)); \ + BENCH("div", mpfr_div(a,b,c,GMP_RNDN)); \ + BENCH("sqrt", mpfr_sqrt(a,b,GMP_RNDN)); \ + BENCH("cmp", mpfr_cmp(b,c)); \ + BENCH("sgn", (mpfr_sgn)(b)); \ + BENCH("set", mpfr_set(a,b, GMP_RNDN)); \ + BENCH("set0", mpfr_set_si(a,0,GMP_RNDN)); \ + BENCH("set1", mpfr_set_si(a,1,GMP_RNDN)); \ + BENCH("swap", mpfr_swap(b,c)); \ + BENCH("MPF:::::::::::", ; ); \ + BENCH("add", mpf_add(x,y,z)); \ + BENCH("sub", mpf_sub(x,y,z)); \ + BENCH("mul", mpf_mul(x,y,z)); \ + BENCH("div", mpf_div(x,y,z)); \ + BENCH("sqrt", mpf_sqrt(x,y)); \ + BENCH("cmp", (mpf_cmp)(y,z)); \ + BENCH("set", mpf_set(x,y)); \ + BENCH("set0", mpf_set_si(x,0)); \ + BENCH("set1", mpf_set_si(x,1)); \ + BENCH("swap", mpf_swap(y,z)); \ + EXTRA_TEST_LIST + +#define TEST_LIST2 \ + BENCH("mpfr_exp", mpfr_exp(a,b,GMP_RNDN)); \ + BENCH("mpfr_log", mpfr_log(a,b,GMP_RNDN)); \ + BENCH("mpfr_sin", mpfr_sin(a,b,GMP_RNDN)); \ + BENCH("mpfr_cos", mpfr_cos(a,b,GMP_RNDN)); \ + BENCH("mpfr_tan", mpfr_tan(a,b,GMP_RNDN)); \ + BENCH("mpfr_asin", mpfr_asin(a,b,GMP_RNDN)); \ + BENCH("mpfr_acos", mpfr_acos(a,b,GMP_RNDN)); \ + BENCH("mpfr_atan", mpfr_atan(a,b,GMP_RNDN)); \ + BENCH("mpfr_agm", mpfr_agm(a,b,c,GMP_RNDN)); \ + BENCH("mpfr_const_log2", (mpfr_const_log2) (a, GMP_RNDN)); \ + BENCH("mpfr_const_pi", (mpfr_const_pi)(a, GMP_RNDN)); \ + BENCH("mpfr_sinh", mpfr_sinh(a,b,GMP_RNDN)); \ + BENCH("mpfr_cosh", mpfr_cosh(a,b,GMP_RNDN)); \ + BENCH("mpfr_tanh", mpfr_tanh(a,b,GMP_RNDN)); \ + BENCH("mpfr_asinh", mpfr_asinh(a,b,GMP_RNDN)); \ + BENCH("mpfr_acosh", mpfr_acosh(a,b,GMP_RNDN)); \ + BENCH("mpfr_atanh", mpfr_atanh(a,b,GMP_RNDN)); \ + BENCH("exp", d1 = exp(d2)); \ + BENCH("log", d1 = log(d2)); \ + BENCH("sin", d1 = sin(d2)); \ + BENCH("cos", d1 = cos(d2)); \ + BENCH("tan", d1 = tan(d2)); \ + BENCH("asin", d1 = asin(d2)); \ + BENCH("acos", d1 = acos(d2)); \ + BENCH("atan", d1 = atan(d2)); + +#define TEST_LIST3 \ + BENCH("mpfr_cos", mpfr_cos(a,b,GMP_RNDN)); + +#define TEST_LIST4 \ + BENCH("get_d", d1 = mpfr_get_d (b, GMP_RNDN)); \ + BENCH("set_d", mpfr_set_d (b, d2, GMP_RNDN)); \ + BENCH("mul_ui", mpfr_mul_si (b, b, 123, GMP_RNDN)); + +#ifndef TEST_LIST +# define TEST_LIST TEST_LIST2 +#endif + +#define USAGE \ + "Bench the low-level functions of Mpfr (V6).\n" \ + __FILE__" " __DATE__" " __TIME__" GCC "__VERSION__ "\n"\ + "Usage: mpfr_v6 [-pPRECISION] [-mSIZE] [-v] [-ffilename]\n" \ + " [-oFUNC] [-l] [-goutgfxname] [-sSMOOTH] [-rGRANULARITY]\n" + +int verbose = 0; + +void mpf_set_fr (mpf_t dest, mpfr_t src, mp_rnd_t rnd) +{ + mpfr_exp_t exp; + char *tmp, *tmp2; + long len; + + tmp = mpfr_get_str(NULL, &exp, 10, 0, src, rnd); + len = strlen(tmp); + tmp2 = (char *) malloc(len+30); + if (tmp2 == NULL) + { + fprintf(stderr, "mpf_set_mpfr: error memory\n"); + exit (1); + } + sprintf(tmp2, "%s@%ld", tmp, exp-len); + mpf_set_str(dest, tmp2, -10); + free(tmp); + free(tmp2); +} + +#define MAX_OP 40 +void make_stats(const char *filename, int num, mpfr_prec_t prec, int select_op, + const char *outputname, int smooth, int granularity) +{ + mpfr_t tab[num+1]; + unsigned long long mc[num][MAX_OP], m; + mpfr_t a, b, c; + mpf_t x, y, z; + double d1, d2, d3; + unsigned long long min, max, moy; + int i, j, op, cont/*, min_i, max_i*/; + SCS(( scs_t sc1, sc2, sc3 )); + + /* INIT */ + mpf_init2 (x, prec); + mpf_init2 (y, prec); + mpf_init2 (z, prec); + mpfr_init2 (a, prec); + mpfr_init2 (b, prec); + mpfr_init2 (c, prec); + for(i = 0 ; i < num ; i++) + { + mpfr_init2 (tab[i], prec); + for(op = 0 ; op < MAX_OP ; op++) + mc[i][op] = 0xFFFFFFFFFFFFFFFLL; + } + mpfr_init2 (tab[i], prec); + + /* SET */ + gnumb_read (filename, tab, num+1); + + TIMP_OVERHEAD (); + + for(j = 0, cont = smooth ; cont ; j++, cont--) + { + printf("Pass %d...\n", j+1); + for(i = 0 ; i < num ; i++) + { + mpfr_set (b, tab[i+0], GMP_RNDN); + mpfr_set (c, tab[i+1], GMP_RNDN); + mpf_set_fr (y, b, GMP_RNDN); + mpf_set_fr (z, c, GMP_RNDN); + SCS(( scs_set_mpfr(sc2, b), scs_set_mpfr(sc3, c) )); + d1 = d2 = mpfr_get_d1 (b); + d3 = mpfr_get_d1 (c); +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (op==select_op || select_op<0) \ + {m = TIMP_MEASURE(TEST); \ + if (m < mc[i][op]) {mc[i][op] = m; cont = smooth;}} \ + op++; + op = 0; + TEST_LIST; + } + +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (op==select_op || select_op<0) { \ + min = 0xFFFFFFFFFFFFFFFLL; max = 0LL; moy = 0LL; \ + for(i = 0 ; i < num ; i++) { \ + if (mc[i][op] < min) min = mc[i][op]; \ + if (mc[i][op] > max) max = mc[i][op]; \ + moy += mc[i][op]; \ + } \ + printf(" %s: %Lu / %Lu.%02Lu / %Lu\n", TEST_STR,min,moy/num,(moy*100LL/num)%100LL, max);\ + } \ + op++; + op =0; + TEST_LIST; + } + printf("End\n"); + + if (verbose && select_op != 0) { + for (i = 0 ; i < num ; i++) { + printf ("Tab[%02d]=", i); mpfr_out_str (stdout, 2, 10, tab[i], GMP_RNDN); + printf ("\tt=%Lu\n", mc[i][select_op]); + } + } + + /* Output GNUPLOT data ? */ + if (outputname != NULL) + { + unsigned long count[granularity][MAX_OP]; + FILE *out; + char filename[100]; + + // Get min and max of cycle for all ops +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (op==select_op || select_op<0) \ + {for(i = 0 ; i < num ; i++) {\ + if (mc[i][op] < min) min = mc[i][op];\ + if (mc[i][op] > max) max = mc[i][op];}} op++; + min = 0xFFFFFFFFFFFFFFFLL; max = 0LL; moy = 0LL; op = 0; + TEST_LIST; + // Count it +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (op==select_op || select_op<0) \ + {for(i = 0 ; i < num ; i++) count[(mc[i][op]-min)*granularity/max][op]++;} op++; + memset (count, 0, sizeof(count)); + max -= min-1; op = 0; + TEST_LIST; + + // Output data + sprintf(filename, "%s.data", outputname); + out = fopen(filename, "w"); + if (out == NULL) + { + fprintf(stderr, "ERROR: Can't open %s\n", filename); + exit (-2); + } + for(i = 0 ; i < granularity ; i++) + { + fprintf (out, "%Lu\t", (min + max * i / granularity)); +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (op==select_op || select_op<0) \ + fprintf(out, "%lu\t", count[i][op]); op++; + op = 0; + TEST_LIST; + fprintf(out, "\n"); + } + fclose (out); + + // Output GNUPLOT Info + sprintf(filename, "%s.gnuplot", outputname); + out = fopen(filename, "w"); + if (out == NULL) + { + fprintf(stderr, "ERROR: Can't open %s\n", filename); + exit (-2); + } + fprintf (out, "set key left\n" + "set data style linespoints\n" + "plot "); + + // "toto.data" using 1:2 title "mpfr_log", + // "toto.data" using 1:3 title "mpfr_exp" +#undef BENCH +#define BENCH(TEST_STR, TEST) \ + if (op==select_op || select_op<0) \ + fprintf(out, "%c \"%s.data\" using 1:%d title \"%s\" ", ((i==2) ? ' ' : ','), outputname, i, TEST_STR), i++; op++; + op = 0; i = 2; + TEST_LIST; + fprintf(out, "\nload \"-\"\n"); + fclose (out); + } + + mpfr_clear(a); + mpfr_clear(b); + mpfr_clear(c); + mpf_clear(x); + mpf_clear(y); + mpf_clear(z); + for(i = 0 ; i < num+1 ; i++) + mpfr_clear(tab[i]); +} + +int main(int argc, const char *argv[]) +{ + mpfr_prec_t prec; + unsigned long stat; + int i, select_op = -1, smooth = 3, granularity = 10, op; + const char *filename = "float.data"; + const char *output = NULL; + + printf(USAGE); + + prec = 53; + stat = 100; + + for(i = 1 ; i < argc ; i++) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'l': +#undef BENCH +#define BENCH(STR,TEST) printf("%d: %s\n", op, STR); op++; + op = 0; + TEST_LIST; + exit (0); + break; + case 'p': + prec = atol(argv[i]+2); + break; + case 'm': + stat = atol(argv[i]+2); + break; + case 'v': + verbose = 1; + break; + case 'f': + filename = &argv[i][2]; + break; + case 'o': + select_op = atoi(argv[i]+2); + break; + case 'g': + output = &argv[i][2]; + break; + case 's': + smooth = atoi(argv[i]+2); + break; + case 'r': + granularity = atoi(argv[i]+2); + break; + default: + fprintf(stderr, "Unkwown option: %s\n", argv[i]); + exit (1); + break; + } + } + } + /* Set low priority */ + setpriority(PRIO_PROCESS,0,15); + printf("GMP: %s\tMPFR: %s\t DATA: %s\n", + gmp_version, mpfr_version, filename); + make_stats (filename, stat, prec, select_op, output, smooth, granularity); + + return 0; +} diff --git a/tools/mbench/timp.h b/tools/mbench/timp.h new file mode 100644 index 000000000..5b7ce6429 --- /dev/null +++ b/tools/mbench/timp.h @@ -0,0 +1,127 @@ +/* +Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by Patrick Pelissier, INRIA. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef __TIMP__H__ +#define __TIMP__H__ + +/* Usage: + * Before doing the measure, call TIMP_OVERHEAD (); + * Then unsigned long long t = TIMP_MEASURE (f(x)); + * to measure the # of cycles taken by the call to f(x). + */ + +#define TIMP_VERSION 1*100+0*10+0 + +#ifndef __GNUC__ +# error CC != GCC +#endif + +/* High accuracy timing */ +#if defined (__i386__) || defined(__amd64__) + +#define timp_rdtsc_before(time) \ + __asm__ __volatile__( \ + ".align 64\n\t" \ + "xorl %%eax,%%eax\n\t" \ + "cpuid\n\t" \ + "rdtsc\n\t" \ + "movl %%eax,(%0)\n\t" \ + "movl %%edx,4(%0)\n\t" \ + "xorl %%eax,%%eax\n\t" \ + "cpuid\n\t" \ + : /* no output */ \ + : "S"(&time) \ + : "eax", "ebx", "ecx", "edx", "memory") + +#define timp_rdtsc_after(time) \ + __asm__ __volatile__( \ + "xorl %%eax,%%eax\n\t" \ + "cpuid\n\t" \ + "rdtsc\n\t" \ + "movl %%eax,(%0)\n\t" \ + "movl %%edx,4(%0)\n\t" \ + "xorl %%eax,%%eax\n\t" \ + "cpuid\n\t" \ + : /* no output */ \ + : "S"(&time) \ + : "eax", "ebx", "ecx", "edx", "memory") + +#elif defined (__ia64) + +#define timp_rdtsc() \ +({ unsigned long long int x; \ + __asm__ __volatile__("mov %0=ar.itc" : "=r"(x) :: "memory"); \ + x; }) +#define timp_rdtsc_before(time) (time = timp_rdtsc()) +#define timp_rdtsc_after(time) (time = timp_rdtsc()) + +#elif defined (__alpha) + +#define timp_rdtsc() \ +({ unsigned long long int x; \ + __asm__ volatile ("rpcc %0\n\t" : "=r" (x)); \ + x; }) +#define timp_rdtsc_before(time) (time = tpp_rdtsc()) +#define timp_rdtsc_after(time) (time = tpp_rdtsc()) + +#else +# error Unsupported CPU +#endif + +/* We do several measures and keep the minimum to avoid counting + * hardware interruption cycles. + * The filling of the CPU cache is done because we do several loops, + * and get the minimum. + * Declaring num_cycle as "volatile" is to avoid optimisation when it is + * possible (To properly calcul overhead). + * overhead is calculated outside by a call to: + * overhead = MEASURE("overhead", ;) + * Use a lot the preprocessor. + * It is a macro to be very flexible. + */ +static unsigned long long int timp_overhead = 0; + +#define TIMP_NUM_TRY 4327 +#define TIMP_MAX_WAIT_FOR_MEASURE 10000000ULL + +#define TIMP_MEASURE(CODE) \ + ({ \ + volatile unsigned long long int num_cycle, num_cycle2; \ + unsigned long long min_num_cycle, start_num_cycle; \ + int _i; \ + timp_rdtsc_before (start_num_cycle); \ + min_num_cycle = 0xFFFFFFFFFFFFFFFFLL; \ + for(_i = 0 ; _i < TIMP_NUM_TRY ; _i++) { \ + timp_rdtsc_before(num_cycle); \ + CODE; \ + timp_rdtsc_after(num_cycle2); \ + num_cycle = num_cycle2 - num_cycle; \ + if (num_cycle < min_num_cycle) \ + min_num_cycle = num_cycle; \ + if (num_cycle2 - start_num_cycle > TIMP_MAX_WAIT_FOR_MEASURE) \ + break; \ + } \ + min_num_cycle - timp_overhead; }) + +#define TIMP_OVERHEAD() \ + (timp_overhead = 0, timp_overhead = TIMP_MEASURE((void) 0) ) + +#endif /* __TIMP__H__ */ diff --git a/tools/mpfrlint b/tools/mpfrlint new file mode 100755 index 000000000..5401ef702 --- /dev/null +++ b/tools/mpfrlint @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +# Check possible problems in the MPFR source. + +# mpfrlint can be run from the tools directory +dir=`pwd` +[ -d src ] || [ "`basename "$dir"`" != tools ] || cd .. + +grep '^# *include *<math\.h>' src/*.c + +grep -E 'mpfr_(underflow|overflow|nanflag|inexflag|erangeflag)_p' src/*.{c,h} | \ + grep -v '^src/exceptions.c:' | \ + grep -v '^src/mpfr-impl.h:#define mpfr_.*_p()' | \ + grep -v '^src/mpfr.h:__MPFR_DECLSPEC ' + +grep -E 'if +(test|\[).* == ' acinclude.m4 configure.ac +grep -E '="`' acinclude.m4 configure.ac + +grep GMP_LIMB_BITS {src,tests}/*.{c,h} + +grep GMP_RND {src,tests}/*.{c,h} | grep -v '#define GMP_RND' + +for i in exp prec rnd +do + grep mp_${i}_t {src,tests}/*.{c,h} | \ + grep -v "\(# *define\|# *ifndef\|typedef\) *mp_${i}_t" | \ + grep -v "\[mp_${i}_t\]" +done + +sp="[[:space:]]*" +grep "MPFR_LOG_MSG$sp($sp($sp\".*\"$sp)$sp)$sp;" {src,tests}/*.{c,h} + +for file in {src,tests}/*.{c,h} */Makefile.am acinclude.m4 configure.ac +do + # Note: this is one less that the POSIX minimum limit in case + # implementations are buggy like POSIX examples. :) + perl -ne "/.{2047,}/ and print \ + \"Line \$. of file '$file' has more than 2046 bytes.\n\"" "$file" +done + +# In general, one needs to include mpfr-impl.h (note that some platforms +# such as MS Windows use a config.h, which is included by mpfr-impl.h). +for file in src/*.c +do + [ "$file" = src/jyn_asympt.c ] || \ + [ "$file" = src/round_raw_generic.c ] || \ + grep -q '^# *include *"\(mpfr-impl\|fits.*\|gen_inverse\)\.h"' $file || \ + echo "Missing '#include \"mpfr-impl.h\"' in $file?" +done + +fdlv1="`sed -n '/Version / {s/.*Version //; s/,.*//; p; q}' doc/fdl.texi`" +fdlv2="`sed -n '/GNU Free Documentation License/ \ + {s/.*Version //; s/ or.*//; p; q}' doc/mpfr.texi`" +[ "x$fdlv1" = "x$fdlv2" ] || cat <<EOF +GFDL versions differ: + fdl.texi: $fdlv1 + mpfr.texi: $fdlv2 +EOF + +# Note: if paragraphs are reformatted, this may need to be updated. +lgpl="`sed -n '/version [0-9.]\+ or any later version/ \ + {s/.*version //; s/ or.*//; p; q}' doc/mpfr.texi`" +for file in {src,tests}/*.{c,h} +do + [ "$file" = "src/get_patches.c" ] && file="tools/get_patches.sh" + if grep -q "GNU MPFR Library" "$file"; then + grep -q "either version $lgpl of the License" "$file" || \ + echo "Possibly missing or incorrect copyright notice in $file" + fi +done + +texisvnd=`LC_ALL=C TZ=UTC svn info doc/mpfr.texi 2> /dev/null | sed -n 's/Last Changed Date:.*, [0-9]* \([A-Z][a-z][a-z] [0-9][0-9][0-9][0-9]\)).*/\1/p'` +if [ $? -eq 0 ] && [ -n "$texisvnd" ]; then + texidate=`sed -n 's/@set UPDATED-MONTH \([A-Z][a-z][a-z]\).*\( [0-9][0-9][0-9][0-9]\)/\1\2/p' doc/mpfr.texi` + [ "$texidate" = "$texisvnd" ] || cat <<EOF +mpfr.texi's UPDATED-MONTH seems to be incorrect: + mpfr.texi's UPDATED-MONTH: $texidate + Last Changed Date in WC: $texisvnd +EOF +fi + +acv1="`sed -n 's/.*autoconf \([0-9.]\+\) (at least).*/\1/p' doc/README.dev`" +acv2="`sed -n 's/AC_PREREQ(\([0-9.]\+\).*/\1/p' acinclude.m4`" +[ "x$acv1" = "x$acv2" ] || cat <<EOF +autoconf minimal versions differ: + README.dev: $acv1 + acinclude.m4: $acv2 +EOF + +cd "$dir" +"`dirname -- "$0"`"/check_inits_clears + +true diff --git a/tools/nightly-test b/tools/nightly-test new file mode 100755 index 000000000..3c5a620b5 --- /dev/null +++ b/tools/nightly-test @@ -0,0 +1,30 @@ +#!/bin/sh +# Usage: nightly-test <GMPDIR> <CC> <BRANCH> +set -e +GMP="$1" +CC="$2" +BRANCH="$3" +DIR=mpfr-nightly +echo "BRANCH=$BRANCH" +echo "GMP=$GMP" +echo "CC=$CC" +cd /tmp +/bin/rm -fr "$DIR" +mkdir "$DIR" +# The following test should be useless, but let's be paranoid. +test ! -h "$DIR" +svn checkout "svn://scm.gforge.inria.fr/svn/mpfr/${BRANCH:-trunk}" "$DIR" +cd "$DIR" +autoreconf -i +./configure --with-gmp="$GMP" --enable-assert=full \ +--disable-shared --enable-thread-safe --enable-tests-timeout=60 \ +CC="$CC" CFLAGS="-Wall -Wmissing-prototypes -O2 -g -fstack-protector \ +-D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -ansi -pedantic-errors" +make +export GMP_CHECK_RANDOMIZE=1 +export MPFR_CHECK_MAX=1 +export MPFR_SUSPICIOUS_OVERFLOW=1 +export MPFR_CHECK_LIBC_PRINTF=1 +make check +cd /tmp +/bin/rm -fr "$DIR" diff --git a/tools/update-patchv b/tools/update-patchv new file mode 100755 index 000000000..ea04c3109 --- /dev/null +++ b/tools/update-patchv @@ -0,0 +1,46 @@ +#!/bin/sh + +# Run this script from the top or tools directory to update some files +# before a patch is built. + +set -e + +LC_ALL=C +export LC_ALL + +if [ $# -ne 1 ]; then + echo >&2 "Usage: $0 <patchnumber>" + exit 1 +fi + +dir=`pwd` +[ -d src ] || [ "`basename "$dir"`" != tools ] || cd .. + +replace() +{ + if [ ! -h "$2" ] && [ -r "$2" ] && [ -w "$2" ]; then + err=`perl -pi -e "$1" "$2" 2>&1 >/dev/null` + if [ -n "$err" ]; then + printf >&2 "Error from perl:\n%s\n" "$err" + exit 2 + fi + else + printf >&2 "Error: %s is not a readable/writable file\n" "$2" + exit 2 + fi +} + +vers="`perl -pe 's/^(\d+\.\d+\.\d+).*/\1/' VERSION`" +if [ -z "$vers" ]; then + echo >&2 "Error: could not get the current MPFR version" + exit 2 +fi + +full="${vers}-p$1" +echo $full > VERSION + +replace "s/(?<=#define MPFR_VERSION_STRING ).*/\"$full\"/" src/mpfr.h +replace "s/(?<=return \").*\"/$full\"/" src/version.c +replace "s/(?<=#if ).*/0/" tests/tversion.c + +echo "MPFR version successfully updated." diff --git a/tools/update-version b/tools/update-version new file mode 100755 index 000000000..1c4e0f4a2 --- /dev/null +++ b/tools/update-version @@ -0,0 +1,59 @@ +#!/bin/sh + +# Run this script from the top or tools directory to update the MPFR version. + +set -e + +LC_ALL=C +export LC_ALL + +if [ $# -lt 3 ] || [ $# -gt 5 ]; then + echo >&2 "Usage: $0 <major> <minor> <patchlevel> [ <suffix> [ - ] ]" + echo >&2 "(use 5 arguments to produce patches for releases)" + exit 1 +fi + +# Examples: +# ./update-version 2 3 0 dev +# ./update-version 2 3 0 rc1 +# ./update-version 2 3 0 +# ./update-version 2 3 0 p1 - + +dir=`pwd` +[ -d src ] || [ "`basename "$dir"`" != tools ] || cd .. + +replace() +{ + if [ ! -h "$2" ] && [ -r "$2" ] && [ -w "$2" ]; then + err=`perl -pi -e "$1" "$2" 2>&1 >/dev/null` + if [ -n "$err" ]; then + printf >&2 "Error from perl:\n%s\n" "$err" + exit 2 + fi + else + printf >&2 "Error: %s is not a readable/writable file\n" "$2" + exit 2 + fi +} + +vers="$1.$2.$3" +full="$vers${4:+-$4}" +replace "s/(?<=#define MPFR_VERSION_MAJOR ).*/$1/; \ + s/(?<=#define MPFR_VERSION_MINOR ).*/$2/; \ + s/(?<=#define MPFR_VERSION_PATCHLEVEL ).*/$3/; \ + s/(?<=#define MPFR_VERSION_STRING ).*/\"$full\"/" src/mpfr.h +replace "s/(?<=return \").*\"/$full\"/" src/version.c +echo $full > VERSION + +if [ $# -lt 5 ]; then + # Up to 4 arguments... + u="http://www.mpfr.org/mpfr-" + replace "s/(?<=\@set VERSION ).*/$full/" doc/mpfr.texi + replace "s,MPFR [\d.]+( web page \@url{$u)[\d.]+/,MPFR $vers\${1}$vers/," \ + doc/mpfr.texi + replace "s/(?<=AC_INIT).*/([MPFR],[$full])/" configure.ac + replace "s,(?<=$u).*?/,$vers/," INSTALL +fi + +echo "MPFR version successfully updated." +echo "Don't forget to update MPFR libtool version in Makefile.am." |