-
Notifications
You must be signed in to change notification settings - Fork 230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow linking with gmp instead of mpir #285
Comments
I've started a branch for this work at https://github.com/DanGrayson/M2/tree/use-native-gmp-mpfr-pari . But it's complicated! Basically, we are forced to let libgmp use malloc instead of continuing to tell it to use GC_malloc, which we need to do so our top level objects get garbage collected. |
I was wondering about this. For instance, frobby also uses gmp integers, inside of c++ data structure memory which, I think, gc is not aware of (having been called through malloc or new). For the part of frobby we use, I think it is not an issue, but if we try to use the rest, it is. This gmp allocation issue has been thorny for a long time!
|
I'm assuming that libgc cannot find thread local storage created with the __thread compiler keyword, but I could be wrong. Thread safe 3rd party libraries (such as pari) will use this. (Actually, pari comes in a non-gmp flavor, too.) So we cannot force them to use GC_malloc. Also, we can't set the gmp allocation functions on the fly, because that info is stored in global variables. (Pari sets them on the fly, which makes the gmp version of pari not thread safe, despite what pari documentation says.) |
In order to maximize the number of native or homebrew-supplied libraries we can use under Mac OS X, it seems we should compile with clang and clang++, to match what the libraries are compiled with. So I'm trying that now. |
The clang provided with mac is way too old, I think. Perhaps with the latest Xcode it is OK, but this is a bit of a problem.
|
How do you compare ages of clang?
|
I think the only way to fix these issue is to stop setting the GMP memory allocation functions (using |
Another option, possibly a bad one, is to use mpn routines at top level (for M2) and do memory allocation ourselves. mpn routines, I think, do no memory allocation. How many gmp functions do you/we interface to?
|
I think that won't work, because it's not just us using GMP routines. On Mon, Jun 8, 2015 at 7:46 PM Mike Stillman notifications@github.com
|
Hmm, I take that back... let me think about it. |
I was thinking that all engine objects should be finalized too. Then I can avoid (extra) garbage collection issues in the engine.
|
There are lots of engine objects that might contain pointers to GMP Another option would be to copy the array of limbs in every GMP integer On Mon, Jun 8, 2015 at 8:10 PM Mike Stillman notifications@github.com
|
Engine objects, once finalized, can have destructors free the gmp integers (and that is done for finalized objects now) How much would the limb switch slow things down in the front end? Maybe not so much? On Jun 8, 2015, at 8:54 PM, Daniel R. Grayson notifications@github.com wrote:
|
It might be too confusing to have GMP integers floating about, some of On Mon, Jun 8, 2015 at 8:58 PM Mike Stillman notifications@github.com
|
That is true, but what we do now is also very confusing, and we have spent a lot of time trying to get the logic of it right. And if we can’t modify library code, then we need to change what we do anyway, it seems. If all of the engine integers in use come from malloc, and all the front end ones come from GC_malloc, we should be ok, as long as when you pass the engine a gmp int, the engine considers it const (which I do now anyway). And when the engine wants to hand one to the front end, there could be a routine to create one (I think the number of cases for these two is quite small).
|
Well, I think what I'm currently trying is less confusing, because remembering to convert the malloced GMP to the GCmalloced GMP will be difficult. See https://github.com/DanGrayson/M2/blob/64e2d6129451ee4d496043411b2839d38a688213/M2/Macaulay2/e/x-relem.cpp#L558 , for example. |
These are exactly the routines that need to be rewritten, if we change to doing gmp both with malloc and GC_malloc. And it would be easy to do so. (There are a few more like this, as we do the same for gmp int’s too). If you want, I can can check for other changes that would be required.
|
This is not for 1.8 though.
|
Right, not for 1.8. I think you don't treat GMP numbers from the engine as read only. For example, try changing mpz_ptr to mpz_srcptr in
|
Re: "These are exactly the routines that need to be rewritten" "These"? |
I just checked the "from_int" routines, and they all consider their argument read only. I am probably using the wrong type, so that changing one type notation to mpz_srcptr can't work, as I would need to change all the locations where from_int is used too. Perhaps I should do that. So in fact, none of these functions (the others refer to the "from_rational" functions) would need to be rewritten. |
That's probably a good idea in any case. I'll try it. On Tue, Jun 9, 2015 at 8:24 AM Mike Stillman notifications@github.com
|
I successfully changed many of your routines to accepting |
Re: "Another option, possibly a bad one, is to use mpn routines at top level (for M2) and do memory allocation ourselves. mpn routines, I think, do no memory allocation." The mpfr library uses also mpz routines, and doesn't provide an interface to avoid that. |
Even if Debian did include mpir, I don't think using the Macaulay2 patched version would be ideal, as other applications built using mpir might want to set the memory functions. So we'd have the same problem as gmp. |
I've sent a note about this issue to the pari dev mailing list. [1] Maybe that will solve it! [1] http://pari.math.u-bordeaux.fr/archives/pari-dev-1605/msg00003.html |
@d-torrance : I presume the MPIR patch can be converted to a proper runtime feature, that can be accepted by upstream. |
I got a nice quick reply from the pari devs [1]! Basically, they propose adding an additional flag which could be passed to pari_init_opts() which would skip the kernel initialization (and thus skip overwriting the gmp memory functions). [1] http://pari.math.u-bordeaux.fr/archives/pari-dev-1605/msg00004.html |
I got another response from the pari devs [1]. They suggest a wrapper around the call to pari_init_opts() saving the gmp memory functions. I'll play around with this and see if it works for the Debian package. If so, I'll submit a pull request. [1] http://pari.math.u-bordeaux.fr/archives/pari-dev-1605/msg00005.html |
Actually, the PARI devs bring up their #1317 which had to do with an analogous issue with Sagemath using PARI and MPIR at the same time. This suggest that M2 could use an analogous wrapper around PARI initialisation to achieve the same effect, and remove MPIR patch. |
here is what Sage does (not a wrapper, in fact): right after calling In the M2 case, I guess that the function to free memory should not do anything. |
f6e2f61 at https://github.com/DanGrayson/M2/ is Dan's implementation of this for M2, and it actually works! |
Oops, I removed that branch from DanGrayson/M2 and put it on Macaulay2/M2, see https://github.com/Macaulay2/M2/tree/try-not-patching-mpir -- it's progressed a bit since then. There are bugs, though. |
By "bugs" do you mean the same sort of memory errors, i.e. more libraries do mess around with MPIR/GMP memory allocators? Or is it something else? |
We're getting many calls to "abort()" from "free()" complaining about pointers to memory not obtained with "malloc()". It happens inside ntl. |
Sage applies the following patch to NTL: https://github.com/sagemath/sage/blob/master/build/pkgs/ntl/patches/new_singular.patch (replacing Without this, Sage gets a problem with (lib)Singular... That is to say that perhaps |
That can't be it, because the calls to abort() happen only if I strip M2-binary. |
I will be at the workshop around 10am, hope to have a closer look then.
|
A possible update: I finally got around to sending a backtrace to the PARI devs of where the M2 build fails when using the Debian GMP package, and they replied saying that there was a possible bug in PARI [1]. I tried building M2 again after making a small change in the PARI code, and it worked! (Well, for a moment. Then I ran into #460...) [1] https://pari.math.u-bordeaux.fr/archives/pari-dev-1706/msg00010.html |
Is this resolved now? |
@d-torrance should know all about it, I believe. |
Yes, linking with gmp works beautifully now! |
No description provided.
The text was updated successfully, but these errors were encountered: