[Cython] Cygwin: Handling missing C99 long double functions

Erik Bray erik.m.bray at gmail.com
Wed Apr 27 06:07:51 EDT 2016


On Tue, Apr 26, 2016 at 10:55 PM, Robert Bradshaw <robertwb at gmail.com> wrote:
> On Tue, Apr 26, 2016 at 8:36 AM, Erik Bray <erik.m.bray at gmail.com> wrote:
>>
>> On Tue, Apr 26, 2016 at 5:16 PM, Dima Pasechnik
>> <dimpase+github at gmail.com> wrote:
>> > Hi,
>> > certainly we did something with Sage on cygwin to work around these...
>> > Just in case,
>>
>> From what I can tell there are several places where Sage has hacked
>> around this issue in different packages, but it's not doing anything
>> specifically with it for Cython.  Sage uses the Cephes math lib to
>> support these functions on FreeBSD--and apparently used to use it on
>> Cygwin too, but disabled that for some reason.
>>
>> Regardless, Cython should ultimately do something sensible in these cases.
>>
>> My general thinking is that in cases where Cython generates code
>> containing C math functions, it ought to support a fallback.  This
>> will require some feature checks so that Cython can generate wrappers,
>> when necessary, around the double versions of those functions (as
>> Numpy currently does).
>
>
> Let's make things concrete. You're complaining that something like
>
> cdef extern from "math.h":
>     long double sqrtl(long double)
>
> def foo(long double x):
>     return sqrtl(x)
>
> Doesn't work on Cygwin?
>
> The same is true for *any* C function that you use that's not totally
> portable (this is the bane of trying to use C). I don't think Cython should
> be detecting this and substituting a (less accurate) sqrt for sqrtl in this
> case. If you want do do this, write your own headers that (conditionally)
> define these things however you want.

No, not at all.  That would be silly.  Let me be clearer...

> Or, are you complaining that Cython's test suite doesn't pass on some Cygwin
> because there are tests of features not available on Cygwin? (Your original
> email isn't clear.) If so, the test framework can be set up to exclude these
> tests on that platform.

There are really two concerns.  This is one of them, yes.  The first
question is what would be the best way to exclude certain tests on
certain platforms?  There's no clear documentation on that (which is
fine, but it's why I'm asking :)

The second concern, and more serious, is that there *are* cases where
Cython generates code that uses long double functions where, for
example, long double is passed as an argument.  For example the
following code

    def truncate_long_double(long double x):
        cdef float r = int(x)
        return r

compiles to something that includes:

      /* "truncl.pyx":2
     * def truncate_long_double(long double x):
     *     cdef float r = int(x)             # <<<<<<<<<<<<<<
     *     return r
     */
      __pyx_t_1 = truncl(__pyx_v_x);
      __pyx_v_r = __pyx_t_1;

      /* "truncl.pyx":3
     * def truncate_long_double(long double x):
     *     cdef float r = int(x)
     *     return r             # <<<<<<<<<<<<<<
     */
      __Pyx_XDECREF(__pyx_r);
      __pyx_t_2 = PyFloat_FromDouble(__pyx_v_r); if
(unlikely(!__pyx_t_2)) __PYX_ERR(0, 3, __pyx_L1_error)

It's not not clear what the best way would be to *not* use this code
on platforms where truncl missing (and there are a handful of other
examples besides truncl). This code is generated by an optimization
that was added here: http://trac.cython.org/ticket/400  In this case
replacing truncl with trunc shouldn't hurt.

It's not uncommon (I think) to ship pre-cythonized C sources in a
package's source distribution so that it can be installed (especially
by pip) without requiring the user to have Cython.  This code will
fail to compile on platforms like Cygwin.

But it's not clear how to handle this at Cythonization time either
since it doesn't know in advance what platform it will be targeting.
I'm suggesting that maybe rather than using these functions directly
Cython should generate some fallbacks for where they're not available,
or at least have the option to.

Erik

P.S. additional long double functions that can be generated by Cython
include powl and fmodl, and long double complex functions like conjl,
cabsl, and cpowl.  So it's really only a limited number at the moment.


More information about the cython-devel mailing list