From haberg-1 at telia.com Tue Feb 10 13:22:40 2015 From: haberg-1 at telia.com (Hans Aberg) Date: Tue, 10 Feb 2015 14:22:40 +0100 Subject: GMP C++11 support Message-ID: <15065D48-FCE3-48F4-9F22-F8F716650DCF@telia.com> For GMP C++11 support, there might be the following functions, x = z, q, f: For use with move constructor/assignment: void mpx_move(mpx_t x, mpx_t y); Move data from y to x, leaving y in a state so that mpx_clear() can be called or assignments be made. Hash function, for use with hash containers: std::unordered_set, std::unordered_map, etc. size_t mpx_hash(mpx_t x); Both are easy to write, but one has to go below the the GMP API. In addition, mpz_init() allocates a limb, so one would want to have inline void mpz_move(mpz_t x, mpz_t y) { x[0] = y[0]; mpz_null(y); } where inline void mpz_null(mpz_t x) { x[0]._mp_alloc = 0; x[0]._mp_size = 0; x[0]._mp_d = NULL; // Setting allocation pointer to null probably suffices. } But in this variation, one does not know if y is left in a valid GMP state - for that one has to use mpz_init() which will make an allocation that is never used (and immediately destroyed). For the hash function, one can write: size_t mpz_hash(mpz_t x) { std::size_t h = 0; for (int i = 0; i < abs(x->_mp_size); ++i) h ^= std::hash()(x->_mp_d[i]); return h; } where std::hash() merely extracts the C++ hash function for the builtin integral type that mp_limb_t represents. But then one has to go into the mpz_t type, so if the GMP implementation changes, the hash function must be changed too. GMP having its own hash maps might be more efficient, too. From tinkr at openmailbox.org Sat Feb 28 09:33:43 2015 From: tinkr at openmailbox.org (Tinker) Date: Sat, 28 Feb 2015 15:03:43 +0530 Subject: How store libGMP bigint&-ratnum:s within a parent Garbage Collected environment with movable objects so that libGMP values must be absent of any absolute pointers =?UTF-8?Q?whatsoever=3F?= Message-ID: <7ed9b115f5e8b56bdba66b4b54e9ecbc@openmailbox.org> Hi! I have a GC:ed heap wherein I want to store my libGMP bigint&-ratnum:s. This means that I provide the memory allocator, and also it means that libGMP must store one bigint/bigratnum as one single solid byte array only, i.e. one such value cannot be split up in more memory allocations, because between libGMP calls my GC changes memory location of heap objects frequently, and therefore the values may utilize no absolute memory pointers. How do I use libGMP in this way? As I see it it's extremely important that libGMP supports this, because this is the only way that a garbage collected environment. (Methods with static memory addresses for values would risk memory fragmentation, and not being exposed to that risk is the exact reason I use a GC.) Thanks! Mikael From marc.glisse at inria.fr Sat Feb 28 11:52:34 2015 From: marc.glisse at inria.fr (Marc Glisse) Date: Sat, 28 Feb 2015 12:52:34 +0100 (CET) Subject: How store libGMP bigint&-ratnum:s within a parent Garbage Collected environment with movable objects so that libGMP values must be absent of any absolute pointers whatsoever? In-Reply-To: <7ed9b115f5e8b56bdba66b4b54e9ecbc@openmailbox.org> References: <7ed9b115f5e8b56bdba66b4b54e9ecbc@openmailbox.org> Message-ID: On Sat, 28 Feb 2015, Tinker wrote: > I have a GC:ed heap wherein I want to store my libGMP bigint&-ratnum:s. This > means that I provide the memory allocator, and also it means that libGMP must > store one bigint/bigratnum as one single solid byte array only, i.e. one such > value cannot be split up in more memory allocations, because between libGMP > calls my GC changes memory location of heap objects frequently, and therefore > the values may utilize no absolute memory pointers. Your email is not very clear. How do you reference your array, if not through a pointer? Or does your GC go through memory and change all the pointers when it moves an array? Note that GMP already stores integers in a continuous memory block (a rational is a pair of integers). Using mp_set_memory_functions and the mpn layer should be safe, but without more info I have no idea if you could use mpz/mpq. > How do I use libGMP in this way? > > > As I see it it's extremely important that libGMP supports this, because this > is the only way that a garbage collected environment. > > (Methods with static memory addresses for values would risk memory > fragmentation, and not being exposed to that risk is the exact reason I use a > GC.) -- Marc Glisse From tinkr at openmailbox.org Sat Feb 28 19:45:34 2015 From: tinkr at openmailbox.org (Tinker) Date: Sun, 01 Mar 2015 01:15:34 +0530 Subject: How store libGMP bigint&-ratnum:s within a parent Garbage Collected environment with movable objects so that libGMP values must be absent of any absolute pointers =?UTF-8?Q?whatsoever=3F?= In-Reply-To: References: <7ed9b115f5e8b56bdba66b4b54e9ecbc@openmailbox.org> Message-ID: <93040b4efe7e3647d4028b7ae59a5c3d@openmailbox.org> Hi Marc, Thank you a lot for your response! I'll define my problem rather roughly now: I want to exact-precision arithmetics, example, i have the numbers A B C D which are each random integer values that are bigger than the machine's integer size, so say in the size range 10^100. Then also I have two fractionals (you know what I mean e.g. the exact numebr 10/7 , some maybe call these just rationals) A/B and C/D, let's call them E and F. What I want to do is all the standard math operations + - * / ^, comparisons, truncate remainder quotient modulo floor round ceiling abs, on them. (I understand that I may need to implement some of these myself, atop libGMP's exports.) E.g., E + F, A + E, F * G, A / B, B + C. Right, so, my GC would move around objects as it pleases, so memory pointer integrity applies only during individual math operations, and not between them. So for this reason, if any libGMP value would need to contain a pointer to anything, then that would need to be represented in the GC's object reference format - so if that would be needed then just let me know, but, if I got you right, a libGMP big-integer is just a byte array, and for the fractionals i can just implement my own format for keeping them in a row. Sure I'm fine with implementing mp_set_memory_functions.. so each math operation, like, generation of result of the E + F operation presuming the result is a bigint, will libGMP make one single alloc_func() for that only? And maybe most importantly, just please re-confirm that libGMP will be fine with that I move around these byte arrays anywhere and use libGMP operations on the moved versions? Are you aware of any example of any other libGMP binding that does this? Thanks! :) On 2015-02-28 17:22, Marc Glisse wrote: > On Sat, 28 Feb 2015, Tinker wrote: > >> I have a GC:ed heap wherein I want to store my libGMP >> bigint&-ratnum:s. This means that I provide the memory allocator, and >> also it means that libGMP must store one bigint/bigratnum as one >> single solid byte array only, i.e. one such value cannot be split up >> in more memory allocations, because between libGMP calls my GC changes >> memory location of heap objects frequently, and therefore the values >> may utilize no absolute memory pointers. > > Your email is not very clear. How do you reference your array, if not > through a pointer? Or does your GC go through memory and change all > the pointers when it moves an array? Note that GMP already stores > integers in a continuous memory block (a rational is a pair of > integers). > > Using mp_set_memory_functions and the mpn layer should be safe, but > without more info I have no idea if you could use mpz/mpq. > >> How do I use libGMP in this way? >> >> >> As I see it it's extremely important that libGMP supports this, >> because this is the only way that a garbage collected environment. >> >> (Methods with static memory addresses for values would risk memory >> fragmentation, and not being exposed to that risk is the exact reason >> I use a GC.)