-
Notifications
You must be signed in to change notification settings - Fork 29
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
Windows support #10
Comments
Yes. When I started this project, I believe Flint was still using 'long' everywhere, and I followed the same convention. There needs to be a 'slong' typedef to mirror 'ulong' for Windows 64 support. |
So I was trying to figure out what exactly
https://arblib.org/issues.html Then looking in the python-flint source I find this: We can see The problem then is that on Windows both I suppose that the most important thing for now is ensuring that If It's a long time since I wrote Cython code. Is it not possible to just the |
That
Cython compilation works in two stages: Cython -> C translation, and C compilation. C headers are only used in the second stage. You need to provide equivalent Cython-format definitions for the first stage. I think the top of
Then we just need to replace I don't know the best way to check for An alternative might be to typedef |
Not really. If the type definitions come from a C header file Cython will use those. Cython just needs to know the "approximate type". From cython docs at https://cython.readthedocs.io/en/stable/src/userguide/external_C_code.html:
Issue is that |
Thanks both! That's very helpful. I'll give this a try. |
This is enough to get a working wheel that passes all tests on 64 bit Windows: diff --git a/src/flint/_flint.pxd b/src/flint/_flint.pxd
index c471237..5121cb6 100644
--- a/src/flint/_flint.pxd
+++ b/src/flint/_flint.pxd
@@ -9,11 +9,13 @@ cdef extern from "Python.h":
int PyObject_TypeCheck(object, PyTypeObject*)
int PyInt_Check(PyObject *o)
PyObject* PyInt_FromLong(long ival)
+ PyObject* PyInt_FromLongLong(long ival)
int PyLong_Check(PyObject *o)
long PyInt_AS_LONG(PyObject *io)
double PyFloat_AS_DOUBLE(PyObject *io)
Py_ssize_t PyList_GET_SIZE(PyObject *list)
long PyLong_AsLongAndOverflow(PyObject *pylong, int *overflow)
+ long long PyLong_AsLongLongAndOverflow(PyObject *pylong, int *overflow)
DEF FMPZ_UNKNOWN = 0
DEF FMPZ_REF = 1
diff --git a/src/flint/fmpz.pyx b/src/flint/fmpz.pyx
index 5cf5ff0..77adea1 100644
--- a/src/flint/fmpz.pyx
+++ b/src/flint/fmpz.pyx
@@ -1,7 +1,7 @@
cdef inline int fmpz_set_pylong(fmpz_t x, obj):
cdef int overflow
- cdef long longval
- longval = PyLong_AsLongAndOverflow(<PyObject*>obj, &overflow)
+ cdef long long longval
+ longval = PyLong_AsLongLongAndOverflow(<PyObject*>obj, &overflow)
if overflow:
s = "%x" % obj
fmpz_set_str(x, chars_from_str(s), 16)
@@ -28,7 +28,7 @@ cdef fmpz_get_intlong(fmpz_t x):
libc.stdlib.free(s)
return v
else:
- return <long>x[0]
+ return <long long>x[0]
cdef int fmpz_set_any_ref(fmpz_t x, obj):
if typecheck(obj, fmpz): |
Wait, that's the wrong diff. It's this: -# fixme!
-DEF FLINT_BITS = 64
+# _flint.pxd
+#
+# Define the contents of the Python, GMP, Flint and Arb headers.
cdef extern from "Python.h":
ctypedef void PyObject
@@ -7,17 +8,27 @@ cdef extern from "Python.h":
ctypedef long Py_ssize_t
int PyObject_TypeCheck(object, PyTypeObject*)
int PyInt_Check(PyObject *o)
- PyObject* PyInt_FromLong(long ival)
int PyLong_Check(PyObject *o)
long PyInt_AS_LONG(PyObject *io)
double PyFloat_AS_DOUBLE(PyObject *io)
Py_ssize_t PyList_GET_SIZE(PyObject *list)
long PyLong_AsLongAndOverflow(PyObject *pylong, int *overflow)
+ long long PyLong_AsLongLongAndOverflow(PyObject *pylong, int *overflow)
DEF FMPZ_UNKNOWN = 0
DEF FMPZ_REF = 1
DEF FMPZ_TMP = 2
+#
+# Note: ulong and slong are used throughout Flint/Arb. They are expected to be
+# 32 bit unsigned and signed integer types on a 32 bit system and 64 bit on a
+# 64 bit system. We denote them as unsigned long and long here which would be
+# incorrect on 64 bit Windows but the definition here does not matter because
+# their actual sizes will be determined by the values from gmp.h and
+# flint/flint.h. Their size in bits (32 or 64) is recorded in the FLINT_BITS
+# macro which is defined in flint/flint.h.
+#
+
cdef extern from "gmp.h":
ctypedef unsigned long ulong
ctypedef unsigned long mp_limb_t
@@ -27,11 +38,14 @@ cdef extern from "gmp.h":
ctypedef mp_limb_t* mp_srcptr
ctypedef unsigned long mp_bitcnt_t
-ctypedef long fmpz_struct
-ctypedef long slong
-ctypedef ulong flint_bitcnt_t
+cdef extern from "flint/fmpz.h":
+ ctypedef long slong
+ ctypedef ulong flint_bitcnt_t
+
+ctypedef slong fmpz_struct
cdef extern from "flint/flint.h":
+ const int FLINT_BITS
ctypedef void * flint_rand_t
void flint_randinit(flint_rand_t state)
void flint_randclear(flint_rand_t state)
diff --git a/src/flint/fmpz.pyx b/src/flint/fmpz.pyx
index 5cf5ff0..77adea1 100644
--- a/src/flint/fmpz.pyx
+++ b/src/flint/fmpz.pyx
@@ -1,7 +1,7 @@
cdef inline int fmpz_set_pylong(fmpz_t x, obj):
cdef int overflow
- cdef long longval
- longval = PyLong_AsLongAndOverflow(<PyObject*>obj, &overflow)
+ cdef long long longval
+ longval = PyLong_AsLongLongAndOverflow(<PyObject*>obj, &overflow)
if overflow:
s = "%x" % obj
fmpz_set_str(x, chars_from_str(s), 16)
@@ -28,7 +28,7 @@ cdef fmpz_get_intlong(fmpz_t x):
libc.stdlib.free(s)
return v
else:
- return <long>x[0]
+ return <long long>x[0]
cdef int fmpz_set_any_ref(fmpz_t x, obj):
if typecheck(obj, fmpz): |
I've opened a PR (#28) that I think fixes this. |
I ran the test suite and for each python version, the error is different.
python 3.6
python 3.7
python 3.8
One possible issue could be that,
long
is used everywhere instead oflong long
. For example,PyLong_AsLongLongAndOverflow
should be used instead ofPyLong_AsLongAndOverflow
at https://github.com/fredrik-johansson/python-flint/blob/master/src/fmpz.pyx#L4.The text was updated successfully, but these errors were encountered: