-
Notifications
You must be signed in to change notification settings - Fork 27
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
Directly initialize fmpz from a python int. #64
base: main
Are you sure you want to change the base?
Conversation
Mimics the code from gmpy2 and so depends on undocumented internals of PyLong.
Can you do this with an ifdef on CPython? |
Can I do what with an ifdef? My knowledge of Cython is not great, and I find the documentation to be of somewhat questionable value. My experience is that Cython does not like #ifdefs, but I would not put much stock in my opinion or experience. The current implementation works, and using _fmpz_promote seems to work on my machine, but I'm not certain that setting the mpz_t given by _fmpz_promote will always leave the fmpz in a valid state. |
It can be done at the C level in the same way as in C e.g.: python-flint/src/flint/_flint.pxd Lines 56 to 69 in bf9d0d1
Agreed!
I presume that @isuruf wants this to work with PyPy also or is considering the general possibility of other Python implementations that support the C API but are not CPython. |
|
@fredrik-johansson Thank you. |
No longer allocating a separate fmpz object so should be faster.
This uses the method from sagemath which is a bit simpler than that of gmpy2. It is missing a normalization step that is in gmpy2. I guess that the normalization step is not necessary.
I'm not entirely sure what is going on, but this seems to be the fastest set of methods
Running some benchmarks it appears that using pylong_as_slong from the old code is slightly faster on my Mac M1 machine. Here 'hex string' is the current method of writing then reading a hex string, 'Py_SIZE' uses Note that all of these measurements have about a 4% stddev.
the benchmark code is
|
These timings are all for relatively small integers. Obviously small integers are an important case but the other important case here is very large integers, like megabyte sized. |
Not surprisingly all three of the methods scale linearly with the size of the number. Using the same benchmark as before, but using only 100 random numbers converted 100 times, we see that the string conversion method is about 3 times slower asymptotically. The differences between the Py_SIZE and pylong_as_slong methods is well within measurement error for these large numbers.
|
I'm not sure I understand exactly what each of the different benchmarks is timing but it seems that the If it is 3x faster than the current master code for large integers then I think that is well worth it. Is the only outstanding item having an |
Yes, the pylong as slong is what is implemented, and it is three times faster. |
@isuruf do you know how to do this in C? I can't see a preprocessor define that could be used to identify CPython specifically. For PyPy you could check for PYPY_VERSION (defined in patchlevel.h). |
Not the most straightforward of merges, light editing of flintlib/flint.pxd and flintlib/fmpz.pxd was needed.
Sorry, This kind of fell off my radar. |
I think it should be enough to check |
There have been some changes to PyLong or at least how it is exposed by the CPython headers in Python 3.12. See aleaxit/gmpy#441 I'm going to rerun CI to see if this passes with 3.12. |
I will take a look at it. I agree with the sentiment that python integers are a mess. |
I hope the PEP 757 will be available with 3.14. @deinst, are you interested in continuing this work using new API? Here is gmpy2 patch: aleaxit/gmpy#495. Here is API backport for older py3 releases: python/pythoncapi-compat#121. |
Mimics the code from gmpy2 and so depends on undocumented internals of PyLong.
This uses rather more of the internals of PyLong than may be prudent. This PR is mainly an attempt to see if it works on the various CI instances. If it flies I'll do the fmpz->pylong conversion as well. Also I think we should use _fmpz_promote to get access to the internal mpz of the fmpz, but I have not convinced myself that it is safe.