On 12 February 2011 10:07, Cactus <rieman...@gmail.com> wrote:
>
>
> On Feb 9, 10:10 am, Cactus <rieman...@gmail.com> wrote:
>> On Feb 8, 3:50 am, Case Vanhorsen <cas...@gmail.com> wrote:
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> > On Mon, Feb 7, 2011 at 7:47 AM, Cactus <rieman...@gmail.com> wrote:
>>
>> > > On Feb 7, 3:09 pm, Case Vanhorsen <cas...@gmail.com> wrote:
>> > >> On Mon, Feb 7, 2011 at 7:00 AM, Cactus <rieman...@gmail.com> wrote:
>>
>> > >> > This would also be a significant task but it would solve this problem
>> > >> > once and for all.
>>
>> > >> It does keep the API from growing. I can see it working with
>> > >> statically linked applications (like gmpy) but wouldn't there be DLL
>> > >> issues if two dynamically linked applications assumed different
>> > >> interfaces?
>>
>> > > Only the application that made the wrong assumption :-)
>>
>> > >    Brian
>>
>> > > --
>> > > You received this message because you are subscribed to the Google 
>> > > Groups "mpir-devel" group.
>> > > To post to this group, send email to mpir-devel@googlegroups.com.
>> > > To unsubscribe from this group, send email to 
>> > > mpir-devel+unsubscr...@googlegroups.com.
>> > > For more options, visit this group 
>> > > athttp://groups.google.com/group/mpir-devel?hl=en.
>>
>> > What about following the API in MPFR and adding mpz_set_sj where j is
>> > defined to be intmax_t? IIUC, this should allow us to pass any integer
>> > type. (And _uj for uintmax_t, etc.)
>>
>> > This may be the most work, but it follows the precedent set in MPFR.
>>
>> > casevh
>>
>> Yes, that's a good solution. Its a lot of work but would be worthwhile
>> in the long term.
>>
>> How many would volunteer some effort to do this though?   I am not
>> sure I would want to embark on this as the only contributor.
>>
>> On the plus side it should not be hard to draw up a small set of
>> 'templates' for doing this, many of which already exist in the code.
>>
>> The get/set with limb and integer size relationships greater, equal
>> and less would be fairly standard code.
>>
>> And others would involve faking up an appropriate GMP type from
>> similar templates.
>>
>>     Brian
>
> Case and I have been discussing how this issue should be approached in
> an 'off list' email exchange so I want to expose a couple of options
> here in case others have any views on the way ahead.
>
> One option is to duplicate (or even replace) all existing 'ui/si'
> functions so that they all use either an mp_limb_t or an mp_slimb_t (a
> new signed limb type) for their integer parameters.

There is already a signed limb format. It is called mp_limb_signed_t

>
> This would be manly a reuse of the existing source code but we would
> need to check that the functions still work for all the limb/integer
> size ratios that we might come across.

An mp_limb_t can currently be a short int, long or long long depending
on platform. As far as I know, an mp_limb_t is now always 32 or 64
bits. Odd sizes have all vanished since the big cleanup of old arches
that Jason did.

I think there are actually some old supported platforms on which long
is *bigger* than the supported ABI, i.e. long is bigger than an
mp_limb_t. Whether these machines are still supported and whether
anyone but museums still owns such machines, I am unsure. But we must
assume they still exist.

The ui functions doubtlessly exist because most people write C code
using either ints or longs or long longs. By having a set_ui function
for example, one can pass either an int or a long or long long into an
MPIR function without caring about what size a limb is. This is
definitely how it should be.

This highlights what should be the correct design principle, an ui
should be larger than any type used commonly on that architecture.
Then one can pass any size and automatic zero or sign extension will
take care of everything for them. Thus on 64 bit Windows an ui should
be a unsigned long long and an si should be a long long.

Note a ui/si should *NOT* in general be the same thing as an mp_limb_t
or mp_limb_signed_t. It might be that you have an ABI=32 bits machine
on which an mp_limb_t is a long (because that is faster and has
hardware support) but long long is 64 bits on that machine. The ui
functions should still use long long and set two limbs.

Now of course functions like mpn_addmul_1 would *NOT* use an ui/si.
They would specifically use an mp_limb_t. This is for performance
reasons. So in general mpz_set_ui would NOT do the same thing as
mpn_set_ui. This is also how things should definitely be.

The only problem with this approach is if someone wants a fast
mpz_mul_ui and an ui is currently two limbs. In this case one might
like to have an mpz_mul_1 function which multiplies by a limb instead
of an ui.

I definitely do not think it is a good idea to allow one to specify
the size of an ui at compile time (of MPIR).

As C is a compiled language, there is no chance to do this efficiently
at run time.

The only way to do it would be to allow it at compile time (of the application).

In other words, one would have to do:

#define MPIR_LIMB_UI
#include "mpir.h"

in the application being compiled against MPIR. This would set the
size of an UI to the same size as a limb for efficiency. Thus when
mpz_mul_ui is used, it would expect a limb sized ui instead of a long
long or whatever the currently largest integer on that machine is.

The reason I have an opinion on this issue is I've recently been
fiddling a lot with compilers and interpreters, including coding some
experimental ones, and the issue of different sized integers came up
there. I finally had the revelation that if one supports the largest
sized integer available, all the others are automatically supported
(at the C level anyway) because of sign/zero extension, i.e. by C's
automatic casting.

>
> Another approach is to modify the existing 'ui/si' source code files
> by using two defines:
>
> #define INT_VAR_TYPE
> #define FN_SUFFIX
>
> internally for their integer types and their function suffixes and
> then rename them to, say, function.inc. we can then use a source code
> file function.c:
>
> #define INT_VAR_TYPE   unsigned int
> #define FN_SUFFIX         ui
> #include "function.inc'
> #undef INT_VAR_TYPE
> #undef FN_SUFFIX
>
> #define INT_VAR_TYPE   unsigned long long
> #define FN_SUFFIX         ull
> #include "function.inc'
> #undef INT_VAR_TYPE
> #undef FN_SUFFIX
>
> #define INT_VAR_TYPE   uintmax_t
> #define FN_SUFFIX         uj
> #include "function.inc'
> #undef INT_VAR_TYPE
> #undef FN_SUFFIX
>
> .......
>
> for as many integer types as we want (we again need to check the
> generic code will work for all anticipated limb/integer size
> ratios).
>
> This is the 'C template' technique that the GNU Scientific Library
> (GSL) uses to handle a similar issue.
>
> But I recall that such techniques can play havoc with the *nix build
> system so it might be only be possible on a windows specific version
> of MPIR, which would be a pity given our eventual desire to have a
> unified build system for *nix and Windows.
>
> I would be interested in any views people might have on these issues
> before we leap in and so any coding.
>
>    Brian
>
> --
> You received this message because you are subscribed to the Google Groups 
> "mpir-devel" group.
> To post to this group, send email to mpir-devel@googlegroups.com.
> To unsubscribe from this group, send email to 
> mpir-devel+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/mpir-devel?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"mpir-devel" group.
To post to this group, send email to mpir-devel@googlegroups.com.
To unsubscribe from this group, send email to 
mpir-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/mpir-devel?hl=en.

Reply via email to