Skip to content
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

[BUG] Access violation using cython.ufunc with cimport numpy #6064

Closed
cgohlke opened this issue Mar 7, 2024 · 3 comments · Fixed by #6065
Closed

[BUG] Access violation using cython.ufunc with cimport numpy #6064

cgohlke opened this issue Mar 7, 2024 · 3 comments · Fixed by #6065

Comments

@cgohlke
Copy link
Contributor

cgohlke commented Mar 7, 2024

Describe the bug

The following code using @cython.ufunc, a slight variation of the documentation, crashes reproducibly on import on Windows with Python 3.11/3.12, Cython 3.0.9/3.1.0a0, numpy 1.26.4, Visual Studio 2022, and define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")].

# ufunc_crash.pyx
cimport cython

cimport numpy  # no crash without this line

@cython.ufunc
cdef double add_one(double x):
    return x+1
> py -X dev -c"import ufunc_crash"
Windows fatal exception: access violation

Current thread 0x000011b8 (most recent call first):
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 1241 in exec_module
  File "<frozen importlib._bootstrap>", line 690 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1147 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1176 in _find_and_load
  File "<string>", line 1 in <module>
[0x0]   ufunc_crash_cp311_win_amd64!__pyx_pymod_exec_ufunc_crash+0x5fb   0x3acbfef1e0   0x7ffab1670a88   
[0x1]   python311!PyModule_ExecDef+0x90   0x3acbfef290   0x7ffab16709a1   
[0x2]   python311!exec_builtin_or_dynamic+0x45   0x3acbfef2c0   0x7ffab175ab18   
[0x3]   python311!_imp_exec_dynamic_impl+0xa   0x3acbfef2f0   0x7ffab1619c0c   
[0x4]   python311!_imp_exec_dynamic+0x10   0x3acbfef2f0   0x7ffab1619c0c   
[0x5]   python311!cfunction_vectorcall_O+0x21c   0x3acbfef320   0x7ffab1660773   
[0x6]   python311!_PyVectorcall_Call+0x19   0x3acbfef380   0x7ffab1660440   
[0x7]   python311!_PyObject_Call+0x5b   0x3acbfef380   0x7ffab1660440   
[0x8]   python311!PyObject_Call+0xc   0x3acbfef3e0   0x7ffab15eac94   
[0x9]   python311!do_call_core+0x1bc   0x3acbfef3e0   0x7ffab15eac94   
[0xa]   python311!_PyEval_EvalFrameDefault+0x5384   0x3acbfef440   0x7ffab160f344   
[0xb]   python311!_PyEval_EvalFrame+0x1c   0x3acbfef650   0x7ffab16a37c3   
[0xc]   python311!_PyEval_Vector+0x30f   0x3acbfef650   0x7ffab16a37c3   
[0xd]   python311!_PyFunction_Vectorcall+0x336   0x3acbfef650   0x7ffab16a37c3   
[0xe]   python311!_PyObject_VectorcallTstate+0x3a4   0x3acbfef650   0x7ffab16a37c3   
[0xf]   python311!object_vacall+0x9f   0x3acbfef6e0   0x7ffab16a36fe   
[0x10]   python311!PyObject_CallMethodObjArgs+0x5e   0x3acbfef770   0x7ffab1646c11   
[0x11]   python311!import_find_and_load+0xe9   0x3acbfef7c0   0x7ffab162596a   
[0x12]   python311!PyImport_ImportModuleLevelObject+0x52a   0x3acbfef830   0x7ffab1648c53   
[0x13]   python311!import_name+0x9f   0x3acbfef8e0   0x7ffab15ecc62   
[0x14]   python311!_PyEval_EvalFrameDefault+0x7352   0x3acbfef980   0x7ffab16456bf   
[0x15]   python311!_PyEval_EvalFrame+0x1e   0x3acbfefb90   0x7ffab16470bf   
[0x16]   python311!_PyEval_Vector+0x77   0x3acbfefb90   0x7ffab16470bf   
[0x17]   python311!PyEval_EvalCode+0x97   0x3acbfefbd0   0x7ffab16d03c6   
[0x18]   python311!run_eval_code_obj+0x52   0x3acbfefc50   0x7ffab16d0342   
[0x19]   python311!run_mod+0x72   0x3acbfefc80   0x7ffab16cf8eb   
[0x1a]   python311!PyRun_StringFlags+0x7b   0x3acbfefcc0   0x7ffab1695599   
[0x1b]   python311!PyRun_SimpleStringFlags+0x41   0x3acbfefd10   0x7ffab169566c   
[0x1c]   python311!pymain_run_command+0xa0   0x3acbfefd50   0x7ffab169597c   
[0x1d]   python311!pymain_run_python+0x124   0x3acbfefd80   0x7ffab1695829   
[0x1e]   python311!Py_RunMain+0x15   0x3acbfefdf0   0x7ffab1696019   
[0x1f]   python311!Py_Main+0x25   0x3acbfefe20   0x7ff6322b1230   
[0x20]   python!invoke_main+0x22   0x3acbfefe70   0x7ffb3533257d   
[0x21]   python!__scrt_common_main_seh+0x10c   0x3acbfefe70   0x7ffb3533257d   
[0x22]   KERNEL32!BaseThreadInitThunk+0x1d   0x3acbfefeb0   0x7ffb36f8aa58   
[0x23]   ntdll!RtlUserThreadStart+0x28   0x3acbfefee0   0x0   

The issue might be with when the numpy C API is initialized. For example, the following code does not crash (calling numpy.import_array() should not be necessary according to the documentation):

cimport numpy
numpy.import_array()

cimport cython

@cython.ufunc
cdef double add_one(double x):
    return x+1

However, that is no solution since this does crash on Cython 3.0.9 (seems to be fixed in 3.1.0a0 ?):

cimport numpy
numpy.import_array()

cimport cython
from cython.parallel import parallel

@cython.ufunc
cdef double add_one(double x):
    return x+1

I have been using the numpy C API with Cython for many years. This seems to be specific to cython.ufunc.

Code to reproduce the behaviour:

cimport cython

cimport numpy

@cython.ufunc
cdef double add_one(double x):
    return x+1

Expected behaviour

No crash.

OS

Windows 11

Python version

3.11, 3.12

Cython version

3.0.9, 3.1.0a0

Additional context

No response

@cgohlke
Copy link
Contributor Author

cgohlke commented Mar 8, 2024

Adding these lines at the top of the .pyx before any other code seems to work reliable for me:

cimport numpy
numpy.import_array()
numpy.import_ufunc()

@da-woods
Copy link
Contributor

da-woods commented Mar 8, 2024

So the issue seems to be: using cython.ufunc is supposed to add this utility code

///////////////////////// NumpyImportUFunc.init ////////////////////
but it doesn't seem to be happening for some reason

da-woods added a commit to da-woods/cython that referenced this issue Mar 9, 2024
Fixes cython#6064. The relevant utility code to set up ufuncs wasn't
being included because it compared equal to a different section
of utility code that also only contained an init section
da-woods added a commit to da-woods/cython that referenced this issue Mar 9, 2024
Fixes cython#6064. The relevant utility code to set up ufuncs wasn't
being included because it compared equal to a different section
of utility code that also only contained an init section
scoder pushed a commit that referenced this issue Mar 9, 2024
The relevant utility code to set up ufuncs wasn't being included because it compared equal to a different section of utility code that also only contained an "init" section

Fixes #6064
@cgohlke
Copy link
Contributor Author

cgohlke commented Mar 9, 2024

Thank you

scoder pushed a commit that referenced this issue Mar 9, 2024
The relevant utility code to set up ufuncs wasn't being included because it compared equal to a different section of utility code that also only contained an "init" section

Fixes #6064
@scoder scoder added this to the 3.0.10 milestone Mar 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants