diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index a1c0d8d1..61b2d0b3 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -6,6 +6,7 @@ jobs: build_wheels: name: Build wheels for ${{ matrix.os }} runs-on: ${{ matrix.os }} + continue-on-error: true strategy: fail-fast: false matrix: @@ -23,8 +24,10 @@ jobs: uses: pypa/cibuildwheel@v2.11.2 env: CIBW_BUILD: cp39-* cp310-* cp311-* - CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux_*" + #CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux_*" + CIBW_SKIP: "*-win32 *-musllinux_*" CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 + CIBW_MANYLINUX_I686_IMAGE: manylinux2014 CIBW_BEFORE_ALL_LINUX: bin/cibw_before_build_linux.sh CIBW_BEFORE_ALL_MACOS: bin/cibw_before_build_macosx.sh CIBW_BEFORE_BUILD: pip install numpy cython diff --git a/.gitignore b/.gitignore index 0b8a9bd5..2cc28b3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ build/* dist/* -src/*.c +src/flint/*.c doc/build/* fmake* *.whl +*.pyc +*.pyd +*.so +__pycache__ MANIFEST .eggs .local diff --git a/bin/build_inplace.sh b/bin/build_inplace.sh new file mode 100755 index 00000000..bd208f19 --- /dev/null +++ b/bin/build_inplace.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# +# Build the flint._flint module in place. + +C_INCLUDE_PATH=.local/include/ LIBRARY_PATH=.local/lib/ python setup.py build_ext --inplace diff --git a/bin/build_wheel.sh b/bin/build_wheel.sh index bc4c62ef..e881dda6 100755 --- a/bin/build_wheel.sh +++ b/bin/build_wheel.sh @@ -5,37 +5,11 @@ set -o errexit -PYTHONFLINTVER=0.3.0 - source bin/build_variables.sh python3 -m venv $PREFIX/venv source $PREFIX/venv/bin/activate -pip install -U pip wheel delocate -pip install numpy cython -# Working as of cython==0.29.28 +pip install -U pip +pip install numpy cython wheel C_INCLUDE_PATH=.local/include/ LIBRARY_PATH=.local/lib/ pip wheel . - -wheelfinal=*.whl - -# On OSX bundle the dynamic libraries for the dependencies -mkdir -p wheelhouse -delocate-wheel -w wheelhouse $wheelfinal - -echo ------------------------------------------ -echo -echo Built wheel: wheelhouse/$wheelfinal -echo -echo Link dependencies: -delocate-listdeps wheelhouse/$wheelfinal -echo -pip install wheelhouse/$wheelfinal -echo -echo Demonstration: -echo -python -c 'import flint; print("(3/2)**2 =", flint.fmpq(3, 2)**2)' -echo -echo Done! -echo -echo ------------------------------------------ diff --git a/src/flint/_flint.pxd b/src/flint/_flint.pxd index bf1e9627..d8eb3e16 100644 --- a/src/flint/_flint.pxd +++ b/src/flint/_flint.pxd @@ -1,5 +1,6 @@ -# 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) @@ -39,6 +53,21 @@ cdef extern from "flint/flint.h": long flint_get_num_threads() void flint_cleanup() +cdef extern from *: + """ + /* FLINT_BITS is not known until C compile time. We need to check if long + * or long long matches FLINT_BITS to know which CPython function to call. + */ + #if FLINT_BITS == 32 && LONG_MAX == 2147483647 + #define pylong_as_slong PyLong_AsLongAndOverflow + #elif FLINT_BITS == 64 && LLONG_MAX == 9223372036854775807 + #define pylong_as_slong PyLong_AsLongLongAndOverflow + #else + #error FLINT_BITS does not match width of long or long long. + #endif + """ + slong pylong_as_slong(PyObject *pylong, int *overflow) + cdef extern from "flint/nmod_vec.h": ctypedef struct nmod_t: mp_limb_t n diff --git a/src/flint/fmpz.pyx b/src/flint/fmpz.pyx index 5cf5ff01..dd2703b5 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(obj, &overflow) + cdef slong longval + longval = pylong_as_slong(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 x[0] + return x[0] cdef int fmpz_set_any_ref(fmpz_t x, obj): if typecheck(obj, fmpz):