RE: GHCI/FFI/GMP/Me madness

2004-08-13 Thread Simon Marlow
On 13 August 2004 14:04, Remi Turk wrote:

 How do you arrange to free a GMP integer when it is no longer
 referenced from the heap?  You'd need finalizers, and that way lies
 madness.  The memory allocation tricks we play with GMP are all to
 support GC of Integers.
 
 Errr, I guess I'll have to start looking for a straitjacket then ;)
 Finalisers where exactly what I was thinking about, and though
 below implementation without doubt contains a bunch of bugs,
 perhaps even show-stoppers, the following code _does_ print True:
 
 import Mpz
 
 main= print $ show (z::Integer) == show (z::Mpz)
 where
 -- some random calculations
 x, y, z :: Blub a = a
 x   = 2^64 - sum (take 100 $ iterate (63*) 3)
 y   = 3^200 * 234233432 - (34 `pow` 38) + sum [1,87..2]
 z   = fac 5000 * (x + y) `div` (2^100)
 
 Or are finalisers simply going to be too slow to take seriously
 for this?

You can't use mallocForeignPtr (because GMP needs to allocate its own
memory), so you have to use full-blown ForeignPtrs with malloc/free and
finalizers.  Yes, these are very slow compared to using GC'd memory.

Cheers,
Simon

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: GHCI/FFI/GMP/Me madness

2004-08-12 Thread Simon Marlow
On 11 August 2004 20:45, Remi Turk wrote:

 But as long as GMP doesn't mind about being abused the way my
 most recent util.c does, I can get away with the
 mp_set_memory_functions-trick, can't I?

Not really.  You can't let GMP realloc() a memory block that was
allocated using one method, with a different method.  Also, GMP must not
try to free() a block that was allocated using a different method.  

 (*Be sure to call `mp_set_memory_functions' only when there are no
 active GMP objects allocated using the previous memory functions!
 Usually that means calling it before any other GMP function.*,
 and using undocumented features)
 
 And with this trick and a ffi GMP-binding implement a working Mpz
 datatype.
 
 And when (if?) this is done, drop in a type Mpz = Integer, rip
 out all Integer-primops, remove the mp_set_memory_functions-trick
 and start benchmarking?
 (Conveniently forgetting that fromInteger :: Integer - Integer
 most certainly has to stay a primop anyway...)

How do you arrange to free a GMP integer when it is no longer referenced
from the heap?  You'd need finalizers, and that way lies madness.  The
memory allocation tricks we play with GMP are all to support GC of
Integers.

 Or is the rts using Integers in such a way that any (standard
 malloc) allocations are forbidden while e.g. (*) :: Integer -
 Integer - Integer is running?

Not sure what you mean here - malloc() can always be used.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: GHCI/FFI/GMP/Me madness

2004-08-11 Thread Simon Marlow
On 10 August 2004 16:04, Remi Turk wrote:

   - reset GMP's memory allocators before calling it from your code,
 and set them back to the RTS allocators afterward.  Slow, but it
 should work.  It doesn't solve the problem properly though:
 external libraries which use GMP are still broken.
 It does indeed seem to work, after a quick test. (new util.c attached)
 
 And it does solve _my_ immediate problem: I can surround every
 gmp-operation with a gmp_begin()/gmp_end() and pretend to be
 happy. (and anyway, I'm just messing around, failure merely means
 I've got yet another unfinished project ;))
 
 Part of the reason for all this messy FFIing is your post:

http://www.haskell.org/pipermail/glasgow-haskell-users/2004-June/006767.
html

Hmm yes, I now realise that it's not quite as easy as I implied in that
message.  The problem is the memory allocation.  If a GMP function
allocates some memory, we have to swizzle the pointer that comes back
(where swizzle(p) { return p-sizeof(StgArrWords) }).  Unfortunately you
have to do this without giving the GC a chance to run, and there's no
way to get this atomicity in plain Haskell+FFI, which is why the primops
are still necessary.

Perhaps one way to do it would be to define generic Integer primop
wrappers - i.e. one wrapper for an mpz function that takes two arguments
and returns one, etc.  The primop implementations already work like
this, except that the wrappers are CPP macros.  If the wrapper were
lifted to the level of a primop itself, then you could easily use
different mpz functions by calling the appropriate primop passing the
address of the mpz function.

Cheers, 
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-11 Thread Remi Turk
On Wed, Aug 11, 2004 at 02:27:19PM +0100, Simon Marlow wrote:
 On 10 August 2004 16:04, Remi Turk wrote:
  http://www.haskell.org/pipermail/glasgow-haskell-users/2004-June/006767.html
 
 Hmm yes, I now realise that it's not quite as easy as I implied in that
 message.  The problem is the memory allocation.  If a GMP function
 allocates some memory, we have to swizzle the pointer that comes back
 (where swizzle(p) { return p-sizeof(StgArrWords) }).  Unfortunately you
 have to do this without giving the GC a chance to run, and there's no
 way to get this atomicity in plain Haskell+FFI, which is why the primops
 are still necessary.
 
 Perhaps one way to do it would be to define generic Integer primop
 wrappers - i.e. one wrapper for an mpz function that takes two arguments
 and returns one, etc.  The primop implementations already work like
 this, except that the wrappers are CPP macros.  If the wrapper were
 lifted to the level of a primop itself, then you could easily use
 different mpz functions by calling the appropriate primop passing the
 address of the mpz function.

Ah, the shockingly inefficient family of GMP_TAKEx_RETy macros ;)
(I understand the swizzle-talk only partly, so I'll ignore it and
hope my words won't turn out to be utter nonsense..)

But as long as GMP doesn't mind about being abused the way my
most recent util.c does, I can get away with the
mp_set_memory_functions-trick, can't I?
(*Be sure to call `mp_set_memory_functions' only when there are no
active GMP objects allocated using the previous memory functions!
Usually that means calling it before any other GMP function.*,
and using undocumented features)

And with this trick and a ffi GMP-binding implement a working Mpz
datatype.

And when (if?) this is done, drop in a type Mpz = Integer, rip
out all Integer-primops, remove the mp_set_memory_functions-trick
and start benchmarking?
(Conveniently forgetting that fromInteger :: Integer - Integer
most certainly has to stay a primop anyway...)

Or is the rts using Integers in such a way that any (standard
malloc) allocations are forbidden while e.g. (*) :: Integer -
Integer - Integer is running?

 Cheers,   
   Simon

Greetings,
Remi

-- 
Nobody can be exactly like me. Even I have trouble doing it.
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: GHCI/FFI/GMP/Me madness

2004-08-10 Thread Simon Marlow
On 09 August 2004 16:57, Remi Turk wrote:

 On Sun, Aug 08, 2004 at 07:34:04AM -0700, Sigbjorn Finne wrote:
 Hi,
 
 please be aware that the RTS uses GMP as well, and upon
 initialisation it sets GMP's 'memory functions' to allocate memory
 from the RTS' heap. So, in the code below, the global variable
 'p' will end up having components pointing into the heap.
 Which is fine, until a GC occurs and the pointed-to
 GMP allocated value is eventually stomped on by the storage
 manager for some other purpose.
 
 I'm _guessing_ that's the reason for the behaviour you're seeing.
 
 Hm, I _was_ aware of mp_set_memory_functions being used by the RTS.
 I've seen it often enough in ltrace's ;)
 It does indeed sound rather plausible (and making big allocations
 and such does indeed cause it to happen earlier).
 
 At which point my next question is: what now? I don't feel really
 confident about my GHC-hacking skills (huh? skills? where? ;) so
 does that mean I'm out of luck?
 *looks* Am I correct that I'd have to copy any GMP-allocated
 memory to my own memory before returning from C and vice-versa?
 I hope not :(

GHC's use of GMP does cause problems if you want to use GMP for your own
purposes, or if you link with external code that wants to use GMP.  The
real problem is that GMP has internal state, which means it can't be
used in a modular way.  But there's not much we can do about that.

Possibilities:

  - Rename all the symbols in our GMP to be unique. (sounds hard)

  - Replace GMP with something else (someone is working on this, 
I believe).

  - try to get two copies of GMP into your program by pre-linking
the RTS with one copy, then linking the rest of the program
with the other copy.  I'm being intentionally vague here - I
feel that this ought to be possible, but it's an ugly hack
at best.

  - reset GMP's memory allocators before calling it from your code,
and set them back to the RTS allocators afterward.  Slow, but it
should work.  It doesn't solve the problem properly though: external
libraries which use GMP are still broken.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: GHCI/FFI/GMP/Me madness

2004-08-10 Thread Simon Marlow
On 10 August 2004 13:03, MR K P SCHUPKE wrote:

 Re GMP, Why not provide more GMP functions as primitives on the
 Integer type, and avoid the need to call out to GMP via the FFI?

Show us the code! :-p

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-10 Thread Carsten Schultz
Hi!

On Tue, Aug 10, 2004 at 12:59:46PM +0100, Simon Marlow wrote:
 On 09 August 2004 16:57, Remi Turk wrote:
 
  Hm, I _was_ aware of mp_set_memory_functions being used by the RTS.
  I've seen it often enough in ltrace's ;)
  It does indeed sound rather plausible (and making big allocations
  and such does indeed cause it to happen earlier).
  
  At which point my next question is: what now? I don't feel really
  confident about my GHC-hacking skills (huh? skills? where? ;) so
  does that mean I'm out of luck?
  *looks* Am I correct that I'd have to copy any GMP-allocated
  memory to my own memory before returning from C and vice-versa?
  I hope not :(
 
 GHC's use of GMP does cause problems if you want to use GMP for your own
 purposes, or if you link with external code that wants to use GMP.  The
 real problem is that GMP has internal state, which means it can't be
 used in a modular way.  But there's not much we can do about that.
 
 Possibilities:
 
[...]
   - reset GMP's memory allocators before calling it from your code,
 and set them back to the RTS allocators afterward.  Slow, but it
 should work.  It doesn't solve the problem properly though: external
 libraries which use GMP are still broken.

I would be careful though:

http://www.swox.com/gmp/manual/Custom-Allocation.html

   Be sure to call mp_set_memory_functions only when there are no
   active GMP objects allocated using the previous memory functions!
   Usually that means calling it before any other GMP function.

Greetings,

Carsten

-- 
Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin
http://carsten.codimi.de/
PGP/GPG key on the pgp.net key servers, 
fingerprint on my home page.


pgpHRM263ZIUM.pgp
Description: PGP signature
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-10 Thread Alastair Reid

   - Rename all the symbols in our GMP to be unique. (sounds hard)

Nah, easy.

First get a list of symbols: nm libgmp.a | grep gmp
  [Supply a few flags to nm to get a better list.]

Then turn it into a list of #defines:

  #define gmp_blah ghc_gmp_blah
  ...

#include your list of #defines into some header file that everyone eats.

make clean; make


You can generate the list by hand or have it rebuilt by make every time.

--
Alastair Reid
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: GHCI/FFI/GMP/Me madness

2004-08-10 Thread Simon Marlow
On 10 August 2004 14:08, Alastair Reid wrote:

   - Rename all the symbols in our GMP to be unique. (sounds hard)
 
 Nah, easy.
 
 First get a list of symbols: nm libgmp.a | grep gmp
   [Supply a few flags to nm to get a better list.]
 
 Then turn it into a list of #defines:
 
   #define gmp_blah ghc_gmp_blah
   ...
 
 #include your list of #defines into some header file that everyone
 eats. 
 
 make clean; make
 
 
 You can generate the list by hand or have it rebuilt by make every
 time. 

Hmmm... well maybe.  We'd have to be sure to always use the version of
GMP that comes with GHC - currently we use an installed dynamic version
if one is available.  Statically linking GMP runs into licensing
problems, so I'd have to figure out how to build it dynamically.

The native codegen has to use the revised names, too.  (the #defines
won't work there because it mentions the names inside strings).

I'd bet there are almost certainly some other gotchas.

Cheers,
SImon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-10 Thread Remi Turk
On Tue, Aug 10, 2004 at 12:59:46PM +0100, Simon Marlow wrote:
 GHC's use of GMP does cause problems if you want to use GMP for your own
 purposes, or if you link with external code that wants to use GMP.  The
 real problem is that GMP has internal state, which means it can't be
 used in a modular way.  But there's not much we can do about that.
 
 Possibilities:
 
   - Rename all the symbols in our GMP to be unique. (sounds hard)
and ugly

   - Replace GMP with something else (someone is working on this, 
 I believe).
Do you have a pointer? It sounds interesting. *see below*

   - try to get two copies of GMP into your program by pre-linking
 the RTS with one copy, then linking the rest of the program
 with the other copy.  I'm being intentionally vague here - I
 feel that this ought to be possible, but it's an ugly hack
 at best.
I'm not sure I share your feelings about that ;) It sounds like
symbol-clash-hell. But quite possibly I'm just being ignorant.

   - reset GMP's memory allocators before calling it from your code,
 and set them back to the RTS allocators afterward.  Slow, but it
 should work.  It doesn't solve the problem properly though: external
 libraries which use GMP are still broken.
It does indeed seem to work, after a quick test. (new util.c attached)

And it does solve _my_ immediate problem: I can surround every
gmp-operation with a gmp_begin()/gmp_end() and pretend to be
happy. (and anyway, I'm just messing around, failure merely means
I've got yet another unfinished project ;))

Part of the reason for all this messy FFIing is your post:
http://www.haskell.org/pipermail/glasgow-haskell-users/2004-June/006767.html

If Integers where implemented via the FFI that would make it
quite a bit easier to special-case e.g. (^) and Show for Integer.
(IIRC, GMP's mpz-to-string recently got a huge speedup, it would
be nice if GHC would automagically profit of that..)

 Cheers,
   Simon
 

Happy hacking  keep up the good work ;)
Remi

-- 
Nobody can be exactly like me. Even I have trouble doing it.
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-10 Thread Remi Turk
On Tue, Aug 10, 2004 at 01:09:03PM +0100, Simon Marlow wrote:
 On 10 August 2004 13:03, MR K P SCHUPKE wrote:
 
  Re GMP, Why not provide more GMP functions as primitives on the
  Integer type, and avoid the need to call out to GMP via the FFI?
 
 Show us the code! :-p

Or implement Integers via the FFI, and make it much easier to
provide more GMP functions as primitives (that is: simple
foreign imports)

Which is what I was trying, until I bumped into those weird
memory problems I had almost forgotten existed ;)

-- 
Nobody can be exactly like me. Even I have trouble doing it.
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-09 Thread Remi Turk
On Sun, Aug 08, 2004 at 07:34:04AM -0700, Sigbjorn Finne wrote:
 Hi,
 
 please be aware that the RTS uses GMP as well, and upon
 initialisation it sets GMP's 'memory functions' to allocate memory
 from the RTS' heap. So, in the code below, the global variable
 'p' will end up having components pointing into the heap.
 Which is fine, until a GC occurs and the pointed-to
 GMP allocated value is eventually stomped on by the storage
 manager for some other purpose.
 
 I'm _guessing_ that's the reason for the behaviour you're seeing.

Hm, I _was_ aware of mp_set_memory_functions being used by the RTS.
I've seen it often enough in ltrace's ;)
It does indeed sound rather plausible (and making big allocations
and such does indeed cause it to happen earlier).

At which point my next question is: what now? I don't feel really
confident about my GHC-hacking skills (huh? skills? where? ;) so
does that mean I'm out of luck?
*looks* Am I correct that I'd have to copy any GMP-allocated
memory to my own memory before returning from C and vice-versa?
I hope not :(

Happy hacking,
Remi 3212th unfinished project Turk

-- 
Nobody can be exactly like me. Even I have trouble doing it.
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-09 Thread Tomasz Zielonka
On Sun, Aug 08, 2004 at 07:34:04AM -0700, Sigbjorn Finne wrote:
 Hi,
 
 please be aware that the RTS uses GMP as well, and upon
 initialisation it sets GMP's 'memory functions' to allocate memory
 from the RTS' heap.

What about linking Haskell programs with C libraries that use GMP
internally? Can it cause similar problems?

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-09 Thread Abraham Egnor
FWIW, I couldn't reproduce this problem on my system (i.e. str_test
always printed 1).  GHC 6.2.1, libgmp 4.1.3, debian unstable

Abe

On Mon, 9 Aug 2004 17:57:14 +0200, Remi Turk [EMAIL PROTECTED] wrote:
 On Sun, Aug 08, 2004 at 07:34:04AM -0700, Sigbjorn Finne wrote:
  Hi,
 
  please be aware that the RTS uses GMP as well, and upon
  initialisation it sets GMP's 'memory functions' to allocate memory
  from the RTS' heap. So, in the code below, the global variable
  'p' will end up having components pointing into the heap.
  Which is fine, until a GC occurs and the pointed-to
  GMP allocated value is eventually stomped on by the storage
  manager for some other purpose.
 
  I'm _guessing_ that's the reason for the behaviour you're seeing.
 
 Hm, I _was_ aware of mp_set_memory_functions being used by the RTS.
 I've seen it often enough in ltrace's ;)
 It does indeed sound rather plausible (and making big allocations
 and such does indeed cause it to happen earlier).
 
 At which point my next question is: what now? I don't feel really
 confident about my GHC-hacking skills (huh? skills? where? ;) so
 does that mean I'm out of luck?
 *looks* Am I correct that I'd have to copy any GMP-allocated
 memory to my own memory before returning from C and vice-versa?
 I hope not :(
 
 Happy hacking,
 Remi 3212th unfinished project Turk
 
 
 
 --
 Nobody can be exactly like me. Even I have trouble doing it.
 ___
 Glasgow-haskell-users mailing list
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-09 Thread Remi Turk
On Mon, Aug 09, 2004 at 01:09:40PM -0400, Abraham Egnor wrote:
 FWIW, I couldn't reproduce this problem on my system (i.e. str_test
 always printed 1).  GHC 6.2.1, libgmp 4.1.3, debian unstable
 
 Abe

Same versions here, on an old heavily-patched/FUBAR rock linux
1.4 system.

Does the following make any difference? (trying to cause GCing)

Haskell/Mpz/weird% make
ghci util.o -#include util.h PrimMpz.hs
   ___ ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |  GHC Interactive, version 6.2.1, for Haskell 98.
/ /_\\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package base ... linking ... done.
Loading object (static) util.o ... done
final link ... done
Compiling Main ( PrimMpz.hs, interpreted )
Ok, modules loaded: Main.
*Main mpz_new
*Main sum (replicate (200*1000) 0)
0
*Main str_test
1076535944
*Main 


Groeten,
Remi

-- 
Nobody can be exactly like me. Even I have trouble doing it.
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHCI/FFI/GMP/Me madness

2004-08-08 Thread Sigbjorn Finne
Hi,

please be aware that the RTS uses GMP as well, and upon
initialisation it sets GMP's 'memory functions' to allocate memory
from the RTS' heap. So, in the code below, the global variable
'p' will end up having components pointing into the heap.
Which is fine, until a GC occurs and the pointed-to
GMP allocated value is eventually stomped on by the storage
manager for some other purpose.

I'm _guessing_ that's the reason for the behaviour you're seeing.

--sigbjorn

- Original Message - 
From: Remi Turk [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Sunday, August 08, 2004 05:52
Subject: GHCI/FFI/GMP/Me madness


 [second attempt, this time from my bulk mailinglist address
  instead of the normal one.]

 Hi all,

 I recently tried to create a ffi-binding to gmp in ghc, and
 failed miserably. After a few days of debugging, simplifying the
 code and tearing my hear out, I'm slightly completely stumped,
 and crying for help ;)

 In short: calling gmp-functions from GHCI *with a prompt between*
 them seems to do Really Bad Things. (read: memory corruption)


 The long story:
 ---

 mpz_t p;

 str_test()
 {
 gmp_printf(%Zd\n, p);
 }

 void mpz_new()
 {
 mpz_init_set_si(p, 1);
 }

 foreign import ccall mpz_new:: IO ()
 foreign import ccall str_test   :: IO ()


 Prelude Main mpz_new
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 1
 Prelude Main str_test
 142833060
 Prelude Main str_test
 142833060


 Using other flags, importing extra modules, using CVS 6.3 (a few
 weeks old) or not compiling it before loading it in GHCI slightly
 changes the symptoms (other wrong numbers or make it happen
 later/earlier) but copypasting the code from main some 10 to 20
 times seems to be a sure way to reproduce it.

 Simply running main doesn't seem to expose the problem.
 Now of course, GHCI uses Integer-ops during it's REPL, which I
 suspect is exactly what causes/exposes the problem.

 Am I doing (Un)Officially Forbidden Things? Is it time for a
 bug-report? Do I finally have to learn drinking coffee? ;)
 I'd be delighted to know.

 The full code is attached.

 TIA,
 Remi

 -- 
 Nobody can be exactly like me. Even I have trouble doing it.







 ___
 Glasgow-haskell-users mailing list
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users