[Cython] Cygwin: Handling missing C99 long double functions

Erik Bray erik.m.bray at gmail.com
Wed May 11 09:22:36 EDT 2016


On Tue, May 10, 2016 at 8:01 AM, Robert Bradshaw
<robertwb at math.washington.edu> wrote:
> On Wed, May 4, 2016 at 8:01 AM, Erik Bray <erik.m.bray at gmail.com> wrote:
>> On Tue, May 3, 2016 at 7:15 PM, Robert Bradshaw <robertwb at gmail.com> wrote:
>>> On Tue, May 3, 2016 at 3:04 AM, Erik Bray <erik.m.bray at gmail.com> wrote:
>>>> I agree that it would be safest not to use long double where long
>>>> double functions are not support, and an application that does should
>>>> probably check for that.
>>>>
>>>> The problem is that Cython is generating code that simply *cannot* be
>>>> compiled on such platforms.
>>>
>>> Does Cython ever generate such code when long doubles are not used in the
>>> source? If so, we should fix that. But I don't think Cython should be
>>> swapping in double versions for long double operations.
>>
>> No, but the problem is that Cython is a pretty heavy layer of
>> abstraction.  In the example I gave no long double function was ever
>> used explicitly--it was added by a compiler optimization.  I probably
>> wouldn't write that code thinking that I will need a workaround on
>> platforms that don't have truncl.
>
> I would argue that if you don't have truncl, you shouldn't be using
> long double. Possibly this particular use of truncl could be worked
> around (though note that using trunc is not safe) but it's starting to
> get on shaky ground.

Yeah but I will state again: Cython is compiling code that may be
distributed to a wide audience.  A developer who writes some code that
happens to use long double isn't going to think themselves "Gosh, I
guess I can't accept `long double` here because it may cause Cython to
generate code that contains "truncl" [how would they know that? It's
an internal optimization] and I can't do that because it won't work on
Cygwin [which the average developer wouldn't know]"

Instead they'll just write their code, ship it, and it will fail to
compile or install for users on Cygwin.  So it's a question of least
astonishment.

>> In the slightly more explicit cases of fmod and pow I might agree.
>> Though there still isn't a great way to anticipate the need to write
>> separate handling for long double functions into a module, for a
>> platform that doesn't support them.  I can't write something in a
>> Cython module like:
>>
>>     if sys.platform != 'cygwin':
>>         def my_long_double_func(long double x):
>>             ....
>
> No, that's not something we support well. You can put them in a
> separate module and conditionally compile/import them.


>> Maybe would be nice to have a simple compiler directive that outright
>> disables compiling a function depending on a platform check. (I think
>> this would also be useful for the test framework--the current system
>> of module-level tags is not fine-grained as I would like, I'm finding.
>>
>>>> My suggestion would be to replace the
>>>> current calls to [trunc,fmod,pow]l to the appropriate
>>>> __Pyx_%(func)_%(type) wrapper which would provide two alternatives:
>>>> One that works properly, and one that falls back to using the double
>>>> version of the function (Numpy does this so there is some precedent).
>>>> I would go further and suggest throwing up a pre-compiler warning when
>>>> using the double versions.
>>>>
>>>> The only question is what condition (in my mind) is what to use as a
>>>> condition for selecting the fallbacks.  For now I'm thinking something
>>>> quite specific like
>>>>
>>>>     #if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL)
>>>>
>>>> since I'm apparently the only person who cares about this at the
>>>> moment, and Cygwin is the platform I'm targeting.
>>>>
>>>> Again, my only real concern right now is that Cython generates code
>>>> that can be compiled on Cygwin.
>>>
>>>
>>> If you want this behavior, wouldn't including a header
>>>
>>> #if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL)
>>> #define truncl trunc
>>> #define fmodl fmod
>>> #define powl pow
>>> #endif
>>>
>>> as part of your package do the job?
>>
>> That's a reasonable workaround. But I would argue that should be baked
>> into Cythonized code, at least optionally, and should generate a
>> warning.
>
> This is dangerous to bake into Cython code, even with a warning (who
> would see it?) I say if you want to pretend to support long double on
> platforms that don't fully support long double, that should be very
> explicit.

Well, something should be explicit anyways.  Right now we just get
code that doesn't compile on some systems :(

I don't necessarily want or care for something to pretend to support
long double on a platform where it isn't fully supported.  All I care
is that my Cython-generated code compiles.  I'm just throwing out
suggestions, and the possibilities are limited due to lack of support
in C for compile-time feature checks.

As for who would see such a warning, anyone who compiles the code?
I'm talking about preprocessor warnings here.  Yes, people ignore
warnings, but at least they have something to refer back to if they
get incorrect results.  Heck, to be safe you're right that it should
really be an #error by default, but at least let's make it an explicit
error (with the ability to downgrade to a warning).  and not "such and
such not found".

Best,
Erik


More information about the cython-devel mailing list