On Thu, Jan 5, 2012 at 5:44 PM, Joachim Breitner <nomeata at debian.org> wrote:
>> Anyways, I’m just brainstorming
> a bit, although it seems I’m only turning up ideas that have been
> dismissed already...
It is good to hash through these things. =)
On a related note, which doesn't solve the general problem, I have been
working with Dan Peebles on a nice set of MPFR bindings for my own purposes
using custom foreign prims.
I unpacked the main MPFR structures and let the ghc garbage collector move
everything around, like it does with GMP itself.
We've been able to get a version that ALMOST works as expected. That is to
say it works perfectly unless you need to access a function that pulls from
its built-in constant cache. (MPFR internally caches the result of
computing the first n digits of pi or log of 2, etc. growing the cache as
you demand longer numbers.)
Dan was able to swap out the ghc gmp allocation hook for a slightly slower
one that checks to see if it is being called from the MPFR cache management
function, and diverting the allocation back to malloc.
Ideally we would swap the handler in an initializer when the library loads,
and this works perfectly in ghc, but not ghci -- which apparently links in
libraries in a way where c++ style initializers don't get invoked?
A 'replaceAllocator' IO action that swaps the gmp allocation hook isn't a
very Haskelly solution either, because I'd prefer to just have it look like
another numeric type.
Dan is currently investigating including a patched copy of MPFR in the
haskell package, which doesn't try to use the built-in allocator for the
constant cache.
This is where it becomes relevant to the discussion at hand, because it
would effectively involve linking in our own copy of MPFR, making
distributions unhappy.
But another option would be to unsafePerformIO that initializer, which
would add a bit of overhead, going through an indirection to make sure that
replaceAllocator had been forced, perhaps it wouldn't be too bad:
Something like:
replaceAllocator :: ()
replaceAllocator = unsafePerformIO replaceAllocatorIO
{-# NOINLINE replaceAllocator #-}
instance (Rounding r, Precision p) => Floating (Fixed r p) where
pi = replaceAllocator `pseq` mpfr_pi ...
This doesn't address general purpose use of third party libraries that
happen to internally rely upon GMP, however.
Or rather, if it does, the methodology it would lead to would be one of
bringing over all of their internals into Haskell. ;)
-Edward Kmett
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/glasgow-haskell-users/attachments/20120109/23600dab/attachment.htm>