robertwb / issues-import-test

0 stars 0 forks source link

Invalid C generated for some numpy complex number multiplications: typedef types with _Complex keyword #1002

Open robertwb opened 9 years ago

robertwb commented 9 years ago

This bug is closely related to ticket http://trac.cython.org/ticket/386, however it is slightly different in that it reports a realistic use case that in my opinion would qualify it as a bug rather than an enhancement request. Hence I've raised a new ticket, but I'm new round here - maybe it should be merged.

The discovery of the bug stems from answering a question on Stack Overflow : http://stackoverflow.com/questions/30054019/complex-numbers-in-cython. It affects numpy multiplication of complex numbers by real valued floats

In its most concise form - this code produces C that will not compile:

cimport numpy as np

cdef extern from "complex.h":
    pass

cdef:
    np.complex128_t varc128 = 1j
    np.float64_t varf64 = 1.

varc128 = varc128 * varf64

whereas the same code produces error free C code with only order of multiplicands reversed. (i.e. substitute varc128 = varf64 * varc128 for varc128 = varc128 * varf64. This appears to be because there are different routes for achieving the multiplication depending on the order of operands, in the first (failing) example it is done via __pyx_t_npy_float64_complex types, whereas in the latter __pyx_t_npy_double_complex

As far as I could investigate - the offending line of generated C code fails to compile because only float, double or long double are allowed before _Complex (http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Standard-Complex-Number-Types).

The offending line of C code seems to be generated by the code here:

https://github.com/cython/cython/blob/bb4d9c2de71b7c7e1e02d9dfeae53f4547fa9d7d/Cython/Compiler/PyrexTypes.py#L1949

We can see here that the offending type is basically an alias for double

https://github.com/cython/cython/blob/e3f5343f3b648fc0033bdaf0def3268abab7b9ea/Cython/Includes/numpy/__init__.pxd#L331

I haven't got a full, generalisable fix / patch as I'm totally new to the codebase, but ''possibly'' the code here should check whether it's valid to append the _Complex and, if not, search to see whether the type can be resolved to an allowable base type.

https://github.com/cython/cython/blob/bb4d9c2de71b7c7e1e02d9dfeae53f4547fa9d7d/Cython/Compiler/Nodes.py#L1011

Migrated from http://trac.cython.org/ticket/850