Ticket #12433: zn_poly-0.9.p6-p7.diff

File zn_poly-0.9.p6-p7.diff, 58.4 KB (added by leif, 10 years ago)

Diff between Andrew's and my new spkg. For reference / review only.

  • .hgignore

    diff --git a/.hgignore b/.hgignore
    a b  
    11src
    2 patches
  • new file .hgtags

    diff --git a/.hgtags b/.hgtags
    new file mode 100644
    - +  
     140715bfe3e31624feb49ab44e843d827c455c3c4 zn_poly-0.9.p6
     2fc80a3f545307b03c99bd426949ffd8d7e1a77b6 zn_poly-0.9.p7
  • SPKG.txt

    diff --git a/SPKG.txt b/SPKG.txt
    a b  
    22
    33== Description ==
    44
    5 zn_poly is a C library for polynomial arithmetic in Z/nZ[x], where n is any modulus that fits into an unsigned long.
     5zn_poly is a C library for polynomial arithmetic in Z/nZ[x], where n is any
     6modulus that fits into an unsigned long.
    67
    78Website: http://cims.nyu.edu/~harvey/zn_poly/
    89
    910== License ==
    1011
    11 GPL V2 or V3. Some of the code has been copied from other projects - see src/COPYING for details.
     12GPL V2 or V3.  Some of the code has been copied from other projects - see
     13the file src/COPYING for details.
    1214
    1315== SPKG Maintainers ==
    1416
     
    2022
    2123== Dependencies ==
    2224
    23  * MPIR
     25 * GMP/MPIR
     26 * (some) Python (to create the Makefile)
     27 * GNU patch
     28 * NTL apparently only if we configured zn_poly differently (same for FLINT)
    2429
    2530== Special Update/Build Instructions ==
    26  * Although this is configured with --ntl-prefix=$SAGE_LOCAL,
     31 * Make sure the patches still apply.
     32   Especially changes in `makemakefile.py` may also require changes to
     33   `spkg-install` (and perhaps also `spkg-check`).
     34 * Don't forget to change the (shared library) version number(s) in
     35   `spkg-install` in case it changed; the current one is `0.9`.
     36   (TODO: Just take the version from upstream automatically instead of
     37    hardcoding it; it's [currently] in `src/VERSION`.)
     38 * Although this is configured with `--ntl-prefix="$SAGE_LOCAL"`,
    2739   apparently NTL is only used if specific targets are created, so this
    28    can probably be removed.
     40   can probably be removed. (Did so. -leif 04/2012)
     41 * There's also a `--use-flint` option to `configure`; no idea what it does,
     42   and we currently don't use it either.
     43 * TODO:
     44   - Use `make install` instead of manually "installing" (copying and sym-
     45     linking) the [shared] libraries and header files.  This requires further
     46     tweaking of `makemakefile.py`, since it currently only installs a static
     47     library and the headers.
     48   - If everything's fine, i.e., no problems arise, some comments and especial-
     49     ly some code I currently just commented out can certainly be removed.   
     50     (-leif, 04/2012)
    2951
    3052== Changelog ==
    3153
     54=== zn_poly-0.9.p7 (Leif Leonhardy, April 8th, 2012) ===
     55 * #12433: Reviewer changes.
     56 * Restore upstream sources. (One file in `src/tune/` was already patched.)
     57 * Remove the obsolete Debian `dist/` directory.
     58 * Use `patch` to apply the patches.
     59 * Remove `patches/` from `.hgignore`! (And remove the prepatched files.)
     60 * Add Python to the dependencies, since (some) Python is needed to create
     61   the Makefile during build / `configure`.  (`spkg/standard/deps` already
     62   reflects this.)
     63 * Rework (upstream's) `makemakefile.py` to create a proper Makefile,
     64   respecting `CC`, `CXX`, `CFLAGS`, `CXXFLAGS`, `CPPFLAGS` etc. with their
     65   *usual* meaning (i.e., not using `CPP` to compile C++!), and using `LDFLAGS`
     66   consistently, also not hardcoding e.g. `-m64` (which was added by Sage).
     67 * Do not add `-O3` to `CFLAGS` (in `spkg-install`) without the possibility to
     68   get overridden by user-provided `CFLAGS`.  Also honor `SAGE_DEBUG=yes` by
     69   completely disabling optimization in that case.
     70 * Fix typo in `spkg-check`, which certainly would break building the test
     71   program when `SAGE64=yes`.  (Although it is actually already built from
     72   within `spkg-install`.)
     73 * Clean up `spkg-install` and `spkg-check`; redirect error messages to
     74   `stderr`, add more error checks, use `$MAKE` in `spkg-check` as well,
     75   quote more environment variables, use `cp [-f]` instead of `$CP`, don't
     76   create an absolute symbolic link on Cygwin.
     77
    3278=== zn_poly-0.9.p6 (R. Andrew Ohana, February 4th, 2012) ===
    33  * make spkg respect global CC flag
     79 * #12433: Make spkg respect global CC flag
    3480
    3581=== zn_poly-0.9.p5 (David Kirkby, July 14th, 2010) ===
    3682 * #9358 Ensure that spkg-install can handle the case
  • deleted file dist/debian/changelog

    diff --git a/dist/debian/changelog b/dist/debian/changelog
    deleted file mode 100644
    + -  
    1 libzn-poly (0.8-1) unstable; urgency=low
    2 
    3   * Initial release.
    4 
    5  -- Tim Abbott <tabbott@mit.edu>  Wed, 14 Nov 2007 20:22:53 -0500
  • deleted file dist/debian/compat

    diff --git a/dist/debian/compat b/dist/debian/compat
    deleted file mode 100644
    + -  
    1 5
  • deleted file dist/debian/control

    diff --git a/dist/debian/control b/dist/debian/control
    deleted file mode 100644
    + -  
    1 Source: libzn-poly
    2 Section: math
    3 Priority: extra
    4 Maintainer: Tim Abbott <tabbott@mit.edu>
    5 Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 5), quilt, patchutils (>= 0.2.25), cdbs (>= 0.4.27-1), libgmp3-dev, libntl-dev, python
    6 Standards-Version: 3.7.2
    7 
    8 Package: libzn-poly0
    9 Section: libs
    10 Architecture: any
    11 Depends: ${shlibs:Depends}, ${misc:Depends}
    12 Description: A library for polynomial arithmetic in Z/nZ[x]
    13  Homepage: http://math.harvard.edu/~dmharvey/zn_poly/
    14 
    15 Package: libzn-poly-dev
    16 Section: libdevel
    17 Architecture: any
    18 Depends: ${shlibs:Depends}, ${misc:Depends}, libzn-poly0
    19 Description: A library for polynomial arithmetic in Z/nZ[x]
    20  Homepage: http://math.harvard.edu/~dmharvey/zn_poly/
  • deleted file dist/debian/control.in

    diff --git a/dist/debian/control.in b/dist/debian/control.in
    deleted file mode 100644
    + -  
    1 Source: libzn-poly
    2 Section: math
    3 Priority: extra
    4 Maintainer: Tim Abbott <tabbott@mit.edu>
    5 Build-Depends: @cdbs@, libgmp3-dev, libntl-dev, python
    6 Standards-Version: 3.7.2
    7 
    8 Package: libzn-poly0
    9 Section: libs
    10 Architecture: any
    11 Depends: ${shlibs:Depends}, ${misc:Depends}
    12 Description: A library for polynomial arithmetic in Z/nZ[x]
    13  Homepage: http://math.harvard.edu/~dmharvey/zn_poly/
    14 
    15 Package: libzn-poly-dev
    16 Section: libdevel
    17 Architecture: any
    18 Depends: ${shlibs:Depends}, ${misc:Depends}, libzn-poly0
    19 Description: A library for polynomial arithmetic in Z/nZ[x]
    20  Homepage: http://math.harvard.edu/~dmharvey/zn_poly/
  • deleted file dist/debian/copyright

    diff --git a/dist/debian/copyright b/dist/debian/copyright
    deleted file mode 100644
    + -  
    1 This package was debianized by Tim Abbott <tabbott@mit.edu> in 2008.
    2 
    3 It was downloaded from http://math.harvard.edu/~dmharvey/zn_poly/
    4 
    5 Upstream Author: David Harvey <dmharvey@math.harvard.edu>
    6 
    7 Copyright (C) 2007, 2008, David Harvey
    8 
    9 License:
    10 
    11    This package is free software; you can redistribute it and/or
    12    modify it under the terms of the GNU General Public License as
    13    published by the Free Software Foundation; either version 2 or
    14    version 3 of the License.
    15 
    16    This package is distributed in the hope that it will be useful,
    17    but WITHOUT ANY WARRANTY; without even the implied warranty of
    18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19    GNU General Public License for more details.
    20 
    21    You should have received a copy of the GNU General Public License
    22    along with this package; if not, write to the Free Software
    23    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
    24 
    25 On Debian systems, the complete text of the GNU General
    26 Public License can be found in `/usr/share/common-licenses/GPL'.
    27 
    28 The Debian packaging is (C) 2008, Tim Abbott <tabbott@mit.edu> and is
    29 licensed under the GPL, see above.
    30 
    31 Licensing notes:
    32 
    33 zn_poly incorporates small amounts of code from other projects:
    34 
    35    (2a)
    36    The file "wide_arith.h" includes some assembly macros from the file
    37    "longlong.h" in GMP 4.2.1; see http://gmplib.org/. The copyright to this
    38    code is held by the Free Software Foundation, and it was released under
    39    "LGPL v2.1 or later".
    40 
    41    (2b)
    42    The file "wide_arith.h" also includes assembly macros from the file
    43    "SPMM_ASM.h" in NTL 5.4.1; see http://www.shoup.net/ntl/. The copyright
    44    to this code is held by Victor Shoup, and it was released under "GPL v2 or
    45    later".
    46 
    47    (2c)
    48    The filer "profiler.h" contains x86 cycle counting code from the file
    49    "profiler.h" in FLINT 1.0; see http://www.flintlib.org/. The copyright
    50    to this code is held by William Hart, and it was released under "GPL v2 or
    51    later".
  • deleted file dist/debian/libzn-poly-dev.install

    diff --git a/dist/debian/libzn-poly-dev.install b/dist/debian/libzn-poly-dev.install
    deleted file mode 100644
    + -  
    1 debian/tmp/usr/include usr/
    2 debian/tmp/usr/lib/*.a usr/lib/
  • deleted file dist/debian/libzn-poly0.install

    diff --git a/dist/debian/libzn-poly0.install b/dist/debian/libzn-poly0.install
    deleted file mode 100644
    + -  
    1 libzn_poly.so usr/lib
  • deleted file dist/debian/rules

    diff --git a/dist/debian/rules b/dist/debian/rules
    deleted file mode 100644
    + -  
    1 #!/usr/bin/make -f
    2 
    3 include /usr/share/cdbs/1/rules/debhelper.mk
    4 include /usr/share/cdbs/1/class/autotools.mk
    5 include /usr/share/cdbs/1/rules/patchsys-quilt.mk
    6 
    7 DEB_CONFIGURE_NORMAL_ARGS = --gmp-prefix="/usr" --ntl-prefix="/usr" \
    8             --prefix="$(DEB_DESTDIR)/usr" --cflags="-fPIC $(CFLAGS)"
    9 
    10 common-build-arch::
    11         +$(DEB_MAKE_INVOKE) libzn_poly.so
  • deleted file patches/makemakefile.py

    diff --git a/patches/makemakefile.py b/patches/makemakefile.py
    deleted file mode 100644
    + -  
    1 #
    2 # This python script is called by configure to generate the makefile
    3 # for zn_poly.
    4 #
    5 
    6 # --------------------------------------------------------------------------
    7 # various lists of modules
    8 
    9 
    10 # These are the modules that go into the actual zn_poly library. They get
    11 # compiled in both optimised and debug modes.
    12 lib_modules = ["array", "invert", "ks_support", "mulmid", "mulmid_ks", "misc",
    13                "mpn_mulmid", "mul", "mul_fft", "mul_fft_dft", "mul_ks",
    14                "nuss", "pack", "pmf", "pmfvec_fft", "tuning", "zn_mod"]
    15 lib_modules = ["src/" + x for x in lib_modules]
    16 
    17 # These are modules containing various test routines. They get compiled
    18 # in debug mode only.
    19 test_modules = ["test", "ref_mul", "invert-test", "pmfvec_fft-test",
    20                 "mulmid_ks-test", "mpn_mulmid-test", "mul_fft-test",
    21                 "mul_ks-test", "nuss-test", "pack-test"]
    22 test_modules = ["test/" + x for x in test_modules]
    23 
    24 # These are modules containing various profiling routines. They get compiled
    25 # in optimised mode only.
    26 prof_modules = ["prof_main", "profiler", "array-profile", "invert-profile",
    27                 "mulmid-profile", "mpn_mulmid-profile", "mul-profile",
    28                 "negamul-profile"]
    29 prof_modules = ["profile/" + x for x in prof_modules]
    30 
    31 # These are modules containing profiling routines for NTL. They get compiled
    32 # in optimised mode only, with the C++ compiler.
    33 cpp_prof_modules = ["profile/ntl-profile"]
    34 
    35 # These are modules containing dummy routines replacing the NTL ones, if
    36 # we're not compiling with NTL support.
    37 noncpp_prof_modules = ["profile/ntl-profile-dummy"]
    38 
    39 # These are modules shared by the test and profiling code. They get compiled
    40 # in both debug and optimised mode.
    41 testprof_modules = ["test/support"]
    42 
    43 # Profiling targets. Each X has a main file "X-main.c" which is linked
    44 # against prof_main.c. They are compiled once with PROFILE_NTL defined
    45 # and once without.
    46 prof_progs = ["array-profile", "invert-profile", "mulmid-profile",
    47               "mpn_mulmid-profile", "mul-profile", "negamul-profile"]
    48 prof_progs = ["profile/" + x for x in prof_progs]
    49 
    50 # These are modules used in the tuning program; they get compiled only in
    51 # optimised mode.
    52 tune_modules = ["tune", "mulmid-tune", "mpn_mulmid-tune", "mul-tune",
    53                 "mul_ks-tune", "mulmid_ks-tune", "nuss-tune"]
    54 tune_modules = ["tune/" + x for x in tune_modules]
    55 
    56 # Demo programs.
    57 demo_progs = ["demo/bernoulli/bernoulli"]
    58 
    59 # These are the headers that need to be copied to the install location.
    60 install_headers = ["include/zn_poly.h", "include/wide_arith.h"]
    61 
    62 # These are the other headers.
    63 other_headers = ["include/support.h", "include/profiler.h",
    64                  "include/zn_poly_internal.h"]
    65 
    66 
    67 # --------------------------------------------------------------------------
    68 # read command line options
    69 
    70 from optparse import OptionParser
    71 
    72 parser = OptionParser()
    73 parser.add_option("--prefix", dest="prefix", default="/usr/local")
    74 parser.add_option("--cflags", dest="cflags", default="-O2")
    75 parser.add_option("--ldflags", dest="ldflags", default="")
    76 parser.add_option("--gmp-prefix", dest="gmp_prefix", default="/usr/local")
    77 parser.add_option("--ntl-prefix", dest="ntl_prefix", default="/usr/local")
    78 parser.add_option("--use-flint", dest="use_flint", action="store_true",
    79                   default=False)
    80 parser.add_option("--flint-prefix", dest="flint_prefix", default="/usr/local")
    81 
    82 options, args = parser.parse_args()
    83 
    84 
    85 gmp_include_dir = options.gmp_prefix + "/include"
    86 gmp_lib_dir = options.gmp_prefix + "/lib"
    87 
    88 ntl_include_dir = options.ntl_prefix + "/include"
    89 ntl_lib_dir = options.ntl_prefix + "/lib"
    90 
    91 if options.use_flint:
    92    flint_include_dir = options.flint_prefix + "/include"
    93    flint_lib_dir = options.flint_prefix + "/lib"
    94 
    95 cflags = options.cflags
    96 ldflags = options.ldflags
    97 prefix = options.prefix
    98 
    99 includes = "-I" + gmp_include_dir + " -I./include"
    100 libs = "-L" + gmp_lib_dir + " -lgmp -lm"
    101 
    102 if options.use_flint:
    103    includes = includes + " -I" + flint_include_dir
    104    libs = libs + " -L" + flint_lib_dir + " -lflint"
    105    cflags = cflags + " -std=c99 -DZNP_USE_FLINT"
    106 
    107 cpp_includes = includes + " -I" + ntl_include_dir
    108 cpp_libs = libs + " -L" + ntl_lib_dir + " -lntl"
    109 
    110 
    111 # --------------------------------------------------------------------------
    112 # generate the makefile
    113 
    114 import time
    115 
    116 print "#"
    117 print "# Do not edit directly -- this file was auto-generated"
    118 print "# by makemakefile.py on " + time.strftime("%a, %d %b %Y %H:%M:%S +0000",
    119                                                  time.gmtime())
    120 print "#"
    121 print
    122 
    123 print
    124 print "CC = gcc"
    125 print "CFLAGS = " + cflags
    126 print "LDFLAGS = " + ldflags
    127 print "INCLUDES = " + includes
    128 print "LIBS = " + libs
    129 
    130 print
    131 print "CPP = g++"
    132 print "CPPFLAGS = " + cflags
    133 print "CPP_INCLUDES = " + cpp_includes
    134 print "CPP_LIBS = " + cpp_libs
    135 
    136 print
    137 print "HEADERS = " + " ".join(install_headers + other_headers)
    138 print "LIBOBJS = " + " ".join([x + ".o" for x in lib_modules])
    139 print "TESTOBJS = " + " ".join([x + "-DEBUG.o" for x in \
    140    lib_modules + test_modules + testprof_modules])
    141 print "PROFOBJS = " + " ".join([x + ".o" for x in \
    142    lib_modules + prof_modules + noncpp_prof_modules + testprof_modules])
    143 print "CPP_PROFOBJS = " + " ".join([x + ".o" for x in \
    144    lib_modules + prof_modules + cpp_prof_modules + testprof_modules])
    145 print "TUNEOBJS = " + " ".join([x + ".o" for x in \
    146    lib_modules + tune_modules + testprof_modules + prof_modules + \
    147    noncpp_prof_modules if x != "profile/prof_main"])
    148 
    149 print "all: libzn_poly.a"
    150 print
    151 print "test: test/test"
    152 print "tune: tune/tune"
    153 print
    154 print "check: test"
    155 print "\ttest/test -quick all"
    156 print
    157 print "install:"
    158 print "\tmkdir -p %s/include/zn_poly" % prefix
    159 print "\tmkdir -p %s/lib" % prefix
    160 print "\tcp libzn_poly.a %s/lib" % prefix
    161 print "\tcp include/zn_poly.h %s/include/zn_poly" % prefix
    162 print "\tcp include/wide_arith.h %s/include/zn_poly" % prefix
    163 print
    164 print "clean:"
    165 print "\trm -f *.o"
    166 print "\trm -f test/*.o"
    167 print "\trm -f profile/*.o"
    168 print "\trm -f tune/*.o"
    169 print "\trm -f src/*.o"
    170 print "\trm -f demo/bernoulli/*.o"
    171 print "\trm -f libzn_poly.a"
    172 print "\trm -f libzn_poly.dylib"
    173 print "\trm -f libzn_poly*.so*"
    174 print "\trm -f test/test"
    175 print "\trm -f tune/tune"
    176 for x in prof_progs:
    177    print "\trm -f " + x
    178    print "\trm -f " + x + "-ntl"
    179 for x in demo_progs:
    180    print "\trm -f " + x
    181 
    182 
    183 print
    184 print
    185 print "##### library targets"
    186 print
    187 print "libzn_poly.a: $(LIBOBJS)"
    188 print "\tar -r libzn_poly.a $(LIBOBJS)"
    189 print "\tranlib libzn_poly.a"
    190 print
    191 print "libzn_poly.dylib: $(LIBOBJS)"
    192 print "\t$(CC) -single_module -fPIC -dynamiclib -o libzn_poly.dylib " \
    193       "$(LIBOBJS) $(LIBS)"
    194 print
    195 print "libzn_poly.dylib64: $(LIBOBJS)"
    196 print "\t$(CC) -m64 -single_module -fPIC -dynamiclib -o libzn_poly.dylib $(LIBOBJS) $(LIBS)"
    197 print
    198 print "libzn_poly.so: $(LIBOBJS)"
    199 print "\t$(CC) -shared $(LDFLAGS) -Wl,-soname,libzn_poly-`cat VERSION`.so " \
    200       "-o libzn_poly-`cat VERSION`.so $(LIBOBJS) $(LIBS)"
    201 print "\t ln -sf libzn_poly-`cat VERSION`.so libzn_poly.so"
    202 
    203 print
    204 print
    205 print "##### test program"
    206 print
    207 print "test/test: $(TESTOBJS) $(HEADERS)"
    208 print "\t$(CC) -g $(LDFLAGS) -o test/test $(TESTOBJS) $(LIBS)"
    209 
    210 print
    211 print
    212 print "##### profiling programs"
    213 print
    214 for x in prof_progs:
    215    print "%s-main.o: %s-main.c $(HEADERS)" % (x, x)
    216    print "\t$(CC) $(CFLAGS) $(INCLUDES) -DNDEBUG -o %s-main.o -c %s-main.c" \
    217          % (x, x)
    218    print
    219    print "%s: %s-main.o $(PROFOBJS)" % (x, x)
    220    print "\t$(CC) $(CFLAGS) $(LDFLAGS) -o %s %s-main.o $(PROFOBJS) $(LIBS)" \
    221          % (x, x)
    222    print
    223    print "%s-main-ntl.o: %s-main.c $(HEADERS)" % (x, x)
    224    print "\t$(CC) $(CFLAGS) $(INCLUDES) -DPROFILE_NTL -DNDEBUG " \
    225          "-o %s-main-ntl.o -c %s-main.c" % (x, x)
    226    print
    227    print "%s-ntl: %s-main-ntl.o $(CPP_PROFOBJS)" % (x, x)
    228    print "\t$(CPP) $(CPPFLAGS) $(LDFLAGS) -o %s-ntl %s-main-ntl.o " \
    229          "$(CPP_PROFOBJS) $(CPP_LIBS)" % (x, x)
    230    print
    231 
    232 print
    233 print
    234 print "##### tuning utility"
    235 print
    236 print "tune/tune: $(TUNEOBJS)"
    237 print "\t$(CC) $(CFLAGS) $(LDFLAGS) -o tune/tune $(TUNEOBJS) $(LIBS)"
    238 
    239 
    240 print
    241 print
    242 print "##### demo programs"
    243 for x in demo_progs:
    244    print
    245    print "%s: %s.o $(LIBOBJS)" % (x, x)
    246    print "\t$(CC) $(CFLAGS) $(LDFLAGS) -o %s %s.o $(LIBOBJS) $(LIBS)" % (x, x)
    247 
    248 
    249 print
    250 print
    251 print "##### object files (with debug code)"
    252 for x in lib_modules + test_modules + testprof_modules + demo_progs:
    253    print
    254    print "%s-DEBUG.o: %s.c $(HEADERS)" % (x, x)
    255    print "\t$(CC) -g $(CFLAGS) $(INCLUDES) -DDEBUG -o %s-DEBUG.o -c %s.c" \
    256          % (x, x)
    257 
    258 print
    259 print
    260 print "##### object files (no debug code)"
    261 for x in lib_modules + prof_modules + testprof_modules + \
    262                        tune_modules + demo_progs:
    263    print
    264    print "%s.o: %s.c $(HEADERS)" % (x, x)
    265    print "\t$(CC) $(CFLAGS) $(INCLUDES) -DNDEBUG -o %s.o -c %s.c" % (x, x)
    266 
    267 print
    268 print
    269 print "##### object files (C++, no debug code)"
    270 for x in cpp_prof_modules:
    271    print
    272    print "%s.o: %s.c $(HEADERS)" % (x, x)
    273    print "\t$(CPP) $(CPPFLAGS) $(CPP_INCLUDES) -DNDEBUG -o %s.o -c %s.c" \
    274          % (x, x)
    275 
    276 
    277 ### end of file
  • patches/makemakefile.py.patch

    diff --git a/patches/makemakefile.py.patch b/patches/makemakefile.py.patch
    a b  
    1 --- ../src/makemakefile.py      2008-09-22 17:35:05.000000000 +0200
    2 +++ makemakefile.py     2010-02-21 17:59:07.440760614 +0100
    3 @@ -192,8 +192,11 @@
    4  print "\t$(CC) -single_module -fPIC -dynamiclib -o libzn_poly.dylib " \
     1--- src/makemakefile.py 2008-09-22 17:35:05.000000000 +0200
     2+++ patches/makemakefile.py     2012-04-08 13:21:09.850926192 +0200
     3@@ -2,6 +2,22 @@
     4 # This python script is called by configure to generate the makefile
     5 # for zn_poly.
     6 #
     7+# Patched for Sage's 'spkg-install' to
     8+# - respect the environment settings of CC, CPP, CXX, AR and RANLIB, and use
     9+#   these as well as CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS with their usual
     10+#   meaning (i.e., CXX and not CPP for the C++ compiler, likewise CXXFLAGS
     11+#   instead of CPPFLAGS, CPPFLAGS for C preprocessor flags, and LDFLAGS in
     12+#   every link command using the compiler driver);
     13+# - support passing CPPFLAGS and CXXFLAGS (via '--cppflags=...' and
     14+#   '--cxxflags=...');
     15+# - build a 64-bit shared library (.dylib) on Darwin / MacOS X by adding the
     16+#   target 'libzn_poly.dylib64'.  (This is meanwhile superfluous, since
     17+#   LDFLAGS are used in the receipt for libzn_poly.dylib as well.)
     18+# - support a variable SONAME_FLAG (defaulting to '-soname', otherwise taken
     19+#   from the environment (e.g. '-h' for the Sun linker);
     20+# - support a variable SHARED_FLAG (defaulting to '-shared'), which could
     21+#   later be used to unify the .so and .dylib targets.  (An SO_EXTENSION
     22+#   variable isn't supported / used yet.)
     23 
     24 # --------------------------------------------------------------------------
     25 # various lists of modules
     26@@ -72,6 +88,8 @@
     27 parser = OptionParser()
     28 parser.add_option("--prefix", dest="prefix", default="/usr/local")
     29 parser.add_option("--cflags", dest="cflags", default="-O2")
     30+parser.add_option("--cppflags", dest="cppflags", default="")
     31+parser.add_option("--cxxflags", dest="cxxflags", default="-O2")
     32 parser.add_option("--ldflags", dest="ldflags", default="")
     33 parser.add_option("--gmp-prefix", dest="gmp_prefix", default="/usr/local")
     34 parser.add_option("--ntl-prefix", dest="ntl_prefix", default="/usr/local")
     35@@ -93,10 +111,14 @@
     36    flint_lib_dir = options.flint_prefix + "/lib"
     37 
     38 cflags = options.cflags
     39+cppflags = options.cppflags # C preprocessor flags
     40+cxxflags = options.cxxflags # C++ compiler flags
     41 ldflags = options.ldflags
     42 prefix = options.prefix
     43 
     44+# Note: This should be put into / added to cppflags:
     45 includes = "-I" + gmp_include_dir + " -I./include"
     46+# Note: This should be put into / added to ldflags:
     47 libs = "-L" + gmp_lib_dir + " -lgmp -lm"
     48 
     49 if options.use_flint:
     50@@ -104,6 +126,8 @@
     51    libs = libs + " -L" + flint_lib_dir + " -lflint"
     52    cflags = cflags + " -std=c99 -DZNP_USE_FLINT"
     53 
     54+# Note: These also belong to CPPFLAGS and LDFLAGS, respectively:
     55+# (But we currently don't use NTL in Sage's zn_poly installation anyway.)
     56 cpp_includes = includes + " -I" + ntl_include_dir
     57 cpp_libs = libs + " -L" + ntl_lib_dir + " -lntl"
     58 
     59@@ -118,18 +142,27 @@
     60 print "# by makemakefile.py on " + time.strftime("%a, %d %b %Y %H:%M:%S +0000",
     61                                                  time.gmtime())
     62 print "#"
     63+print "# (makemakefile.py patched for Sage, 04/2012)"
     64 print
     65 
     66 print
     67-print "CC = gcc"
     68+print "CC ?= gcc"
     69+print "CPP ?= cpp"
     70 print "CFLAGS = " + cflags
     71+print "CPPFLAGS = " + cppflags
     72 print "LDFLAGS = " + ldflags
     73-print "INCLUDES = " + includes
     74-print "LIBS = " + libs
     75+print "INCLUDES = " + includes # These are options to the C preprocessor.
     76+print "LIBS = " + libs # These are linker options passed to the compiler.
     77+print
     78+print "AR ?= ar"
     79+print "RANLIB ?= ranlib"
     80+print
     81+print "SHARED_FLAG ?= -shared"
     82+print "SONAME_FLAG ?= -soname" # '-h' for the Sun/Solaris linker
     83 
     84 print
     85-print "CPP = g++"
     86-print "CPPFLAGS = " + cflags
     87+print "CXX ?= g++"             # The C++ compiler.
     88+print "CXXFLAGS = " + cxxflags # Options passed to the C++ compiler.
     89 print "CPP_INCLUDES = " + cpp_includes
     90 print "CPP_LIBS = " + cpp_libs
     91 
     92@@ -185,17 +218,23 @@
     93 print "##### library targets"
     94 print
     95 print "libzn_poly.a: $(LIBOBJS)"
     96-print "\tar -r libzn_poly.a $(LIBOBJS)"
     97-print "\tranlib libzn_poly.a"
     98+print "\t$(AR) -r libzn_poly.a $(LIBOBJS)"
     99+print "\t$(RANLIB) libzn_poly.a"
     100 print
     101+print "# TODO: Put '-single_module -fPIC -dynamiclib' into $(SHARED_FLAG)"
     102+print "#       and use that; also support $(SO_EXTENSION)..."
     103 print "libzn_poly.dylib: $(LIBOBJS)"
     104-print "\t$(CC) -single_module -fPIC -dynamiclib -o libzn_poly.dylib " \
     105+print "\t$(CC) $(LDFLAGS) -single_module -fPIC -dynamiclib -o libzn_poly.dylib " \
    5106       "$(LIBOBJS) $(LIBS)"
    6107 print
     108+print "# Left for compatibility with previous versions of Sage's 'spkg-install':"
    7109+print "libzn_poly.dylib64: $(LIBOBJS)"
    8110+print "\t$(CC) -m64 -single_module -fPIC -dynamiclib -o libzn_poly.dylib $(LIBOBJS) $(LIBS)"
    9111+print
    10112 print "libzn_poly.so: $(LIBOBJS)"
    11113-print "\t$(CC) -shared -Wl,-soname,libzn_poly-`cat VERSION`.so " \
    12 +print "\t$(CC) -shared $(LDFLAGS) -Wl,-soname,libzn_poly-`cat VERSION`.so " \
     114+print "\t$(CC) $(SHARED_FLAG) $(LDFLAGS) -Wl,$(SONAME_FLAG),libzn_poly-`cat VERSION`.so " \
    13115       "-o libzn_poly-`cat VERSION`.so $(LIBOBJS) $(LIBS)"
    14  print "\t ln -sf libzn_poly-`cat VERSION`.so libzn_poly.so"
     116-print "\t ln -sf libzn_poly-`cat VERSION`.so libzn_poly.so"
     117+print "\tln -sf libzn_poly-`cat VERSION`.so libzn_poly.so"
    15118 
     119 print
     120 print
     121@@ -210,7 +249,7 @@
     122 print
     123 for x in prof_progs:
     124    print "%s-main.o: %s-main.c $(HEADERS)" % (x, x)
     125-   print "\t$(CC) $(CFLAGS) $(INCLUDES) -DNDEBUG -o %s-main.o -c %s-main.c" \
     126+   print "\t$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -DNDEBUG -o %s-main.o -c %s-main.c" \
     127          % (x, x)
     128    print
     129    print "%s: %s-main.o $(PROFOBJS)" % (x, x)
     130@@ -218,11 +257,11 @@
     131          % (x, x)
     132    print
     133    print "%s-main-ntl.o: %s-main.c $(HEADERS)" % (x, x)
     134-   print "\t$(CC) $(CFLAGS) $(INCLUDES) -DPROFILE_NTL -DNDEBUG " \
     135+   print "\t$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -DPROFILE_NTL -DNDEBUG " \
     136          "-o %s-main-ntl.o -c %s-main.c" % (x, x)
     137    print
     138    print "%s-ntl: %s-main-ntl.o $(CPP_PROFOBJS)" % (x, x)
     139-   print "\t$(CPP) $(CPPFLAGS) $(LDFLAGS) -o %s-ntl %s-main-ntl.o " \
     140+   print "\t$(CXX) $(CXXFLAGS) $(LDFLAGS) -o %s-ntl %s-main-ntl.o " \
     141          "$(CPP_PROFOBJS) $(CPP_LIBS)" % (x, x)
     142    print
     143 
     144@@ -249,7 +288,7 @@
     145 for x in lib_modules + test_modules + testprof_modules + demo_progs:
     146    print
     147    print "%s-DEBUG.o: %s.c $(HEADERS)" % (x, x)
     148-   print "\t$(CC) -g $(CFLAGS) $(INCLUDES) -DDEBUG -o %s-DEBUG.o -c %s.c" \
     149+   print "\t$(CC) -g $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -DDEBUG -o %s-DEBUG.o -c %s.c" \
     150          % (x, x)
     151 
     152 print
     153@@ -259,7 +298,7 @@
     154                        tune_modules + demo_progs:
     155    print
     156    print "%s.o: %s.c $(HEADERS)" % (x, x)
     157-   print "\t$(CC) $(CFLAGS) $(INCLUDES) -DNDEBUG -o %s.o -c %s.c" % (x, x)
     158+   print "\t$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -DNDEBUG -o %s.o -c %s.c" % (x, x)
     159 
     160 print
     161 print
     162@@ -267,7 +306,7 @@
     163 for x in cpp_prof_modules:
     164    print
     165    print "%s.o: %s.c $(HEADERS)" % (x, x)
     166-   print "\t$(CPP) $(CPPFLAGS) $(CPP_INCLUDES) -DNDEBUG -o %s.o -c %s.c" \
     167+   print "\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(CPP_INCLUDES) -DNDEBUG -o %s.o -c %s.c" \
     168          % (x, x)
     169 
     170 
  • deleted file patches/mpn_mulmid-tune.c

    diff --git a/patches/mpn_mulmid-tune.c b/patches/mpn_mulmid-tune.c
    deleted file mode 100644
    + -  
    1 /*
    2    mpn_mulmid-tune.c:  tuning program for integer middle product algorithms
    3    
    4    Copyright (C) 2007, 2008, David Harvey
    5    
    6    This file is part of the zn_poly library (version 0.9).
    7    
    8    This program is free software: you can redistribute it and/or modify
    9    it under the terms of the GNU General Public License as published by
    10    the Free Software Foundation, either version 2 of the License, or
    11    (at your option) version 3 of the License.
    12 
    13    This program is distributed in the hope that it will be useful,
    14    but WITHOUT ANY WARRANTY; without even the implied warranty of
    15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16    GNU General Public License for more details.
    17 
    18    You should have received a copy of the GNU General Public License
    19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20 
    21 */
    22 
    23 #include <math.h>
    24 #include "support.h"
    25 #include "zn_poly_internal.h"
    26 #include "profiler.h"
    27 
    28 
    29 /*
    30    Finds approximate threshold between basecase and karatsuba integer middle
    31    product algorithms.
    32    
    33    Store this in mpn_smp_kara_thresh, and writes some logging information
    34    to flog.
    35 */
    36 void
    37 tune_mpn_smp_kara (FILE* flog, int verbose)
    38 {
    39    fprintf (flog, "mpn smp kara: ");
    40    fflush (flog);
    41 
    42    // how long we are willing to wait for each profile run
    43    const double speed = 0.0001;
    44 
    45    // reset the threshold so karatsuba never accidentally recurses
    46    ZNP_mpn_smp_kara_thresh = SIZE_MAX;
    47 
    48    size_t thresh;
    49    const int max_intervals = 200;
    50    size_t points[max_intervals + 1];
    51    double score[max_intervals + 1];
    52    double result[2];
    53    profile_info_t info;
    54 
    55    // find an upper bound, where karatsuba appears to be safely ahead of
    56    // basecase
    57    size_t upper;
    58    int found = 0;
    59    for (upper = 2; upper <= 1000 && !found; upper = 2 * upper)
    60    {
    61       info->n1 = 2 * upper - 1;
    62       info->n2 = info->n = upper;
    63      
    64       result[0] = profile (NULL, NULL, profile_mpn_smp_basecase, info, speed);
    65       result[1] = profile (NULL, NULL, profile_mpn_smp_kara, info, speed);
    66      
    67       if (result[1] < 0.9 * result[0])
    68          found = 1;
    69    }
    70 
    71    if (!found)
    72    {
    73       // couldn't find a reasonable upper bound
    74       thresh = SIZE_MAX;
    75       goto done;
    76    }
    77    
    78    // subdivide [2, upper] into intervals and sample at each endpoint
    79    double lower = 2.0;
    80    double ratio = (double) upper / lower;
    81    unsigned i;
    82    for (i = 0; i <= max_intervals; i++)
    83    {
    84       points[i] = ceil (lower * pow (ratio, (double) i / max_intervals));
    85       info->n1 = 2 * points[i] - 1;
    86       info->n2 = info->n = points[i];
    87       result[0] = profile (NULL, NULL, profile_mpn_smp_basecase, info, speed);
    88       result[1] = profile (NULL, NULL, profile_mpn_smp_kara, info, speed);
    89       score[i] = result[1] / result[0];
    90    }
    91    
    92    // estimate threshold
    93    unsigned count = 0;
    94    for (i = 0; i <= max_intervals; i++)
    95       if (score[i] > 1.0)
    96          count++;
    97    thresh = (size_t)
    98         ceil (lower * pow (ratio, (double) count / (max_intervals + 1)));
    99 
    100    done:
    101 
    102    if (verbose)
    103    {
    104       if (thresh == SIZE_MAX)
    105          fprintf (flog, "infinity");
    106       else
    107          fprintf (flog, "%lu", thresh);
    108    }
    109    else
    110       fprintf (flog, "done");
    111 
    112    fflush (flog);
    113 
    114    ZNP_mpn_smp_kara_thresh = thresh;
    115 
    116    fprintf (flog, "\n");
    117 }
    118 
    119 
    120 
    121 /*
    122    Finds approximate threshold between karatsuba and fallback integer middle
    123    product algorithms.
    124    
    125    Store this in mpn_mulmid_fallback_thresh, and writes some logging
    126    information to flog.
    127 */
    128 void
    129 tune_mpn_mulmid_fallback (FILE* flog, int verbose)
    130 {
    131    fprintf (flog, "mpn mulmid fallback: ");
    132    fflush (flog);
    133 
    134    // how long we are willing to wait for each profile run
    135    const double speed = 0.0001;
    136 
    137    size_t thresh;
    138    const int max_intervals = 30;
    139    size_t points[max_intervals + 1];
    140    double score[max_intervals + 1];
    141    double result[2];
    142    profile_info_t info;
    143 
    144    // find an upper bound, where fallback appears to be safely ahead of
    145    // karatsuba
    146    size_t upper = ZNP_mpn_smp_kara_thresh;
    147    int found = 0;
    148    for (; upper <= 40000 && !found; upper = 2 * upper)
    149    {
    150       info->n1 = 2 * upper - 1;
    151       info->n2 = info->n = upper;
    152      
    153       result[0] = profile (NULL, NULL, profile_mpn_smp_kara, info, speed);
    154       result[1] = profile (NULL, NULL, profile_mpn_mulmid_fallback,
    155                            info, speed);
    156                          
    157       if (result[1] < 0.9 * result[0])
    158          found = 1;
    159    }
    160 
    161    if (!found)
    162    {
    163       // couldn't find a reasonable upper bound
    164       thresh = SIZE_MAX;
    165       goto done;
    166    }
    167    
    168    // subdivide [kara_thresh, upper] into intervals and sample at
    169    // each endpoint
    170    double lower = ZNP_mpn_smp_kara_thresh;
    171    double ratio = (double) upper / lower;
    172    unsigned i;
    173    for (i = 0; i <= max_intervals; i++)
    174    {
    175       points[i] = ceil (lower * pow (ratio, (double) i / max_intervals));
    176       info->n1 = 2 * points[i] - 1;
    177       info->n2 = info->n = points[i];
    178       result[0] = profile (NULL, NULL, profile_mpn_smp_kara, info, speed);
    179       result[1] = profile (NULL, NULL, profile_mpn_mulmid_fallback,
    180                            info, speed);
    181       score[i] = result[1] / result[0];
    182    }
    183    
    184    // estimate threshold
    185    unsigned count = 0;
    186    for (i = 0; i <= max_intervals; i++)
    187       if (score[i] > 1.0)
    188          count++;
    189    thresh = (size_t)
    190         ceil (lower * pow (ratio, (double) count / (max_intervals + 1)));
    191 
    192    done:
    193 
    194    if (verbose)
    195    {
    196       if (thresh == SIZE_MAX)
    197          fprintf (flog, "infinity");
    198       else
    199          fprintf (flog, "%lu", thresh);
    200    }
    201    else
    202       fprintf (flog, "done");
    203 
    204    fflush (flog);
    205 
    206    ZNP_mpn_mulmid_fallback_thresh = thresh;
    207 
    208    fprintf (flog, "\n");
    209 }
    210 
    211 
    212 // end of file ****************************************************************
  • patches/mpn_mulmid-tune.c.patch

    diff --git a/patches/mpn_mulmid-tune.c.patch b/patches/mpn_mulmid-tune.c.patch
    a b  
    1 --- mpn_mulmid-tune.c.orig      2010-04-26 23:47:46.000000000 +0200
    2 +++ mpn_mulmid-tune.c   2010-04-26 23:48:58.000000000 +0200
     1--- src/tune/mpn_mulmid-tune.c  2010-04-26 23:47:46.000000000 +0200
     2+++ patches/mpn_mulmid-tune.c   2010-04-26 23:52:16.000000000 +0200
    33@@ -46,6 +46,9 @@
    44    ZNP_mpn_smp_kara_thresh = SIZE_MAX;
    55 
  • deleted file patches/mul-tune.c

    diff --git a/patches/mul-tune.c b/patches/mul-tune.c
    deleted file mode 100644
    + -  
    1 /*
    2    mul-tune.c:  tuning program for multiplication algorithms
    3    
    4    Copyright (C) 2007, 2008, David Harvey
    5    
    6    This file is part of the zn_poly library (version 0.9).
    7    
    8    This program is free software: you can redistribute it and/or modify
    9    it under the terms of the GNU General Public License as published by
    10    the Free Software Foundation, either version 2 of the License, or
    11    (at your option) version 3 of the License.
    12 
    13    This program is distributed in the hope that it will be useful,
    14    but WITHOUT ANY WARRANTY; without even the implied warranty of
    15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16    GNU General Public License for more details.
    17 
    18    You should have received a copy of the GNU General Public License
    19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20 
    21 */
    22 
    23 #include <math.h>
    24 #include "support.h"
    25 #include "zn_poly_internal.h"
    26 #include "profiler.h"
    27 
    28 
    29 /*
    30    For each modulus size, finds approximate threshold between KS4 and fft
    31    multiplication algorithms.
    32    
    33    (Note this needs to be done *after* the KS1/KS2/KS4 and nussbaumer
    34    thresholds have been determined, since they are used as subroutines.)
    35    
    36    Store these in the global threshold table, and writes some logging
    37    information to flog.
    38 */
    39 void
    40 tune_mul (FILE* flog, int sqr, int verbose)
    41 {
    42    unsigned b;
    43 
    44    fprintf (flog, "    KS/FFT %s: ", sqr ? "sqr" : "mul");
    45    fflush (flog);
    46    
    47    // how long we are willing to wait for each profile run
    48    const double speed = 0.0001;
    49    
    50    // run tuning process for each modulus size
    51    for (b = 2; b <= ULONG_BITS; b++)
    52    {
    53       // thresh for KS4->FFT
    54       size_t thresh;
    55    
    56       const int max_intervals = 20;
    57       size_t points[max_intervals + 1];
    58       double score[max_intervals + 1];
    59 
    60       double result[2];
    61 
    62       profile_info_t info[2];
    63       info[0]->sqr = info[1]->sqr = sqr;
    64       info[0]->m = info[1]->m = (1UL << (b - 1)) + 1;
    65 
    66       info[0]->algo = ALGO_MUL_KS4;
    67       info[1]->algo = ALGO_MUL_FFT;
    68      
    69       // find an upper bound, where FFT algorithm appears to be safely
    70       // ahead of KS4 algorithm
    71       size_t upper;
    72       int found = 0;
    73       for (upper = 45; upper <= 65536 && !found; upper = 2 * upper)
    74       {
    75          info[0]->n1 = info[1]->n1 = upper;
    76          info[0]->n2 = info[1]->n2 = upper;
    77          
    78          result[0] = profile (NULL, NULL, profile_mul, info[0], speed);
    79          result[1] = profile (NULL, NULL, profile_mul, info[1], speed);
    80          
    81          if (result[1] < 0.95 * result[0])
    82             found = 1;
    83       }
    84 
    85       if (!found)
    86       {
    87          // couldn't find a reasonable upper bound
    88          thresh = SIZE_MAX;
    89          goto done;
    90       }
    91      
    92       // find a lower bound, where KS4 algorithm appears to be safely
    93       // ahead of FFT algorithm
    94       size_t lower;
    95       found = 0;
    96       for (lower = upper/2; lower >= 2 && !found; lower = lower / 2)
    97       {
    98          info[0]->n1 = info[1]->n1 = lower;
    99          info[0]->n2 = info[1]->n2 = lower;
    100          
    101          result[0] = profile (NULL, NULL, profile_mul, info[0], speed);
    102          result[1] = profile (NULL, NULL, profile_mul, info[1], speed);
    103          
    104          if (result[1] > 1.05 * result[0])
    105             found = 1;
    106       }
    107 
    108       if (!found)
    109       {
    110          // couldn't find a reasonable lower bound
    111          thresh = 0;
    112          goto done;
    113       }
    114 
    115       // subdivide [lower, upper] into intervals and sample at each endpoint
    116       double ratio = (double) upper / (double) lower;
    117       unsigned i;
    118       for (i = 0; i <= max_intervals; i++)
    119       {
    120          points[i] = ceil (lower * pow (ratio, (double) i / max_intervals));
    121          info[0]->n1 = info[1]->n1 = points[i];
    122          info[0]->n2 = info[1]->n2 = points[i];
    123          result[0] = profile (NULL, NULL, profile_mul, info[0], speed);
    124          result[1] = profile (NULL, NULL, profile_mul, info[1], speed);
    125          score[i] = result[1] / result[0];
    126       }
    127      
    128       // estimate threshold
    129       unsigned count = 0;
    130       for (i = 0; i <= max_intervals; i++)
    131          if (score[i] > 1.0)
    132             count++;
    133       thresh = (size_t)
    134            ceil (lower * pow (ratio, (double) count / (max_intervals + 1)));
    135 
    136       done:
    137      
    138       if (verbose)
    139       {
    140          fprintf (flog, "\nbits = %u, cross to FFT at ", b);
    141          if (thresh == SIZE_MAX)
    142             fprintf (flog, "infinity");
    143          else
    144             fprintf (flog, "%lu", thresh);
    145       }
    146       else
    147          fprintf (flog, ".");
    148 
    149       fflush (flog);
    150 
    151       if (sqr)
    152          tuning_info[b].sqr_fft_thresh = thresh;
    153       else
    154          tuning_info[b].mul_fft_thresh = thresh;
    155    }
    156 
    157    fprintf (flog, "\n");
    158 }
    159 
    160 
    161 // end of file ****************************************************************
  • patches/mul-tune.c.patch

    diff --git a/patches/mul-tune.c.patch b/patches/mul-tune.c.patch
    a b  
    1 --- mul-tune.c.orig     2010-04-26 23:34:59.000000000 +0200
    2 +++ mul-tune.c  2010-04-26 23:35:26.000000000 +0200
     1--- src/tune/mul-tune.c 2010-04-26 23:40:07.000000000 +0200
     2+++ patches/mul-tune.c  2010-04-26 23:52:16.000000000 +0200
    33@@ -53,6 +53,10 @@
    44       // thresh for KS4->FFT
    55       size_t thresh;
  • deleted file patches/mulmid-tune.c

    diff --git a/patches/mulmid-tune.c b/patches/mulmid-tune.c
    deleted file mode 100644
    + -  
    1 /*
    2    mulmid-tune.c:  tuning program for middle product algorithms
    3    
    4    Copyright (C) 2007, 2008, David Harvey
    5    
    6    This file is part of the zn_poly library (version 0.9).
    7    
    8    This program is free software: you can redistribute it and/or modify
    9    it under the terms of the GNU General Public License as published by
    10    the Free Software Foundation, either version 2 of the License, or
    11    (at your option) version 3 of the License.
    12 
    13    This program is distributed in the hope that it will be useful,
    14    but WITHOUT ANY WARRANTY; without even the implied warranty of
    15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16    GNU General Public License for more details.
    17 
    18    You should have received a copy of the GNU General Public License
    19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20 
    21 */
    22 
    23 #include <math.h>
    24 #include "support.h"
    25 #include "zn_poly_internal.h"
    26 #include "profiler.h"
    27 
    28 
    29 /*
    30    For each modulus size, finds approximate threshold between KS4 and fft
    31    middle product algorithms.
    32    
    33    (Note this needs to be done *after* the KS1/KS2/KS4 multiplication and
    34    nussbaumer thresholds have been determined, since they are used as
    35    subroutines.)
    36    
    37    Store these in the global threshold table, and writes some logging
    38    information to flog.
    39 */
    40 void
    41 tune_mulmid (FILE* flog, int verbose)
    42 {
    43    unsigned b;
    44 
    45    fprintf (flog, " KS/FFT mulmid: ");
    46    fflush (flog);
    47    
    48    // how long we are willing to wait for each profile run
    49    const double speed = 0.0001;
    50    
    51    // run tuning process for each modulus size
    52    for (b = 2; b <= ULONG_BITS; b++)
    53    {
    54       // thresh for KS4->FFT
    55       size_t thresh;
    56 
    57       const int max_intervals = 20;
    58       size_t points[max_intervals + 1];
    59       double score[max_intervals + 1];
    60    
    61       double result[2];
    62 
    63       profile_info_t info[2];
    64       info[0]->m = info[1]->m = (1UL << (b - 1)) + 1;
    65 
    66       info[0]->algo = ALGO_MULMID_KS4;
    67       info[1]->algo = ALGO_MULMID_FFT;
    68      
    69       // find an upper bound, where FFT algorithm appears to be safely
    70       // ahead of KS4 algorithm
    71       size_t upper;
    72       int found = 0;
    73       for (upper = 45; upper <= 65536 && !found; upper = 2 * upper)
    74       {
    75          info[0]->n1 = info[1]->n1 = 2 * upper;
    76          info[0]->n2 = info[1]->n2 = upper;
    77          
    78          result[0] = profile (NULL, NULL, profile_mulmid, info[0], speed);
    79          result[1] = profile (NULL, NULL, profile_mulmid, info[1], speed);
    80          
    81          if (result[1] < 0.95 * result[0])
    82             found = 1;
    83       }
    84 
    85       if (!found)
    86       {
    87          // couldn't find a reasonable upper bound
    88          thresh = SIZE_MAX;
    89          goto done;
    90       }
    91      
    92       // find a lower bound, where KS4 algorithm appears to be safely
    93       // ahead of FFT algorithm
    94       size_t lower;
    95       found = 0;
    96       for (lower = upper/2; lower >= 2 && !found; lower = lower / 2)
    97       {
    98          info[0]->n1 = info[1]->n1 = 2 * lower;
    99          info[0]->n2 = info[1]->n2 = lower;
    100          
    101          result[0] = profile (NULL, NULL, profile_mulmid, info[0], speed);
    102          result[1] = profile (NULL, NULL, profile_mulmid, info[1], speed);
    103          
    104          if (result[1] > 1.05 * result[0])
    105             found = 1;
    106       }
    107 
    108       if (!found)
    109       {
    110          // couldn't find a reasonable lower bound
    111          thresh = 0;
    112          goto done;
    113       }
    114 
    115       // subdivide [lower, upper] into intervals and sample at each endpoint
    116       double ratio = (double) upper / (double) lower;
    117       unsigned i;
    118       for (i = 0; i <= max_intervals; i++)
    119       {
    120          points[i] = ceil (lower * pow (ratio, (double) i / max_intervals));
    121          info[0]->n1 = info[1]->n1 = 2 * points[i];
    122          info[0]->n2 = info[1]->n2 = points[i];
    123          result[0] = profile (NULL, NULL, profile_mulmid, info[0], speed);
    124          result[1] = profile (NULL, NULL, profile_mulmid, info[1], speed);
    125          score[i] = result[1] / result[0];
    126       }
    127      
    128       // estimate threshold
    129       unsigned count = 0;
    130       for (i = 0; i <= max_intervals; i++)
    131          if (score[i] > 1.0)
    132             count++;
    133       thresh = (size_t)
    134            ceil (lower * pow (ratio, (double) count / (max_intervals + 1)));
    135 
    136       done:
    137      
    138       if (verbose)
    139       {
    140          fprintf (flog, "\nbits = %u, cross to FFT at ", b);
    141          if (thresh == SIZE_MAX)
    142             fprintf (flog, "infinity");
    143          else
    144             fprintf (flog, "%lu", thresh);
    145       }
    146       else
    147          fprintf (flog, ".");
    148 
    149       fflush (flog);
    150 
    151       tuning_info[b].mulmid_fft_thresh = thresh;
    152    }
    153 
    154    fprintf (flog, "\n");
    155 }
    156 
    157 
    158 // end of file ****************************************************************
  • patches/mulmid-tune.c.patch

    diff --git a/patches/mulmid-tune.c.patch b/patches/mulmid-tune.c.patch
    a b  
    1 --- mulmid-tune.c.orig  2010-04-26 23:37:29.000000000 +0200
    2 +++ mulmid-tune.c       2010-04-26 23:37:10.000000000 +0200
     1--- src/tune/mulmid-tune.c      2010-04-26 23:40:03.000000000 +0200
     2+++ patches/mulmid-tune.c       2010-04-26 23:52:16.000000000 +0200
    33@@ -53,6 +53,10 @@
    44    {
    55       // thresh for KS4->FFT
  • spkg-check

    diff --git a/spkg-check b/spkg-check
    a b  
    11#!/usr/bin/env bash
    22
    3 ################################################################
     3###############################################################################
    44#
    5 #  zn_poly sage check script
     5#  zn_poly Sage check script
    66#
    7 ################################################################
     7###############################################################################
    88
    99if [ -z "$SAGE_LOCAL" ]; then
    10    echo "SAGE_LOCAL undefined ... exiting";
    11    echo "Maybe run 'sage -sh'?"
    12    exit 1
     10    echo >&2 "Error: SAGE_LOCAL undefined - exiting..."
     11    echo >&2 "Maybe run 'sage -sh'?"
     12    exit 1
    1313fi
    1414
    15 # Let the user set an environment variable CFLAG64 to
    16 # indicate the C compiler flag for 64-bit builds. By
    17 # default this will be -m64. IBM's compiler on AIX
    18 # and HP's on HP-UX do NOT use -m64.
     15###############################################################################
     16# Set up environment variables:
     17###############################################################################
    1918
    20 if [ -z "$CFLAG64" ] ; then
    21    CFLAG64=-m64
     19if [ "$SAGE64" = yes ]; then
     20    echo "Building a 64-bit version of zn_poly's \"extensive\" test suite."
     21    if [ -z "$CFLAG64" ]; then
     22        CFLAG64=-m64
     23    fi
     24    CFLAGS="$CFLAGS $CFLAG64"
     25    CPPFLAGS="$CPPFLAGS $CFLAG64"
     26    CXXFLAGS="$CXXFLAGS $CFLAG64"
     27    LDFLAGS="$LDFLAGS $CFLAG64"
     28    # This should really have happened in advance from 'spkg-install':
     29    # cp patches/makemakefile.py src/makemakefile.py
     30    # if [ $? -ne 0 ]; then
     31    #     echo >&2 "Error copying over patched 'makemakefile.py'."
     32    #     exit 1
     33    # fi
     34    # (Also no need to re-'sed' it in case we're using the Sun linker.)
    2235fi
    2336
    24 if [ "x$SAGE64" = xyes ]; then
    25    CFLAGS="$CFLAGS $CFLAG64"
    26    CPPFLAGS="$CPPFLAGS $CFLAG64" ; export CPPFLAGS
    27    LDFLAGS="$LDFLAGS $CFLAG64" ; export LDFLAGS
    28    CC="$CC CFLAG64" ; export CC
     37if [ "$SAGE_DEBUG" = yes ]; then
     38    echo >&2 "Warning: Setting SAGE_DEBUG to 'yes' completely disables optimization."
     39    CFLAGS="$CFLAGS -O0 -g -fPIC"
     40    CXXFLAGS="$CXXFLAGS -O0 -g -fPIC"
     41else
     42    CFLAGS="-O3 -g $CFLAGS -fPIC"
     43    CXXFLAGS="-O3 -g $CXXFLAGS -fPIC"
    2944fi
     45# LDFLAGS="-L. $LDFLAGS" # Not needed. (-leif, 04/2012)
    3046
    31 cd src
     47export CFLAGS CPPFLAGS CXXFLAGS LDFLAGS # Partially redundant, but safe.
    3248
    33 # The methods for testing zn_poly are more complex than most other packages.
    34 # A 'make check' does some quick tests. These are run from spkg-install
    35 # to check zn_poly is not obviously disfunctional
     49# Actually, these flags have been written to the Makefile during 'configure'.
     50# Only CC, CPP and CXX settings from the environment currently override the
     51# ones in the Makefile (which was generated from a patched 'makemakefile.py').
     52# -leif 04/2012
    3653
    37 # However, a more comprehensive set of tests can be run
    38 # by first building a test program, then running that test program.
     54###############################################################################
     55# Build the 'test' program (if it's not already built) and run it:
     56###############################################################################
    3957
    40 # To quote from the file src/README
     58cd src/
     59
     60# The methods for testing zn_poly are more complex than those of most other
     61# packages.  A 'make check' does some quick tests.  These are run from
     62# 'spkg-install' to check zn_poly is not obviously disfunctional.
     63#
     64# However, a more comprehensive set of tests can be run by first building a
     65# test program, then running that test program, which we do here.
     66#
     67# To quote from the file src/README:
    4168#
    4269# make check
    4370#    Runs some quick tests to make sure that everything appears to be working.
    44 
     71#
    4572# make test
    4673#    Builds a test program. Running "test/test all" runs the whole zn_poly test
    4774#    suite, which tests zn_poly much more thoroughly than "make check".
    4875
    49 make test  #  Make sure the test program is built
    50 
    51 if [ $? -ne 0 ]; then
    52     echo "zn_poly failed to build the test program"
    53     echo "So zn_poly's extensive test suite can not be run"
     76echo
     77echo "Now building zn_poly's extensive test suite (if not already built)..."
     78# $MAKE test CC="$CC" # See comment above. We don't have to pass CC.
     79$MAKE test # Make sure the test program is built.
     80if [ $? -ne 0 ] || [ ! -x test/test ]; then
     81    echo >&2 "Error: zn_poly failed to build its 'test' program,"
     82    echo >&2 "       so zn_poly's extensive test suite cannot be run."
    5483    exit 1
    5584fi
    5685
    57 echo ""
    58 echo "zn_poly's extensive test suite will now be run"
    59 echo ""
    60 
    61 test/test all # Run the extensive test suite
    62 
     86echo
     87echo "Now running zn_poly's extensive test suite..."
     88test/test all # Run the extensive test suite.
    6389if [ $? -ne 0 ]; then
    64     echo "zn_poly failed to pass the extensive test suite"
     90    echo >&2 "Error: zn_poly failed to pass its extensive test suite."
    6591    exit 1
    66 else
    67     echo "zn_poly has passed the extensive test suite."
    68     exit 0
    6992fi
    70 
     93echo "zn_poly has passed its extensive test suite."
  • spkg-install

    diff --git a/spkg-install b/spkg-install
    a b  
    11#!/usr/bin/env bash
    22
    3 ################################################################
     3###############################################################################
    44#
    5 #  zn_poly sage install script
     5#  zn_poly Sage install script
    66#
    7 ################################################################
     7###############################################################################
    88
    99if [ -z "$SAGE_LOCAL" ]; then
    10    echo "SAGE_LOCAL undefined ... exiting";
    11    echo "Maybe run 'sage -sh'?"
    12    exit 1
     10    echo >&2 "Error: SAGE_LOCAL undefined - exiting..."
     11    echo >&2 "Maybe run 'sage -sh'?"
     12    exit 1
    1313fi
    1414
    15 # Let the user set an environment variable CFLAG64 to
    16 # indicate the C compiler flag for 64-bit builds. By
    17 # default this will be -m64. IBM's compiler on AIX
    18 # and HP's on HP-UX do NOT use -m64.
     15###############################################################################
     16# Set up environment variables:
     17###############################################################################
    1918
    20 if [ -z "$CFLAG64" ] ; then
    21    CFLAG64=-m64
     19if [ "$SAGE64" = yes ]; then
     20    echo "Building a 64-bit version of zn_poly."
     21    if [ -z "$CFLAG64" ]; then
     22        CFLAG64=-m64
     23    fi
     24    CFLAGS="$CFLAGS $CFLAG64"
     25    CPPFLAGS="$CPPFLAGS $CFLAG64"
     26    CXXFLAGS="$CXXFLAGS $CFLAG64"
     27    LDFLAGS="$LDFLAGS $CFLAG64"
     28    # We now do this unconditionally below (actually by patching):
     29    # cp -f patches/makemakefile.py src/makemakefile.py
     30    # if [ $? -ne 0 ]; then
     31    #     echo >&2 "Error copying over patched 'makemakefile.py'."
     32    #     exit 1
     33    # fi
    2234fi
    2335
    24 if [ "x$SAGE64" = xyes ]; then
    25    echo "Building a 64-bit version of zn_poly"
    26    CFLAGS="$CFLAGS $CFLAG64"
    27    CPPFLAGS="$CPPFLAGS $CFLAG64" ; export CPPFLAGS
    28    LDFLAGS="$LDFLAGS $CFLAG64" ; export LDFLAGS
    29    cp patches/makemakefile.py src/makemakefile.py
    30    CC="$CC $CFLAG64" ; export CC
     36if [ "$SAGE_DEBUG" = yes ]; then
     37    echo >&2 "Warning: Setting SAGE_DEBUG to 'yes' completely disables optimization."
     38    CFLAGS="$CFLAGS -O0 -g -fPIC"
     39    CXXFLAGS="$CXXFLAGS -O0 -g -fPIC"
     40else
     41    CFLAGS="-O3 -g $CFLAGS -fPIC"
     42    CXXFLAGS="-O3 -g $CXXFLAGS -fPIC"
     43fi
     44# LDFLAGS="-L. $LDFLAGS" # Not needed. (-leif, 04/2012)
     45
     46export CFLAGS CPPFLAGS CXXFLAGS LDFLAGS # Partially redundant, but safe.
     47
     48# (Actually the currently generated Makefile won't use any of them from the
     49# environment; instead we have to pass them with special options to 'configure',
     50# which we do below.  Furthermore, CPPFLAGS and CXXFLAGS are only supported by
     51# our patched 'makemakefile.py', which is called by 'configure'.)
     52
     53###############################################################################
     54# Apply patches (if any):
     55###############################################################################
     56
     57# cp patches/mpn_mulmid-tune.c patches/mul-tune.c patches/mulmid-tune.c src/tune
     58# if [ $? -ne 0 ]; then
     59#     echo >&2 "Error copying over patched upstream source files."
     60#     exit 1
     61# fi
     62
     63# We now also always patch 'makemakefile.py' below, since the changes are
     64# independent of the setting of SAGE64.
     65
     66cd src/
     67
     68echo "Applying patches (if any) to upstream sources..."
     69for patch in ../patches/*.patch; do
     70    basename "$patch"
     71    patch -p1 <"$patch"
     72    if [ $? -ne 0 ]; then
     73        echo >&2 "Error: '$patch' failed to apply."
     74        exit 1
     75    fi
     76done
     77
     78case "$UNAME" in SunOS)
     79    if ! (ld --version  2>&1 | grep GNU >/dev/null); then
     80        # Assume it's the Sun linker; change '-soname' to '-h':
     81        # echo "Patching 'makemakefile.py' for the Sun linker..."
     82        # sed 's/-soname/-h/g' makemakefile.py > makemakefile.py.$$ &&
     83        # mv -f makemakefile.py.$$ makemakefile.py
     84        # if [ $? -ne 0 ]; then
     85        #     echo >&2 "Error patching 'makemakefile.py' (with 'sed')."
     86        #     exit 1
     87        # fi
     88        # The following is only supported by the Makefile generated by our
     89        # patched 'makemakefile.py':
     90        export SONAME_FLAG=-h
     91    fi;;
     92    *) unset SONAME_FLAG # Leave the Makefile default; for safety.
     93esac
     94
     95unset SHARED_FLAG # Currently leave the Makefile default ('-shared'); for safety.
     96
     97###############################################################################
     98# Configure, tune, build and test zn_poly:
     99###############################################################################
     100
     101echo "Now configuring zn_poly..."
     102# Note: The '--cppflags' and '--cxxflags' options are added by our patch to
     103#       'makemakefile.py', and aren't available with vanilla upstream.
     104#       Moreover, the generated Makefile now takes CC, CXX and CPP from the
     105#       environment, so no need to pass them later explicitly to 'make'.
     106./configure --prefix="$SAGE_LOCAL" \
     107            --cflags="$CFLAGS" --ldflags="$LDFLAGS" \
     108            --cppflags="$CPPFLAGS" --cxxflags="$CXXFLAGS" \
     109            --gmp-prefix="$SAGE_LOCAL" # --ntl-prefix="$SAGE_LOCAL"
     110if [ $? -ne 0 ] || [ ! -f makefile ]; then
     111    echo >&2 "Error configuring zn_poly."
     112    exit 1
    31113fi
    32114
    33 CFLAGS="$CFLAGS -g -fPIC -O3 -L."; export CFLAGS
    34 LDFLAGS="$LDFLAGS"; export LDFLAGS
    35 
    36 if [ "x$UNAME" = xSunOS ] && [  "`ld  --version  2>&1  | grep GNU`" = ""  ]; then
    37    # Change -soname to -h if the Sun linker is used.
    38    sed 's/-soname/-h/g' src/makemakefile.py > /tmp/makemakefile.py.$$
    39    mv /tmp/makemakefile.py.$$ src/makemakefile.py
     115# Run the tuning program, only takes 1 minute or so:
     116echo "Now building zn_poly's self-tuning program..."
     117$MAKE tune # CC="$CC"
     118if [ $? -ne 0 ] || [ ! -x tune/tune ]; then
     119    echo >&2 "Error building zn_poly's tuning program."
     120    exit 1
     121fi
     122echo "Now running zn_poly's self-tuning program..."
     123tune/tune > src/tuning.c
     124if [ $? -ne 0 ]; then
     125    echo >&2 "Error running zn_poly's tuning program."
     126    exit 1
    40127fi
    41128
    42 cp patches/mpn_mulmid-tune.c patches/mul-tune.c patches/mulmid-tune.c src/tune
     129echo "Now building zn_poly with its tuning parameters..."
     130$MAKE # CC="$CC"
    43131if [ $? -ne 0 ]; then
    44         echo "Error patching."
    45         exit 1
     132    echo >&2 "Error building zn_poly."
     133    exit 1
    46134fi
    47135
    48 cd src
    49 
    50 ./configure --gmp-prefix="$SAGE_LOCAL" --ntl-prefix="$SAGE_LOCAL" \
    51             --prefix="$SAGE_LOCAL" --cflags="$CFLAGS" --ldflags="$LDFLAGS"
    52 
    53 # optionally run tuning program, only takes 1 minute or so
    54 $MAKE tune CC=$CC
     136# Run the brief test suite:
     137echo "Now building and running zn_poly's quick self-test..."
     138$MAKE check # CC="$CC"
    55139if [ $? -ne 0 ]; then
    56         echo "Error building zn_poly tuning program."
    57         exit 1
    58 fi
    59 tune/tune > src/tuning.c
    60 
    61 if [ $? -ne 0 ]; then
    62         echo "Error running tune program."
    63         exit 1
     140    echo >&2 "Error running zn_poly's quick test suite ('make check')."
     141    exit 1
     142else
     143    echo "zn_poly's *quick* test suite passed."
     144    if [ "$SAGE_CHECK" != yes ]; then
     145        echo "A more comprehensive test suite can be run if SAGE_CHECK is"
     146        echo "exported to \"yes\", but it takes about 10x as long to run."
     147    fi
    64148fi
    65149
    66 $MAKE CC=$CC
    67 if [ $? -ne 0 ]; then
    68         echo "Error building zn_poly."
    69         exit 1
    70 fi
     150###############################################################################
     151# Build and manually install the shared library:
     152###############################################################################
    71153
    72 # run test suite (quick version)
    73 $MAKE check CC=$CC
     154echo "Now building and installing zn_poly's shared library..."
    74155
    75 if [ $? -ne 0 ]; then
    76    echo "Error running zn_poly's quick test suite (make check)."
    77    exit 1
    78 else
    79    echo ""
    80    echo "zn_poly's *quick* test suite passed. A more comprehensive"
    81    echo "test suite can be run if SAGE_CHECK is exported to \"yes\""
    82    echo "but it takes about 10x as long to run"
    83    echo ""
    84 fi
    85 
    86 
    87 # UNIX
    88 if [ $UNAME != "Darwin" ]; then
    89     $MAKE libzn_poly.so CC=$CC
     156if [ "$UNAME" != Darwin ]; then
     157    # Linux, SunOS/Solaris, Cygwin etc.:
     158    $MAKE libzn_poly.so # CC="$CC"
    90159    if [ $? -ne 0 ]; then
    91         echo "Error building zn_poly shared library."
     160        echo >&2 "Error building zn_poly's shared library."
    92161        exit 1
    93162    fi
    94     $CP libzn_poly-0.9.so "$SAGE_LOCAL/lib/"
    95     (cd $SAGE_LOCAL/lib/ && ln -sf libzn_poly-0.9.so libzn_poly.so)
    96 fi
    97 
    98 # CYGWIN
    99 if [ $UNAME = "CYGWIN" ]; then
    100     ln -s "$SAGE_LOCAL"/lib/libzn_poly.so "$SAGE_LOCAL"/lib/libzn_poly.dll
     163    cp -f libzn_poly-0.9.so "$SAGE_LOCAL"/lib/ &&
     164    (cd "$SAGE_LOCAL"/lib/ && ln -sf libzn_poly-0.9.so libzn_poly.so)
     165    if [ $? -ne 0 ]; then
     166        echo >&2 "Error installing zn_poly's shared library."
     167        exit 1
     168    fi
     169    if [ "$UNAME" = CYGWIN ]; then
     170        (cd "$SAGE_LOCAL"/lib/ && ln -sf libzn_poly.so libzn_poly.dll)
     171        if [ $? -ne 0 ]; then
     172            echo >&2 "Error creating symbolic link from libzn_poly.dll to libzn_poly.so."
     173            exit 1
     174        fi
     175    fi
     176else
     177    # Darwin (MacOS X):
     178    # We now use LDFLAGS instead of the hardcoded '-m64' (for the .dylib64
     179    # target), so we don't have to differentiate here; i.e., a single
     180    # 'libzn_poly.dylib' target is sufficient for both, the extra flag (if any)
     181    # used depending on the value of LDFLAGS passed to 'configure' (which in
     182    # turn was set above, depending on the value of SAGE64).
     183    # if [ "$SAGE64" = yes ]; then
     184    #     target=libzn_poly.dylib64
     185    # else
     186    #     target=libzn_poly.dylib
     187    # fi
     188    # $MAKE $target # CC="$CC"
     189    $MAKE libzn_poly.dylib # CC="$CC"
     190    if [ ! -f libzn_poly.dylib ]; then
     191        echo >&2 "Error building zn_poly's dylib (shared library)."
     192        exit 1
     193    fi
     194    cp -f libzn_poly.dylib "$SAGE_LOCAL"/lib/
     195    if [ $? -ne 0 ]; then
     196        echo >&2 "Error copying 'libzn_poly.dylib'."
     197        exit 1
     198    fi
    101199fi
    102200
     201###############################################################################
     202# Manually install the header files:
     203###############################################################################
    103204
    104 # OS X
    105 if [ $UNAME = "Darwin" ]; then
    106     if [ "$SAGE64" = "yes" ]; then
    107       $MAKE libzn_poly.dylib64 CC=$CC
    108     else
    109       $MAKE libzn_poly.dylib CC=$CC
    110     fi
    111     if [ ! -f libzn_poly.dylib ]; then
    112         echo "Failed to build zn_poly dylib."
    113         exit 1
    114     fi
    115     $CP libzn_poly.dylib "$SAGE_LOCAL/lib/"
    116 fi
     205echo "Now installing zn_poly's header files..."
    117206
    118 # copy header files
    119 
    120 mkdir -p $SAGE_LOCAL/include/zn_poly
    121 $CP include/zn_poly.h $SAGE_LOCAL/include/zn_poly
    122 $CP include/wide_arith.h $SAGE_LOCAL/include/zn_poly
    123 
    124 
     207mkdir -p "$SAGE_LOCAL"/include/zn_poly/ &&
     208cp -f include/{zn_poly,wide_arith}.h "$SAGE_LOCAL"/include/zn_poly/
    125209if [ $? -ne 0 ]; then
    126     echo "Error building zn_poly"
     210    echo >&2 "Error installing zn_poly's header files."
    127211    exit 1
    128212fi
     213echo "Finished installing zn_poly."