You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party module fails on Python 3.5) #69337
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2020-06-05.20:42:45.704>created_at=<Date2015-09-17.12:58:59.262>labels= ['extension-modules', '3.8', 'build', '3.7']
title='3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party module fails on Python 3.5)'updated_at=<Date2020-06-05.20:42:45.701>user='https://bugs.python.org/axh'
trying to install the yt package, most recent version 3.2.1 on python 3.5.0 using pip
pip3 install -U yt
error output attached. The same package installs fine with python 3.4.3, same compiler and also build from scratch, so the suspicion is that it is related to the new 3.5.0 version. The system installed is the current Fedora 22, gcc 5.1.1-4.
It looks like the problem is that yt uses OpenMP whereas OpenMP doesn't support atomic operations:
In file included from /home/alex/Python/include/python3.5m/pyatomic.h:12:0,
from /home/alex/Python/include/python3.5m/Python.h:53,
from build/src.linux-x86_64-3.5/yt/utilities/lib/geometry_utils.c:4:
/usr/lib/gcc/x86_64-redhat-linux/5.1.1/include/stdatomic.h:40:1: sorry, unimplemented: ‘_Atomic’ with OpenMP
typedef _Atomic _Bool atomic_bool;
^
changed the title [-]yt package pip compile/install error[/-][+]3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party yt module fails on Python 3.5)[/+]on Sep 17, 2015
axh commented on Sep 17, 2015
axhmannequin
MannequinAuthor
More actions
When I just comment out the
#include"pyatomic.h"
line, python 3.5.0 will no longer compile
gcc -pthread -c -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -Werror=declaration-after-statement -I. -IInclude -I./Include -DPy_BUILD_CORE -o Programs/python.o ./Programs/python.c
In file included from Include/traceback.h:8:0,
from Include/Python.h:97,
from ./Programs/python.c:3: Include/pystate.h:186:8: error: unknown type name ‘_Py_atomic_address’
PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current;
^
Makefile:747: recipe for target 'Programs/python.o' failed
make: *** [Programs/python.o] Error 1
pystate.h:
/* Assuming the current thread holds the GIL, this is the
PyThreadState for the current thread.
Issuepython/cpython#67832: pyatomic.h is incompatible with C++ (yet). Disable
PyThreadState_GET() optimization: declareitasanaliastoPyThreadState_Get(), asdoneforlimitedAPI. */
#if !defined(Py_LIMITED_API) && !defined(__cplusplus)
PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current;
#endif
"When I just comment out the << #include "pyatomic.h" >> line, python 3.5.0 will no longer compile"
Sure. My idea is to "disable" the header with we are not building Python itself. There is a nice define for that: Py_BUILD_CORE. See attached patch.
Since all symbols in pyatomic.h are prefixed by _Py, this header is fully part of the Python private API and so it's fine to modify it in a bugfix release (3.5.0 => 3.5.1).
Failed to build these modules:
_ctypes _decimal _json
_pickle
axh commented on Sep 18, 2015
axhmannequin
MannequinAuthor
More actions
So, apparently, more than just one spot needs to be fixed. I also tried just modifying the Python.h after install, but that does not do the trick either.
I created a venv with a Python patched with pyatomic-2.patch: I successfully installed yt. yt depends on numpy & Cython: good news, numpy & Cython were compiled correctly. These two libraries are well known users of the Python C API. It's not enough to check if this change breaks modules on PyPI, but it's still a good news :-)
Would there be a way to expose these internals rather than hiding them?
Here is the issue is that pyatomic.h cannot be compiled on OpenMP. We had the same issue with C++. In fact, it doesn't make sense to compile pyatomic.h differently to access an atomic variable from an extension module. We must always use exactly the same implementation, otherwise bad things will happen.
A solution for that is to hide the implementation details and only expose high level APIs.
For example, pyatomic.h must be completly hidden.
A consequence is that the _PyThreadState_Current variable must be hidden to. _PyThreadState_Current is an implementation detail, you must not access it directly.
The PyThreadState_GET() macro uses directly the _PyThreadState_Current variable. So the solution to expose the "PyThreadState_GET" symbol (not necessary as a macro) is to define it as an alias to the PyThreadState_Get() *function*.
The advantage of using a function is that we don't expose implementation details to third-party extensions, it avoids the risk of ABI incompatibilies.
Understood and agreed. Second patch looks good to me.
Cython calls PyThreadState_GET() in pretty much every helper function that deals with exceptions, but I doubt that the potential speed difference is going to be relevant in the real world. And we target CPython's API level anyway, not the ABI, so the C code will just adapt at compile time.
On 5 November 2015 at 23:01, STINNER Victor <report@bugs.python.org> wrote:
>
> STINNER Victor added the comment:
>
> "Pyatomic-2.patch solved the problem."
>
> Great! The good news is that the Python 3.5.1 release has now a schedule: https://www.python.org/dev/peps/pep-0478/
>
> "3.5.1 final: December 6, 2015"
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue25150\>
> _______________________________________
I think this should be reconsidered. I understand the desire to compile Python with OpenMP. But the resolution here is hiding _Py_atomic symbols all the time, even when OpenMP isn't involved, and even when building a standard extension module.
Case in point: if I want to include "internal/pystate.h" from _pickle.c, I get the following error:
"""
In file included from ./Include/internal/pystate.h:12:0,
from /home/antoine/cpython/default/Modules/_pickle.c:10:
./Include/internal/ceval.h:14:5: error: unknown type name ‘_Py_atomic_int’
_Py_atomic_int calls_to_do;
^
"""
Yes, why not fix this by putting the offending code under "#ifndef _OPENMP"?
What would be even better if is pyatomic.h wasn't included in Python.h, which should be fine since pyatomic.h doesn't have any public APIs. Maybe we can do that for 3.8.
(Ah, Benjamin restarted the discussion, so I reopen this issue.)
I understand the desire to compile Python with OpenMP.
I'm not sure that I understood the use case. Do you want to only compile Python core ("python3" binary") or just stdlib C extensions, or both?
But the resolution here is hiding _Py_atomic symbols all the time, even when OpenMP isn't involved, and even when building a standard extension module.
Sorry, but I don't understand the problem. Why is it an issue to hide _Py_atomic symbols?
This issue is very specific to *third party* extensions, not C extensions which are part of the standard library. That's why I asked if it wouldn't be better to open a new issue, if your use case concerns the stdlib and/or Python core.
changed the title [-]3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party yt module fails on Python 3.5)[/-][+]3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party module fails on Python 3.5)[/+]on Jul 18, 2018
Python.h does not include pyatomic.h in Python 3.8: the header file moved to the internal C API. The initial issue is fixed, so I close again the issue.
Activity
axh commentedon Sep 17, 2015
trying to install the yt package, most recent version 3.2.1 on python 3.5.0 using pip
pip3 install -U yt
error output attached. The same package installs fine with python 3.4.3, same compiler and also build from scratch, so the suspicion is that it is related to the new 3.5.0 version. The system installed is the current Fedora 22, gcc 5.1.1-4.
vstinner commentedon Sep 17, 2015
It looks like the problem is that yt uses OpenMP whereas OpenMP doesn't support atomic operations:
I'm not sure that Include/pyatomic.h should be included by the main Include/Python.h header. We already skipped Include/pyatomic.h on C++ because this header is incompatible with C++.
[-]yt package pip compile/install error[/-][+]3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party yt module fails on Python 3.5)[/+]axh commentedon Sep 17, 2015
When I just comment out the
line, python 3.5.0 will no longer compile
gcc -pthread -c -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -Werror=declaration-after-statement -I. -IInclude -I./Include -DPy_BUILD_CORE -o Programs/python.o ./Programs/python.c
In file included from Include/traceback.h:8:0,
from Include/Python.h:97,
from ./Programs/python.c:3:
Include/pystate.h:186:8: error: unknown type name ‘_Py_atomic_address’
PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current;
^
Makefile:747: recipe for target 'Programs/python.o' failed
make: *** [Programs/python.o] Error 1
pystate.h:
/* Assuming the current thread holds the GIL, this is the
PyThreadState for the current thread.
vstinner commentedon Sep 17, 2015
"When I just comment out the << #include "pyatomic.h" >> line, python 3.5.0 will no longer compile"
Sure. My idea is to "disable" the header with we are not building Python itself. There is a nice define for that: Py_BUILD_CORE. See attached patch.
Since all symbols in pyatomic.h are prefixed by _Py, this header is fully part of the Python private API and so it's fine to modify it in a bugfix release (3.5.0 => 3.5.1).
brettcannon commentedon Sep 17, 2015
If everything in the header is a _Py definition then I agree we should hide it in Python.h from the public.
axh commentedon Sep 17, 2015
(...)
Failed to build these modules:
_ctypes _decimal _json
_pickle
axh commentedon Sep 18, 2015
So, apparently, more than just one spot needs to be fixed. I also tried just modifying the Python.h after install, but that does not do the trick either.
vstinner commentedon Sep 18, 2015
Ah yes, if you check the fix for C++ (changeset cb05b6d7aacd), I also had to modify pystate.h.
Please try pyatomic-2.patch which hides more CPython internals in public headers.
vstinner commentedon Sep 18, 2015
I created a venv with a Python patched with pyatomic-2.patch: I successfully installed yt. yt depends on numpy & Cython: good news, numpy & Cython were compiled correctly. These two libraries are well known users of the Python C API. It's not enough to check if this change breaks modules on PyPI, but it's still a good news :-)
scoder commentedon Sep 18, 2015
Would there be a way to expose these internals rather than hiding them?
vstinner commentedon Sep 18, 2015
Here is the issue is that pyatomic.h cannot be compiled on OpenMP. We had the same issue with C++. In fact, it doesn't make sense to compile pyatomic.h differently to access an atomic variable from an extension module. We must always use exactly the same implementation, otherwise bad things will happen.
A solution for that is to hide the implementation details and only expose high level APIs.
For example, pyatomic.h must be completly hidden.
A consequence is that the _PyThreadState_Current variable must be hidden to. _PyThreadState_Current is an implementation detail, you must not access it directly.
The PyThreadState_GET() macro uses directly the _PyThreadState_Current variable. So the solution to expose the "PyThreadState_GET" symbol (not necessary as a macro) is to define it as an alias to the PyThreadState_Get() *function*.
The advantage of using a function is that we don't expose implementation details to third-party extensions, it avoids the risk of ABI incompatibilies.
scoder commentedon Sep 18, 2015
Understood and agreed. Second patch looks good to me.
Cython calls PyThreadState_GET() in pretty much every helper function that deals with exceptions, but I doubt that the potential speed difference is going to be relevant in the real world. And we target CPython's API level anyway, not the ABI, so the C code will just adapt at compile time.
10 remaining items
vstinner commentedon Nov 23, 2015
cool
2015-11-23 22:19 GMT+01:00 Alexander Heger <report@bugs.python.org>:
pitrou commentedon Jul 17, 2018
I think this should be reconsidered. I understand the desire to compile Python with OpenMP. But the resolution here is hiding _Py_atomic symbols all the time, even when OpenMP isn't involved, and even when building a standard extension module.
pitrou commentedon Jul 17, 2018
Case in point: if I want to include "internal/pystate.h" from _pickle.c, I get the following error:
"""
In file included from ./Include/internal/pystate.h:12:0,
from /home/antoine/cpython/default/Modules/_pickle.c:10:
./Include/internal/ceval.h:14:5: error: unknown type name ‘_Py_atomic_int’
_Py_atomic_int calls_to_do;
^
"""
pitrou commentedon Jul 17, 2018
(see bpo-34128 for context)
vstinner commentedon Jul 17, 2018
This issue is closed. Would you mind to either reopen it or create a new issue?
benjaminp commentedon Jul 18, 2018
Yes, why not fix this by putting the offending code under "#ifndef _OPENMP"?
What would be even better if is pyatomic.h wasn't included in Python.h, which should be fine since pyatomic.h doesn't have any public APIs. Maybe we can do that for 3.8.
vstinner commentedon Jul 18, 2018
(Ah, Benjamin restarted the discussion, so I reopen this issue.)
I'm not sure that I understood the use case. Do you want to only compile Python core ("python3" binary") or just stdlib C extensions, or both?
Sorry, but I don't understand the problem. Why is it an issue to hide _Py_atomic symbols?
vstinner commentedon Jul 18, 2018
This issue is very specific to *third party* extensions, not C extensions which are part of the standard library. That's why I asked if it wouldn't be better to open a new issue, if your use case concerns the stdlib and/or Python core.
[-]3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party yt module fails on Python 3.5)[/-][+]3.5: Include/pyatomic.h is incompatible with OpenMP (compilation of the third-party module fails on Python 3.5)[/+]vstinner commentedon Jun 5, 2020
Python.h does not include pyatomic.h in Python 3.8: the header file moved to the internal C API. The initial issue is fixed, so I close again the issue.