New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cython: potential compilation failures with fused types #893

Closed
mstimberg opened this Issue Oct 25, 2017 · 0 comments

Comments

Projects
None yet
1 participant
@mstimberg
Member

mstimberg commented Oct 25, 2017

In the generated Cython code, we do not define the types for the temporary variables (e.g. the intermediate result _v for the update of the membrane potential v before it is written back). Normally, Cython figures out the type by itself just fine (i.e. this is not about a performance issue where Cython generates Python instead of C code). However, the use of fused types (e.g. for the clip function) can confuse Cython sufficiently so it raises an error during compilation. The error will complain about "Invalid use of fused types, type cannot be specialized" or the compiler will crash. The latter is actually a bug in Cython, but I think fixing it would just mean to raise the "Invalid use of fused types" error.
We actually get this with the frompapers/Platkiewicz_Brette_2011.py example:

Error compiling Cython file:
------------------------------------------------------------
...
        t = _array_defaultclock_t[0]
        v = _array_neurongroup_v[_idx]
        not_refractory = (t - lastspike) > 0.005
        xi = _lio_1 * _randn(_vectorisation_idx)
        _I = ((_lio_2 * (- I)) + I) + (_lio_3 * xi)
        _theta = (_lio_4 * ((vT + (a * clip(_lio_5 + v, 0.0, _lio_6))) - theta)) + theta
                               ^
------------------------------------------------------------

/home/marcel/.cython/brian_extensions/_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:32: Compiler crash in AnalyseExpressionsTransform

ModuleNode.body = StatListNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:6:0)
StatListNode.stats[15] = StatListNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:79:0)
StatListNode.stats[0] = DefNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:79:0,
    modifiers = [...]/0,
    name = u'main',
    np_args_idx = [...]/0,
    num_required_args = 1,
    py_wrapper_required = True,
    reqd_kw_flags_cname = '0',
    used = True)
File 'ExprNodes.py', line 10680, in infer_type: AddNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:81,
    infix = True,
    operator = u'+',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 10681, in infer_type: MulNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:25,
    infix = True,
    operator = u'*',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 10680, in infer_type: SubNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:71,
    infix = True,
    operator = u'-',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 10681, in infer_type: AddNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:32,
    infix = True,
    operator = u'+',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 10751, in result_type: AddNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:32,
    infix = True,
    operator = u'+',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 11027, in is_py_operation_types: AddNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:32,
    infix = True,
    operator = u'+',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 10978, in is_py_operation_types: AddNode(_cython_magic_ca70be6786b10bc4b580e0b5c5af56e0.pyx:183:32,
    infix = True,
    operator = u'+',
    result_is_used = True,
    use_managed_ref = True)

Compiler crash traceback from this point on:
  File "/home/marcel/anaconda2/envs/brian2/lib/python2.7/site-packages/Cython/Compiler/ExprNodes.py", line 10978, in is_py_operation_types
    type2.is_unicode_char or
AttributeError: 'NoneType' object has no attribute 'is_unicode_char'

A fix seems to be to define the types of all temporary variables in the Cython code, I did this in a branch already, will open a PR shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment