[Cython] Fused Types

Dag Sverre Seljebotn d.s.seljebotn at astro.uio.no
Sat Apr 30 09:51:20 CEST 2011

On 04/30/2011 08:39 AM, Robert Bradshaw wrote:
> On Fri, Apr 29, 2011 at 3:53 AM, mark florisson
> <markflorisson88 at gmail.com>  wrote:
>> On 29 April 2011 12:28, Pauli Virtanen<pav at iki.fi>  wrote:
>>> No, just that real_t is specialized to float whenever struct_t is specialized
>>> to A and to double when B. Or a more realistic example,
>>>         ctypedef cython.fused_type(float, double) real_t
>>>         ctypedef cython.fused_type(float complex, double complex) complex_t
>>>         cdef real_plus_one(complex_t a):
>>>             real_t b = a.real
>>>             return b + 1
>>> which I suppose would not be a very unusual thing in numerical codes.
>>> This would also allow writing the case you had earlier as
>>>         cdef cython.fused_type(string_t, int, paired=struct_t) attr_t
>>>         cdef func(struct_t mystruct, int i):
>>>             cdef attr_t var
>>>             if typeof(mystruct) is typeof(int):
>>>                 var = mystruct.attrib + i
>>>                 ...
>>>             else:
>>>                 var = mystruct.attrib + i
>>>                 ...
>>> Things would need to be done explicitly instead of implicitly, though,
>>> but it would remove the need for any special handling of
>>> the "complex" keyword.
> If we're going to introduce pairing, another option would be
>      ctypedef fused_type((double complex, double), (float complex,
> float)) (complex_t, real_t)
> though I'm not sure I like that either. We're not trying to create the
> all-powerful templating system here, and anything that can be done
> with pairing can be done (though less elegantly) via branching on the
> types, or, as Pauli mentions, using a wider type is often (but not
> always) a viable option.

Keeping the right balance is difficult. But, at least there's some cases 
of needing this in various codebases when interfacing with LAPACK.

Most uses of templating with Cython code I've seen so far does a similar 
kind of "zip" as what you have above (as we discussed on the workshop). 
So at least the usage pattern you write above is very common.

float32 is not about to disappear, it really is twice as fast when 
you're memory IO bound.

Using a wider type is actually quite often not possible; any time the 
type is involved as the base type of an array it is not possible, and 
that's a pretty common case. (With LAPACK you take the address of the 
variable and pass it to Fortran, so using a wider type is not possible 
there either, although I'll agree that's a more remote case.)

My proposal: Don't support either "real_t complex" or paired fused types 
for the time being. Then see.

But my vote is for paired fused types instead of "real_t complex".

Dag Sverre

More information about the cython-devel mailing list