[Cython] calling gmp automatically

Ondrej Certik ondrej at certik.cz
Tue Dec 23 14:29:51 CET 2008


On Tue, Dec 23, 2008 at 1:53 PM, Stefan Behnel <stefan_ml at behnel.de> wrote:
> Hi,
>
> Ondrej Certik wrote:
>> currently Cython converts all "ints" as int32 in C (right?).
>
> Depends on what you mean with "ints". Python ints are Python objects. Only
> things defined "cdef int" will become C ints.

Yeah, that's right.

>
>
>> How difficult would be to improve Cython, so that it can automatically
>> convert all ints to gmp calls, so that one can use arbitrary integers?
>>
>> Or to put the question differently, obviously, for most of my codes I
>> just need int32 and enjoy the speedups. However, sometimes it's handy
>> to use arbitrary ints, and since in Python both of it is just "int"
>> (resp. long in py2.6) --- what is the best way to have both?
>
> We have special support for NumPy (and buffer objects in general), so I
> wouldn't mind getting special support for other common high-performance
> libraries in as well. However, I'm not sure what we could do more than
> what gmpy already does.

Is there some example in Sage (or elsewhere) how to do this? Looking
into sage/ext/arith_gmp.pyx I read:

  See polynomial_pyx.pyx for an example.

and looking into sage/rings/polynomial/polynomial_pyx.pyx I find code like this:

    cdef mpz_t tmp

    # Allocate memory for answer, and raise exception on failure.
    vec[0] = <mpz_t *> sage_malloc(sizeof(mpz_t) * (f.degree+1))
    if vec[0] == <mpz_t *> 0:
        raise MemoryError

    # Go through and find the least commmon multiple of the denominators
    mpz_set_si(den, 1)
    for i from 0 <= i <= f.degree:
        mpz_lcm(den, den, mpq_denref(f.v[i]))

    # Fill vec with the products c*d, where c are the coefficients
    if mpz_sgn(den) == 0:   # denominator is 1
        for i from 0 <= i <= f.degree:
            mpz_init(vec[0][i])
            mpz_set(vec[0][i], mpq_numref(f.v[i]))
    else:
        mpz_init(tmp)
        for i from 0 <= i <= f.degree:
            mpz_init(vec[0][i])
            mpz_divexact(tmp, den, mpq_denref(f.v[i]))
            mpz_mul(vec[0][i], mpq_numref(f.v[i]), tmp)
        mpz_clear(tmp)


Preferably one could use it like this:

cdef mpz tmp
tmp = den/f.v[i]
vec[0][i] = f.v[i]*tmp

or something like that and leave it to Cython to call the correct
methods. I don't like the fact that Cython would have to be gmp aware
--- maybe there is some way to just implement a cdef class mpz that
would support __add__, __mull__ and things like that, so as to behave
just like python integer, but still be as fast as the explicit code
above.

Ondrej


More information about the Cython-dev mailing list