From: nisse@lysator.liu.se (Niels Möller)
To: 10519@debbugs.gnu.org
Cc: Torbjorn Granlund <tg@gmplib.org>
Subject: bug#10519: guile and (mini-)gmp
Date: Sun, 15 Jan 2012 22:22:16 +0100 [thread overview]
Message-ID: <nnmx9oy83b.fsf@stalhein.lysator.liu.se> (raw)
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 <gmp.h> 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 <gmp.h> 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 <limits.h> 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 <= 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.
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="-lgc" and
BDW_GC_CFLAGS="", 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
--
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.
next reply other threads:[~2012-01-15 21:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-15 21:22 Niels Möller [this message]
2012-01-16 10:19 ` bug#10519: guile and (mini-)gmp Mark H Weaver
2012-01-16 14:06 ` Niels Möller
2012-01-16 19:21 ` Mark H Weaver
2012-01-28 9:49 ` Niels Möller
2012-01-28 10:10 ` Mark H Weaver
2012-07-22 9:04 ` Ludovic Courtès
2012-02-03 13:40 ` Andy Wingo
2012-02-03 19:56 ` Niels Möller
2012-02-03 20:01 ` Torbjorn Granlund
2012-02-04 22:46 ` Ludovic Courtès
2012-07-22 9:00 ` Ludovic Courtès
2012-07-22 23:17 ` Niels Möller
2012-08-10 21:51 ` Ludovic Courtès
2012-08-11 9:37 ` Niels Möller
2012-08-11 19:46 ` Ludovic Courtès
2012-08-11 21:50 ` Niels Möller
2012-08-11 22:48 ` Ludovic Courtès
2013-03-02 20:04 ` Andy Wingo
2013-03-02 20:58 ` Mark H Weaver
2013-03-05 19:09 ` Mark H Weaver
2013-03-18 0:01 ` Mark H Weaver
2013-03-18 9:19 ` Ludovic Courtès
2013-03-26 8:17 ` Niels Möller
2013-03-27 17:00 ` Mark H Weaver
2016-10-27 12:29 ` Niels Möller
2016-11-10 19:56 ` Andy Wingo
2013-03-02 21:45 ` Niels Möller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=nnmx9oy83b.fsf@stalhein.lysator.liu.se \
--to=nisse@lysator.liu.se \
--cc=10519@debbugs.gnu.org \
--cc=tg@gmplib.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).