From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: nisse@lysator.liu.se (Niels =?UTF-8?Q?M=C3=B6ller?=) Newsgroups: gmane.lisp.guile.bugs Subject: bug#10519: guile and (mini-)gmp Date: Sun, 15 Jan 2012 22:22:16 +0100 Message-ID: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: dough.gmane.org 1326674308 23571 80.91.229.12 (16 Jan 2012 00:38:28 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 16 Jan 2012 00:38:28 +0000 (UTC) Cc: Torbjorn Granlund To: 10519@debbugs.gnu.org Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Mon Jan 16 01:38:19 2012 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1RmaaX-0005bS-Ex for guile-bugs@m.gmane.org; Mon, 16 Jan 2012 01:38:17 +0100 Original-Received: from localhost ([::1]:49972 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RmaaW-0007Ho-V9 for guile-bugs@m.gmane.org; Sun, 15 Jan 2012 19:38:16 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:40881) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RmY7a-0007FF-E9 for bug-guile@gnu.org; Sun, 15 Jan 2012 17:00:15 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RmY7Y-0005hP-KR for bug-guile@gnu.org; Sun, 15 Jan 2012 17:00:14 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:36047) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RmY7Y-0005hE-F6 for bug-guile@gnu.org; Sun, 15 Jan 2012 17:00:12 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1RmY8M-0001VC-G6 for bug-guile@gnu.org; Sun, 15 Jan 2012 17:01:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: nisse@lysator.liu.se (Niels =?UTF-8?Q?M=C3=B6ller?=) Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-guile@gnu.org Resent-Date: Sun, 15 Jan 2012 22:01:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 10519 X-GNU-PR-Package: guile X-GNU-PR-Keywords: X-Debbugs-Original-To: bug-guile@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.13266648305734 (code B ref -1); Sun, 15 Jan 2012 22:01:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 15 Jan 2012 22:00:30 +0000 Original-Received: from localhost ([127.0.0.1]:58953 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RmY7p-0001UQ-AS for submit@debbugs.gnu.org; Sun, 15 Jan 2012 17:00:30 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:52997) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RmXXm-0000YN-Kp for submit@debbugs.gnu.org; Sun, 15 Jan 2012 16:23:17 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RmXWw-0000vR-Ma for submit@debbugs.gnu.org; Sun, 15 Jan 2012 16:22:24 -0500 Original-Received: from lists.gnu.org ([140.186.70.17]:46305) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RmXWw-0000vN-L5 for submit@debbugs.gnu.org; Sun, 15 Jan 2012 16:22:22 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:58127) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RmXWv-0003xV-7i for bug-guile@gnu.org; Sun, 15 Jan 2012 16:22:22 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RmXWt-0000vB-FL for bug-guile@gnu.org; Sun, 15 Jan 2012 16:22:21 -0500 Original-Received: from mail.lysator.liu.se ([130.236.254.3]:34004) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RmXWt-0000v7-6r for bug-guile@gnu.org; Sun, 15 Jan 2012 16:22:19 -0500 Original-Received: from mail.lysator.liu.se (localhost [127.0.0.1]) by mail.lysator.liu.se (Postfix) with ESMTP id C50054000A; Sun, 15 Jan 2012 22:22:16 +0100 (CET) Original-Received: from stalhein.lysator.liu.se (stalhein.lysator.liu.se [IPv6:2001:6b0:17:f0a0::cc]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.lysator.liu.se (Postfix) with ESMTPS id B729240009; Sun, 15 Jan 2012 22:22:16 +0100 (CET) Original-Received: from stalhein.lysator.liu.se (localhost [127.0.0.1]) by stalhein.lysator.liu.se (8.14.4+Sun/8.14.4) with ESMTP id q0FLMGte003197; Sun, 15 Jan 2012 22:22:16 +0100 (MET) Original-Received: (from nisse@localhost) by stalhein.lysator.liu.se (8.14.4+Sun/8.14.4/Submit) id q0FLMGTq003196; Sun, 15 Jan 2012 22:22:16 +0100 (MET) X-Authentication-Warning: stalhein.lysator.liu.se: nisse set sender to nisse@lysator.liu.se using -f User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (usg-unix-v) X-Virus-Scanned: ClamAV using ClamSMTP X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Mailman-Approved-At: Sun, 15 Jan 2012 17:00:27 -0500 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-Mailman-Approved-At: Sun, 15 Jan 2012 19:38:14 -0500 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Original-Sender: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.bugs:6041 Archived-At: Hi, I'm hacking on something called "mini-gmp" (see http://gmplib.org:8000/mini-gmp/). This is inteded to be a small and simple implementation of a GMP subset, suitable for programs which needs bignums, but which don't use very large numbers or very high performance. (I aimed for mini-gmp.c to be smaller than gmp's configure.in; currently, mini-gmp.c is some 10% larger). In part, this work was triggered by a discussion on how guile's gmp dependency is causing problems for programs using guile as an extension language, but which don't have any particular bignum needs. And I think minimality in terms of both dependencies and size of "core guile" is pretty important for guile to be successful as an extension language. One way to use mini-gmp, which I think would be appropriate for guile, is to bundle mini-gmp with the guile sources, and use it as a fallback in case the real GMP is not available. To try that out, I'm working with a slightly patched guile: I copied mini-gmp.c and .h to the libguile directory. configure.ac: Don't fail if gmp is not present, instead just add mini-gmp.o to LIBOBJS. And add an option --disable-gmp, to always use the bundled mini-gmp. Other files: #include only when HAVE_LIBGMP is defined, and fall back to including "mini-gmp.h" otherwise. I'm then compiling guile to see how far I get and solve the problems I find. **End of background** I'm now going to describe a few of the problems. 1. The header file libguile.h. As far as I understand, this is a public header file and it's use of means that the public guile ABI depends on gmp. Since mini-gmp is not binary compatible, that probably makes it more or less impossible to *install* guile when built with mini-gmp. The remaining case is an applications which bundle guile for using it as an extension language. Wnen the real gmp is unavailable, they still need a libguile.h which somehow includes mini-gmp.h rather than gmp.h. One solution might be to not modify include directives, but instead have configure create some symlink gmp.h -> mini-gmp.h in the build directory (to make --disable-gmp work, that directory must come before system directories where the real gmp-h file may be installed). The same directory also must be in the include path when building the application wanting to use guile. 2. The next problem is maybe more a nuisance than a real problem. I'm looking at scm_i_big2dbl, in numbers.c. I notice this code doesn't currently use mpz_get_d (comment says that's because gmp-4.2 and earlier didn't do well-defined rounding). Next, mpz_get_d in current gmp rounds towards zero. guile wants rounding to nearest, and it arranges this by testing the next lower bit. Unfortunately, it can't use mpz_tstbit directly, since for negative values it needs the bit of the abolute value, not of the two's complement. The code instead uses mpz_getlimbn and GMP_NUMB_BITS. That's not an unreasonable way to do it, but it causes problems for me because mini-gmp.h doesn't declare GMP_NUMB_BITS (and can't do, without including for CHAR_BIT, which is somewhat undesirable in the interface definition header, or use autoconf, which I'd really like to avoid here. Maybe I have to bite the bullet and define these constants (in mini-gmp, the correct value for both GMP_LIMB_BITS and GMP_NUMB_BITS is CHAR_BIT * sizeof(unsigned long)). Testing the bit in the absolute value could be done as mpz_init (t); mpz_abs (t, SCM_I_BIG_MPZ(b)); ...mpz_tstbit(t, pos)... mpz_clear (t); but that's an unnecessary allocation and copy. Maybe gmp (and mini-gmp) should have a function mpz_tstbitabs (and similarly for other bitops) which ignore the sign? Or should there be some mpz_get_d-like function with configurable rounding (I imagine libmpfr interfaces could provide some inspiration)? 3. Occcasional use of mpq functions (do_divide, scm_inexact_to_exact), for conversion of fradctions to and from doubles. mini-gmp has no mpq-functions (and it shouldn't have), so these calls have to either be eliminated altogether, or be made conditional on HAVE_LIBGMP. For conversion double->fraction, mpq seems overkill: Just multiply by a power of two to make the number an integer, to construct a fraction p / 2^k, and then eliminate any common factors of two (if fractions are required to be in some canonical form). For fraction->double, I think the current code using mpq_get_d rounds towards zero rather than towards nearest, which might not be what's desired. To avoid using mpq, I think converting p/q to a double could be done as follows: Find k so that floor (2^k p / q) is precisely the right number of bits (i.e., if precicion is n bits, 2^{n-1} q <=3D 2^k p < 2^n p). Compute the 2^k p / q appropriately rounded, and convert to double. There may be some corner case when 2^k p / q to have one more bit when rounded (upward) than when truncated. 4. mini-gmp has no mp_set_memory_functions. If I understand the the conservative gc used with guile right, having mini-gmp always use plain malloc and free should not cause any errors, just a slight waste of memory in case some limbs happen to be valid pointers. Which should be a small problem since one shouldn't use mini-gmp if the numbers get large. In guile, the calls could then just be made conditional on HAVE_LIBGMP. =20 I'd apppreciate comments both on mini-gmp in general, and on the proper solution of the above issues. I may be able to prepare a few patches to guile, if I know what's desired. Ah, and I can report one build problem: The debian package of libgc doesn't include any .pc file, so when run without arguments, guile's configure failed to detect the precense of this library, even though I had the -dev package with libraries and header files installed. I figured out I should rerun configure with BDW_GC_LIBS=3D"-lgc" and BDW_GC_CFLAGS=3D"", and then the configure test passed, but -lgc for some reason wasn't added where it should in the Makefiles. I had to edit the generated libguile/Makefile and add it to LIBS there to be able to link. Happy hacking, /Niels --=20 Niels M=F6ller. PGP-encrypted email is preferred. Keyid C0B98E26. Internet email is subject to wholesale government surveillance.