Code Monkey home page Code Monkey logo

nogil's Introduction

Python Multithreading without GIL

Copyright (c) 2001-2022 Python Software Foundation. All rights reserved.

See Doc/license.rst for copyright and license information.

Overview

This is a proof-of-concept implementation of CPython that supports multithreading without the global interpreter lock (GIL). An overview of the design is described in the Python Multithreading without GIL Google doc.

Installation

The proof-of-concept works best on Linux x86-64. It also builds on macOS, Linux ARM64, and Windows (64-bit), but you will have to recompile extension modules yourself for these platforms.

Install with pyenv

First you need to install pyenv on Linux or on macOS . To install the "nogil-3.9.10-1" version:

pyenv install nogil-3.9.10-1

You can make the nogil installation the default Python installation with:

pyenv global nogil-3.9.10-1

Docker

A pre-built Docker image nogil/python is available on Docker Hub. For CUDA support, use nogil/python-cuda.
For arm64 devices, use nogil/python-arm64.

For example:

docker run -it nogil/python

Build from source

The build process has not changed from upstream CPython. See https://devguide.python.org/ for instructions on how to build from source, or follow the steps below.

Install:

./configure [--prefix=PREFIX] [--enable-optimizations]
make -j
make install

The optional --prefix=PREFIX specifies the destination directory for the Python installation. The optional --enable-optimizations enables profile guided optimizations (PGO). This slows down the build process, but makes the compiled Python a bit faster.

Packages

Use pip install <package> as usual to install packages. Please file an issue if you are unable to install a pip package you would like to use.

The proof-of-concept comes with a modified bundled "pip" that includes an alternative package index. The alternative package index includes C extensions that are either slow to build from source or require some modifications for compatibility.

GIL control

The GIL is disabled by default, but if you wish, you can enable it at runtime using the environment variable PYTHONGIL=1. You can check if the GIL is disabled from Python by accessing sys.flags.nogil:

python3 -c "import sys; print(sys.flags.nogil)"  # True
PYTHONGIL=1 python3 -c "import sys; print(sys.flags.nogil)"  # False

Example

You can use the existing Python APIs, such as the threading module and the ThreadPoolExecutor class.

Here is an example based on Larry Hastings's Gilectomy benchmark:

import sys
from concurrent.futures import ThreadPoolExecutor

print(f"nogil={getattr(sys.flags, 'nogil', False)}")

def fib(n):
    if n < 2: return 1
    return fib(n-1) + fib(n-2)

threads = 8
if len(sys.argv) > 1:
    threads = int(sys.argv[1])

with ThreadPoolExecutor(max_workers=threads) as executor:
    for _ in range(threads):
        executor.submit(lambda: print(fib(34)))

Run it with, e.g.:

time python3 fib.py 1   # 1 thread, 1x work
time python3 fib.py 20  # 20 threads, 20x work

The program parallelizes well up to the number of available cores. On a 20 core Intel Xeon E5-2698 v4 one thread takes 1.50 seconds and 20 threads take 1.52 seconds [1].

[1] Turbo boost was disabled to measure the scaling of the program without the effects of CPU frequency scaling. Additionally, you may get more reliable measurements by using taskset to avoid virtual "hyperthreading" cores.

nogil's People

Contributors

1st1 avatar akuchling avatar benjaminp avatar berkerpeksag avatar birkenfeld avatar bitdancer avatar brettcannon avatar ezio-melotti avatar freddrake avatar gpshead avatar gvanrossum avatar gward avatar jackjansen avatar jeremyhylton avatar loewis avatar mdickinson avatar merwok avatar miss-islington avatar ned-deily avatar nnorwitz avatar orsenthil avatar pitrou avatar rhettinger avatar serhiy-storchaka avatar terryjreedy avatar tim-one avatar tiran avatar vsajip avatar vstinner avatar warsaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nogil's Issues

Can not install cffi using poetry

I just tried to use nogil on my side project, and found out there is an error when installing cffi. Seems like there is a confict between nogil and CPython.

Origin error message as following,

Installing cffi (1.15.0): Failed

  EnvCommandError

  Command ['/workspace/.venv/bin/pip', 'install', '--no-deps', 'file:///root/.cache/pypoetry/artifacts/20/b6/2f/d86d84b144949a7c7435d77e30e4731b66f07f492faac0f75b18bebca7/cffi-1.15.0.tar.gz'] errored with the following return code 1, and output: 
  Processing /root/.cache/pypoetry/artifacts/20/b6/2f/d86d84b144949a7c7435d77e30e4731b66f07f492faac0f75b18bebca7/cffi-1.15.0.tar.gz
  Building wheels for collected packages: cffi
    Building wheel for cffi (setup.py): started
    Building wheel for cffi (setup.py): finished with status 'error'
    ERROR: Command errored out with exit status 1:
     command: /workspace/.venv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-ned2bb9p/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-ned2bb9p/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-fies3lsc
         cwd: /tmp/pip-req-build-ned2bb9p/
    Complete output (36 lines):
    running bdist_wheel
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.9
    creating build/lib.linux-x86_64-3.9/cffi
    copying cffi/commontypes.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/cparser.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/model.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/cffi_opcode.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/recompiler.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/pkgconfig.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/api.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/verifier.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/backend_ctypes.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/vengine_cpy.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/__init__.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/setuptools_ext.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/ffiplatform.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/vengine_gen.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/lock.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/error.py -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/_cffi_include.h -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/parse_c_type.h -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/_embedding.h -> build/lib.linux-x86_64-3.9/cffi
    copying cffi/_cffi_errors.h -> build/lib.linux-x86_64-3.9/cffi
    running build_ext
    building '_cffi_backend' extension
    creating build/temp.linux-x86_64-3.9
    creating build/temp.linux-x86_64-3.9/c
    gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/workspace/.venv/include -I/usr/local/include/python3.9 -c c/_cffi_backend.c -o build/temp.linux-x86_64-3.9/c/_cffi_backend.o
    c/_cffi_backend.c: In function ‘get_unique_type’:
    c/_cffi_backend.c:4638:20: error: ‘PyObject’ {aka ‘struct _object’} has no member named ‘ob_refcnt’
     4638 |     ((PyObject *)x)->ob_refcnt--;
          |                    ^~
    error: command 'gcc' failed with exit status 1
    ----------------------------------------
    ERROR: Failed building wheel for cffi
    Running setup.py clean for cffi
  Failed to build cffi
  Installing collected packages: cffi
      Running setup.py install for cffi: started
      Running setup.py install for cffi: finished with status 'error'
      ERROR: Command errored out with exit status 1:
       command: /workspace/.venv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-ned2bb9p/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-ned2bb9p/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-e26e6dwz/install-record.txt --single-version-externally-managed --compile --install-headers /workspace/.venv/include/site/python3.9/cffi
           cwd: /tmp/pip-req-build-ned2bb9p/
      Complete output (36 lines):
      running install
      running build
      running build_py
      creating build
      creating build/lib.linux-x86_64-3.9
      creating build/lib.linux-x86_64-3.9/cffi
      copying cffi/commontypes.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/cparser.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/model.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/cffi_opcode.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/recompiler.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/pkgconfig.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/api.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/verifier.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/backend_ctypes.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/vengine_cpy.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/__init__.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/setuptools_ext.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/ffiplatform.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/vengine_gen.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/lock.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/error.py -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/_cffi_include.h -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/parse_c_type.h -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/_embedding.h -> build/lib.linux-x86_64-3.9/cffi
      copying cffi/_cffi_errors.h -> build/lib.linux-x86_64-3.9/cffi
      running build_ext
      building '_cffi_backend' extension
      creating build/temp.linux-x86_64-3.9
      creating build/temp.linux-x86_64-3.9/c
      gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/workspace/.venv/include -I/usr/local/include/python3.9 -c c/_cffi_backend.c -o build/temp.linux-x86_64-3.9/c/_cffi_backend.o
      c/_cffi_backend.c: In function ‘get_unique_type’:
      c/_cffi_backend.c:4638:20: error: ‘PyObject’ {aka ‘struct _object’} has no member named ‘ob_refcnt’
       4638 |     ((PyObject *)x)->ob_refcnt--;
            |                    ^~
      error: command 'gcc' failed with exit status 1
      ----------------------------------------
  ERROR: Command errored out with exit status 1: /workspace/.venv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-ned2bb9p/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-ned2bb9p/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-e26e6dwz/install-record.txt --single-version-externally-managed --compile --install-headers /workspace/.venv/include/site/python3.9/cffi Check the logs for full command output.
  WARNING: You are using pip version 21.2.4; however, version 21.3 is available.
  You should consider upgrading via the '/workspace/.venv/bin/python -m pip install --upgrade pip' command.
  

  at /usr/local/lib/python3.9/site-packages/poetry/utils/env.py:1183 in _run
      1179│                 output = subprocess.check_output(
      1180│                     cmd, stderr=subprocess.STDOUT, **kwargs
      1181│                 )
      1182│         except CalledProcessError as e:
    → 1183│             raise EnvCommandError(e, input=input_)
      1184│ 
      1185│         return decode(output)
      1186│ 
      1187│     def execute(self, bin, *args, **kwargs):

Celery: Segmentation fault on set_pdeathsig

test_process_initializer is crashing the interpreter.

See code here: https://github.com/celery/celery/blob/24f22a5dac7c5282e59f547112a1799156382f0e/t/unit/concurrency/test_prefork.py#L66-L98

Fatal Python error: Segmentation fault

Current thread 0x00007fa20fc1b740 (most recent call first):
  File "/home/omer/.pyenv/versions/nogil-3.9.9/lib/python3.9/unittest/mock.py", line 491 in _mock_add_spec
  File "/home/omer/.pyenv/versions/nogil-3.9.9/lib/python3.9/unittest/mock.py", line 437 in __init__
  File "/home/omer/.pyenv/versions/nogil-3.9.9/lib/python3.9/unittest/mock.py", line 1074 in __init__
  File "/home/omer/.pyenv/versions/nogil-3.9.9/lib/python3.9/unittest/mock.py", line 2034 in __init__
  File "/home/omer/.pyenv/versions/nogil-3.9.9/lib/python3.9/unittest/mock.py", line 1018 in _get_child_mock
  File "/home/omer/.pyenv/versions/nogil-3.9.9/lib/python3.9/unittest/mock.py", line 648 in __getattr__
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/billiard/util.py", line 216 in set_pdeathsig
  File "/home/omer/Documents/Projects/celery/celery/platforms.py", line 716 in set_pdeathsig
  File "/home/omer/Documents/Projects/celery/celery/concurrency/prefork.py", line 45 in process_initializer
  File "/home/omer/Documents/Projects/celery/t/unit/concurrency/test_prefork.py", line 75 in test_process_initializer
  File "/home/omer/.pyenv/versions/nogil-3.9.9/lib/python3.9/unittest/mock.py", line 1336 in patched
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/python.py", line 192 in pytest_pyfunc_call
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/python.py", line 1761 in runtest
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/runner.py", line 166 in pytest_runtest_call
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/runner.py", line 259 in <lambda>
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/runner.py", line 338 in from_call
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/runner.py", line 258 in call_runtest_hook
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/runner.py", line 219 in call_and_report
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/runner.py", line 130 in runtestprotocol
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/runner.py", line 111 in pytest_runtest_protocol
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/main.py", line 347 in pytest_runtestloop
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/main.py", line 322 in _main
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/main.py", line 268 in wrap_session
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/main.py", line 315 in pytest_cmdline_main
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/config/__init__.py", line 164 in main
  File "/home/omer/.virtualenvs/celery-nogil/lib/python3.9/site-packages/_pytest/config/__init__.py", line 187 in console_main
  File "/home/omer/.virtualenvs/celery-nogil/bin/pytest", line 8 in <module>
Segmentation fault (core dumped)

Segfault in multithreaded Cython code in memoryview __dealloc__ in scikit-learn

Here is the original reproducer:

pip install cython numpy scipy pytest
git clone https://github.com/scikit-learn/scikit-learn
cd scikit-learn
python setup.py develop
gdb --ex r --args python -m pytest -svlx -k "test_parallel[RandomForestClassifier]" sklearn/ensemble/tests/test_forest.py
Fatal Python error: Aborted

Stack (most recent call first):
  File "/home/ogrisel/code/scikit-learn/sklearn/tree/_classes.py", line 964 in fit
  File "/home/ogrisel/code/scikit-learn/sklearn/ensemble/_forest.py", line 189 in _parallel_build_trees
  File "/home/ogrisel/code/scikit-learn/sklearn/utils/fixes.py", line 117 in __call__
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/parallel.py", line 262 in <listcomp>
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/parallel.py", line 262 in __call__
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/_parallel_backends.py", line 595 in __call__
  File "/home/ogrisel/code/nogil/Lib/multiprocessing/pool.py", line 125 in worker
  File "/home/ogrisel/code/nogil/Lib/threading.py", line 886 in run
  File "/home/ogrisel/code/nogil/Lib/threading.py", line 935 in _bootstrap_inner
  File "/home/ogrisel/code/nogil/Lib/threading.py", line 906 in _bootstrap

Note that in this code, joblib is using simple Python-level threads instead of Python worker processes.

with either of the following GDB backtraces:

#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737175123520) at pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737175123520) at pthread_kill.c:80
#2  __GI___pthread_kill (threadid=140737175123520, signo=signo@entry=6) at pthread_kill.c:91
#3  0x00007ffff7ce6476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7ccc7b7 in __GI_abort () at abort.c:79
#5  0x00007ffff7d2d606 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff7e7f13d "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007ffff7d44afc in malloc_printerr (str=str@entry=0x7ffff7e81d18 "double free or corruption (fasttop)") at malloc.c:5543
#7  0x00007ffff7d463bb in _int_free (av=0x7ffff7ebdc60 <main_arena>, p=0x5555559e8c80, have_lock=0) at malloc.c:4426
#8  0x00007ffff7d48d05 in __GI___libc_free (mem=<optimized out>) at malloc.c:3278
#9  0x00007ffff0fbb0e2 in __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__ (__pyx_v_self=0x44e5aa10790) at sklearn/tree/_tree.cpp:28305
#10 __pyx_memoryview___dealloc__ (__pyx_v_self=<sklearn.tree._tree.memoryview at remote 0x44e5aa10790>) at sklearn/tree/_tree.cpp:28112
#11 __pyx_tp_dealloc_memoryview (o=<sklearn.tree._tree.memoryview at remote 0x44e5aa10790>) at sklearn/tree/_tree.cpp:39929
#12 0x00007ffff1070177 in _Py_DECREF (op=<optimized out>) at /home/ogrisel/code/nogil/Include/object.h:569
#13 __Pyx_XDEC_MEMVIEW (lineno=24909, have_gil=1, memslice=0x44e5aa00520) at sklearn/tree/_criterion.c:28987
#14 __pyx_tp_dealloc_7sklearn_4tree_10_criterion_Criterion (o=<sklearn.tree._criterion.Gini at remote 0x44e5aa00500>) at sklearn/tree/_criterion.c:24909
#15 __pyx_tp_dealloc_7sklearn_4tree_10_criterion_ClassificationCriterion (o=<sklearn.tree._criterion.Gini at remote 0x44e5aa00500>) at sklearn/tree/_criterion.c:25026

at another run I got the following backtrace:

#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737191908928) at pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737191908928) at pthread_kill.c:80
#2  __GI___pthread_kill (threadid=140737191908928, signo=signo@entry=6) at pthread_kill.c:91
#3  0x00007ffff7ce6476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7ccc7b7 in __GI_abort () at abort.c:79
#5  0x00007ffff7d2d606 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff7e7f13d "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007ffff7d44afc in malloc_printerr (str=str@entry=0x7ffff7e81cc0 "free(): double free detected in tcache 2") at malloc.c:5543
#7  0x00007ffff7d46a4f in _int_free (av=0x7ffff7ebdc60 <main_arena>, p=0x5555559e8520, have_lock=0) at malloc.c:4360
#8  0x00007ffff7d48d05 in __GI___libc_free (mem=<optimized out>) at malloc.c:3278
#9  0x00007ffff102f352 in __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__ (__pyx_v_self=0x4fb1d220850) at sklearn/tree/_splitter.c:16407
#10 __pyx_memoryview___dealloc__ (__pyx_v_self=<sklearn.tree._splitter.memoryview at remote 0x4fb1d220850>) at sklearn/tree/_splitter.c:16214
#11 __pyx_tp_dealloc_memoryview (o=<sklearn.tree._splitter.memoryview at remote 0x4fb1d220850>) at sklearn/tree/_splitter.c:27573
#12 0x00007ffff10318b5 in _Py_DECREF (op=<optimized out>) at /home/ogrisel/code/nogil/Include/object.h:569
#13 __Pyx_XDEC_MEMVIEW (lineno=26682, have_gil=1, memslice=0x4fb1d230400) at sklearn/tree/_splitter.c:29899
#14 __pyx_tp_dealloc_7sklearn_4tree_9_splitter_BaseDenseSplitter (o=<sklearn.tree._splitter.BestSplitter at remote 0x4fb1d230290>) at sklearn/tree/_splitter.c:26682
#15 0x000055555581315c in _PyEval_Fast (ts=0x555555ad8540, initial_acc=Register(as_int64 = 8), initial_pc=0x17 <error: Cannot access memory at address 0x17>) at Python/ceval.c:1125

So in both cases this is occurring in the __dealloc__ method of a Cython managed memoryview but from 2 different Cython files in the scikit-learn source code.

Note: I installed the nogil wheels for numpy, scipy and Cython with pip:

  • Cython 0.29.26
  • NumPy 1.22.3
  • SciPy 1.7.1

If you want I can try to spend time to craft a minimal reproducer using only Cython (and probably numpy) without scikit-learn.

Is it possible to trick Numpy as having GIL?

Python nogil builds OK, with Pip. But Numpy won't compile (I have to compile coz pip can't find a suitable Numpy prebuilt).

Numpy build error:

numpy/core/src/multiarray/shape.c: In function ‘PyArray_Resize’:
numpy/core/include/numpy/ndarrayobject.h:102:51: error: ‘PyObject’ {aka ‘struct _object’} has no member named ‘ob_refcnt’
    102 | #define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
        |                                                   ^~
numpy/core/src/multiarray/shape.c:108:22: note: in expansion of macro ‘PyArray_REFCOUNT’
    108 |             refcnt = PyArray_REFCOUNT(self);

I guess the Python nogil source code has removed that variable ob_refcnt, and Numpy without doubts won't compile. Is it possible to trick that Numpy about the variables about GIL it needs?

Assorted observations

Disclaimer: I would not, by any means, call myself an expert at either concurrency or CPython. Nonetheless, several things jumped out at me (a couple of which are quite concerning; others of which are quibbles, guesses, or random ideas)

This is a mixture of feedback on the design document (mostly in order) and the implementation (randomly).

I've done this as a single post with checkboxes, since I feel that's best at least for first glance. Feel free to split parts off into separate issues, or edit it if checkboxes aren't enough.


  •  

Replacing Py_INCREF and Py_DECREF with atomic variants would result in a 60% average slowdown on the pyperformance benchmark suite.

Really? What exactly are you comparing here? It can't be "just use atomic operations; keep the GIL for now", since that would have <2% performance impact (since the GIL makes you uncontended) even if literally every instruction was a refcount change. And it can't be "use atomic operations and ignore the GIL" because of all the C method implementations that must be made atomic.


  •  

To avoid the possibility of false sharing between unrelated objects (is it worth it?), you must guarantee either:

  • all (non-immortal) object allocations are rounded up to a minimum of 64 bytes (or whatever the cacheline size is)
    • remember that you're increasing the default object size already in your patch.
    • note that dict already exceeds this on vanilla CPython (at least on 64-bit platforms), and dict outnumbers ordinary objects (since they all have a dict). The biggest loser is probably int
  • the allocator only ever hands out a given cacheline to the same thread
    • some allocators do this semi-accidentally as part of improving their own multithreaded performance; this may or may not apply if the memory is later freed then reused.

Do you have to worry about false sharing between the local and shared refcounts that are right next to each other? Thinking particularly about the case of exactly 2 threads, which wouldn't be contending if the local count was stored indirectly.


  •  

What fraction of refcount calls are to immortal objects (also, talk about gc.freeze)? Even though most objects aren't immortal, the immortal objects are by far the most common... It's unfortunate that we have to choose between "optimize for branch prediction" and "optimize for memory accesses" ... since your code is more than a simple branch, we might also have to care about how multiple branches are predicted.


  •  

Use of uint32_t for refcounts is scary, especially when you're stealing 2 bits from it. Making an 8GB list (or multiple smaller ones) is quite doable (about 5 seconds) on current systems: [object()] * 2**30 (warning: double-check your free RAM before testing that).


  •  

Is it really necessary to do a full-blown CAS, rather than an acq_rel sub?


  •  

Use of non-_explicit atomic operations is almost always a bug. Particularly, that means you're using seq_cst semantics for (shared) incref even though it only needs relaxed (since you already own a reference, you don't have to worry about the last reference disappearing. I admit to not knowing how biased locking affects this)!


  •  

Casting to atomic is UB, and since the variables are newly-introduced here, it should be avoidable by using the correct type in the first place.


  •  

Wouldn't this be a great opportunity to say "we no longer support compilers that haven't been updated since 2011" and just write it in C11 without all the wrappers? Or at least just use a drop-in implementation of <stdatomic.h>?


  •  

If putting a deferred object on the stack doesn't increase the refcount, what happens you then call back into Python code that nukes the reference and then invokes the GC? (If this is impossible, prove it, since you've eliminated the usual (universal) guarantee)


  •  

If you force a single allocator (which is not a bad idea, really), you should address what happens to lower-level allocator replacements like AddressSanitizer uses ... I think the fact that it calls mmap should suffice, but this should be explicitly tested and documented.


  •  

This design is implemented for the list and dict classes

Why, oh why, must set always be a second-class citizen?


  •  

re-used for other Python objects of the same size

really "same size **class" or maybe "same size, as rounded up for allocation purposes" since you haven't introduced that term yet. Really, all that matters is that the start of the object never becomes the middle of a different object.


  •  

C11 acquire-release semantics (or stronger) to ensure proper ordering. This is “free” on x86-64: these accesses are compiled to plain load and store instructions

It's worth noting that this only applies to simple loads and stores, not to things like add (let alone CAS). And it's hard to implement a concurrent algorithm using only atomic stores. I would phrase it something like "loads are free; stores are free but require taking the (much more expensive) lock anyway"


  •  

stores a Python object pointer tagged with least-significant-bit set

There's another alternate approach: there are two "arrays" - one of ordinary objects, and a separate dynamic_bitset - then use the same index to access the related items from each. This uses 1/64 more memory but avoids the masking.

(this is very similar to the rule "prefer struct of arrays, not array of structs")


  •  

I'm rather skeptical of all the asm this adds (especially that return 0; fallback; yikes! Better to #error than leave that kind of landmine).

With a modern compiler you can almost always coerce it into generating optimal code without it, so any asm block should have a justification of not just why it is correct, but why you haven't been able to do it properly.

crash with CFFI

Hi, I am trying to use nogil Python within a C application that calls Python code via CFFI.
While CFFI is installed successfully with pip install cffi, there is an error while initialising it.

import cffi runs successfully
but ffibuilder = cffi.FFI() raises the following error:

Modules/gcmodule.c:879: move_unreachable: Assertion "gc_get_refs(gc) >= 0" failed: refcount is too small
Enable tracemalloc to get the memory block allocation traceback

object address  : 0x4779ea71390
object refcount : 999
object local    : 1
object shared   : 0
object tid      : 0x7fc386a5f740
object type     : 0x7fc386a2ff00
object type name: _cffi_backend.CType
object repr     : <ctype 'void'>
object gc_refs  : -1

referrer: obj=0x4779ea71410 (type=_cffi_backend.CType) gc_get_refs=0 ob_ref_local=1 ob_ref_shared=0 ob_tid=0x7fc386a5f740

Fatal Python error: _PyObject_AssertFailed: _PyObject_AssertFailed
Python runtime state: initialized

Current thread 0x00007fc386a5f740 (most recent call first):
  File "<frozen importlib._bootstrap_external>", line 648 in _compile_bytecode
  File "<frozen importlib._bootstrap_external>", line 979 in get_code
  File "<frozen importlib._bootstrap_external>", line 847 in exec_module
  File "<frozen importlib._bootstrap>", line 681 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 988 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1009 in _find_and_load
  File "<frozen importlib._bootstrap>", line 228 in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1060 in _handle_fromlist
  File "/home/johnfouf/.local/lib/python3.9/site-packages/pycparser/c_parser.py", line 9 in <module>
  File "<frozen importlib._bootstrap>", line 228 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 851 in exec_module
  File "<frozen importlib._bootstrap>", line 681 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 988 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1009 in _find_and_load
  File "/home/johnfouf/.local/lib/python3.9/site-packages/pycparser/__init__.py", line 15 in <module>
  File "<frozen importlib._bootstrap>", line 228 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 851 in exec_module
  File "<frozen importlib._bootstrap>", line 681 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 988 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1009 in _find_and_load
  File "/home/johnfouf/.local/lib/python3.9/site-packages/cffi/cparser.py", line 7 in <module>
  File "<frozen importlib._bootstrap>", line 228 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 851 in exec_module
  File "<frozen importlib._bootstrap>", line 681 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 988 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1009 in _find_and_load
  File "<frozen importlib._bootstrap>", line 228 in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1060 in _handle_fromlist
  File "/home/johnfouf/.local/lib/python3.9/site-packages/cffi/api.py", line 65 in __init__
  File "<stdin>", line 1 in <module>
Aborted (core dumped)

dis.hasjrel and other opcode collections missing

>>> dis.hasjrel
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'dis' has no attribute 'hasjrel'

In particular this causes problems with using llvmlite/numba in conjunction with this python fork.
These are part of the nominal python distribution but it looks like this part of the code had to be significantly altered for the nogil changes.
https://docs.python.org/3.9/library/dis.html#opcode-collections
If it's not too hard to add these collections back in I may send a pull request, but if it's deeper than that I'd like to hear your thoughts on this!

Add multiprocess benchmark

Since concurrency using threads is in some way competing with multiprocess I think it makes sense to add a benchmark for that as well like how much time it takes for 20 threads vs 20 process to do the simple fib task. Obviously there are other benefits but one of the reasons to have multi threaded concurrency is its less resource intensive to start new threads compared to processes

Track a more recent upstream version of CPython that supports the Apple M1 platform?

I would like to test this experimental branch on a regular basis on my Apple M1 dev laptop when working on the Scientific Python / PyData related projects so as to be able to report problems or performance improvements encountered with practical application cases.

However the build setup in this branch is a bit too old and the configure refuses to generate the Makefile for this platform:

./configure --with-openssl=$(brew --prefix openssl)
checking for git... found
checking build system type... Invalid configuration `arm64-apple-darwin20.0.0': machine `arm64-apple' not recognized
configure: error: /bin/sh ./config.sub arm64-apple-darwin20.0.0 failed

Would it be possible to sync with branch with a more recent version of CPython (e.g. 3.10)?

EDIT: the error above was probably observed with a version of clang installed from conda-forge. I get a different error at build time when using the system compiler instead, see the discussion below: #36 (comment)

Does not pass all regression tests

With the last commit 703a299d9f412b38caf3d2301d1a365135b66bff of nogil, test command is like:

python -m test.regrtest

and breaking at:

0:08:13 load avg: 3.72 [ 48/418/3] test_capi
test_buildvalue_N (test.test_capi.CAPITest) ... ok
test_c_subclass_of_heap_ctype_with_del_modifying_dunder_class_only_decrefs_once (test.test_capi.CAPITest) ... ok
test_c_subclass_of_heap_ctype_with_tpdealloc_decrefs_once (test.test_capi.CAPITest) ... ok
test_c_type_with_ipow (test.test_capi.CAPITest) ... ok
test_c_type_with_matrix_multiplication (test.test_capi.CAPITest) ... ok
test_docstring_signature_parsing (test.test_capi.CAPITest) ... ok
test_exc_info (test.test_capi.CAPITest) ... FAIL
test_heaptype_with_dict (test.test_capi.CAPITest) ... ok
test_heaptype_with_negative_dict (test.test_capi.CAPITest) ... ok
test_heaptype_with_weakref (test.test_capi.CAPITest) ... ok
test_instancemethod (test.test_capi.CAPITest) ... ok
test_mapping_keys_values_items (test.test_capi.CAPITest) ... ok
test_mapping_keys_values_items_bad_arg (test.test_capi.CAPITest) ... ok
test_memoryview_from_NULL_pointer (test.test_capi.CAPITest) ... ok
test_negative_refcount (test.test_capi.CAPITest) ... skipped 'need _testcapi.negative_refcount'
test_no_FatalError_infinite_loop (test.test_capi.CAPITest) ... ok
test_return_null_without_error (test.test_capi.CAPITest) ... Fatal Python error: Segmentation fault

Current thread 0x00007fb1dbb25740 (most recent call first):
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/test_capi.py", line 211 in test_return_null_without_error
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/case.py", line 616 in _callTestMethod
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/case.py", line 659 in run
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/case.py", line 719 in __call__
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/suite.py", line 122 in run
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/suite.py", line 84 in __call__
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/suite.py", line 122 in run
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/suite.py", line 84 in __call__
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/suite.py", line 122 in run
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/suite.py", line 84 in __call__
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/unittest/runner.py", line 176 in run
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/support/__init__.py", line 2079 in _run_suite
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/support/__init__.py", line 2201 in run_unittest
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/runtest.py", line 209 in _test_module
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/runtest.py", line 234 in _runtest_inner2
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/runtest.py", line 270 in _runtest_inner
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/runtest.py", line 153 in _runtest
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/runtest.py", line 193 in runtest
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/main.py", line 417 in run_tests_sequential
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/main.py", line 515 in run_tests
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/main.py", line 687 in _main
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/main.py", line 634 in main
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/libregrtest/main.py", line 712 in main
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/regrtest.py", line 43 in _main
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/test/regrtest.py", line 47 in <module>
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/runpy.py", line 86 in _run_code
  File "/zdata/abs/local/nogil/src/nogil-703a299d9f412b38caf3d2301d1a365135b66bff/Lib/runpy.py", line 193 in _run_module_as_main
/zdata/abs/local/nogil/PKGBUILD: line 74: 130021 Segmentation fault      (core dumped) LD_LIBRARY_PATH="${srcdir}/${pkgname}-${_commit}":${LD_LIBRARY_PATH} LC_CTYPE=en_US.UTF-8 "${srcdir}/${pkgname}-${_commit}/python" -m test.regrtest -v -uall -x test_tk -x test_ttk_guionly
==> ERROR: A failure occurred in check().
    Aborting...

Using the scripts from the official python package of Arch Linux on Arch Linux x86_64:
https://github.com/archlinux/svntogit-packages/tree/packages/python/trunk
(current commit a1ae1728730878a4436be1538880d1ab39367e72)

[Question] Can this nogil implementation also provide improvements for asyncio?

So I was wondering if there is a chance to improve asyncio alongside nogil or maybe nogil already improves asyncio? (like threadpool offloading or sth?)

I was also wondering if now one could do something like lightweight processes inside Python with scheduler - similar to Erlang ?
I am really not sure if this question makes sense.
I am sorry if this is confusing or I said something wrong, I might not understand nogil correctly, or even how Python internally works.

Memory leak when using nogil Cython

Code to reproduce:

pip install numpy scipy cython psutil
git clone https://github.com/scikit-learn/scikit-learn
cd scikit-learn
pip install -e .
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.datasets import make_classification
import psutil
import gc


X, y = make_classification(n_samples=int(1e4), random_state=42)
print(f"data size: {X.nbytes / 1e6:.1f} MB")

for i in range(5):
    clf = HistGradientBoostingClassifier(max_iter=100).fit(X, y)
    gc.collect()
    print(f"memory usage: {psutil.Process().memory_info().rss / 1e6:.1f} MB")

Using nogil-Cython build of scikit-learn: CPython

$ OPENMP_NUM_THREADS=1 python ~/code/sanbox/debug_memleak.py 
data size: 1.6 MB
memory usage: 701.8 MB
memory usage: 1290.5 MB
memory usage: 1878.0 MB
memory usage: 2466.0 MB
memory usage: 3053.4 MB

Using scikit-learn installed from conda-forge

$ OPENMP_NUM_THREADS=1 python ~/code/sanbox/debug_memleak.py 
data size: 1.6 MB
memory usage: 124.6 MB
memory usage: 124.6 MB
memory usage: 125.1 MB
memory usage: 125.1 MB
memory usage: 125.1 MB

Note: this code is using OpenMP-based threading but the leak still happens when disabling the OpenMP threading layer by setting OPENMP_NUM_THREADS=1 so this problem is probably not related to OpenMP.

Note sure how to debug this. Maybe I could try to use valgrind.

Can't compile CFFI on Ubuntu 20.04

|       Building wheels for collected packages: cffi
|         Building wheel for cffi (setup.py): started
|         Building wheel for cffi (setup.py): finished with status 'error'
|         error: subprocess-exited-with-error
|       
|         × python setup.py bdist_wheel did not run successfully.
|         │ exit code: 1
|         ╰─> [36 lines of output]
|             running bdist_wheel
|             running build
|             running build_py
|             creating build
|             creating build/lib.linux-x86_64-3.9
|             creating build/lib.linux-x86_64-3.9/cffi
|             copying cffi/verifier.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/backend_ctypes.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/vengine_cpy.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/recompiler.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/cparser.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/setuptools_ext.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/vengine_gen.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/api.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/commontypes.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/pkgconfig.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/lock.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/cffi_opcode.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/__init__.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/error.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/ffiplatform.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/model.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/_cffi_include.h -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/parse_c_type.h -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/_embedding.h -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/_cffi_errors.h -> build/lib.linux-x86_64-3.9/cffi
|             running build_ext
|             building '_cffi_backend' extension
|             creating build/temp.linux-x86_64-3.9
|             creating build/temp.linux-x86_64-3.9/c
|             gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/Users/okatz6/Documents/celery/.tox/3.9-unit/include -I/opt/hostedtoolcache/pyenv_root/2.2.4/x64/versions/nogil-3.9.9/include/python3.9 -c c/_cffi_backend.c -o build/temp.linux-x86_64-3.9/c/_cffi_backend.o
|             c/_cffi_backend.c: In function ‘get_unique_type’:
|             c/_cffi_backend.c:4638:20: error: ‘PyObject’ {aka ‘struct _object’} has no member named ‘ob_refcnt’
|              4638 |     ((PyObject *)x)->ob_refcnt--;
|                   |                    ^~
|             error: command '/usr/bin/gcc' failed with exit code 1
|             [end of output]
|       
|         note: This error originates from a subprocess, and is likely not a problem with pip.
|         ERROR: Failed building wheel for cffi
|         Running setup.py clean for cffi
|       Failed to build cffi
|       Installing collected packages: wheel, typing-extensions, setuptools, semantic-version, pycparser, setuptools-rust, cffi
|         Running setup.py install for cffi: started
|         Running setup.py install for cffi: finished with status 'error'
|         error: subprocess-exited-with-error
|       
|         × Running setup.py install for cffi did not run successfully.
|         │ exit code: 1
|         ╰─> [38 lines of output]
|             running install
|             /Users/okatz6/Documents/celery/.tox/3.9-unit/lib/python3.9/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
|               warnings.warn(
|             running build
|             running build_py
|             creating build
|             creating build/lib.linux-x86_64-3.9
|             creating build/lib.linux-x86_64-3.9/cffi
|             copying cffi/verifier.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/backend_ctypes.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/vengine_cpy.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/recompiler.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/cparser.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/setuptools_ext.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/vengine_gen.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/api.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/commontypes.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/pkgconfig.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/lock.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/cffi_opcode.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/__init__.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/error.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/ffiplatform.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/model.py -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/_cffi_include.h -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/parse_c_type.h -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/_embedding.h -> build/lib.linux-x86_64-3.9/cffi
|             copying cffi/_cffi_errors.h -> build/lib.linux-x86_64-3.9/cffi
|             running build_ext
|             building '_cffi_backend' extension
|             creating build/temp.linux-x86_64-3.9
|             creating build/temp.linux-x86_64-3.9/c
|             gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/Users/okatz6/Documents/celery/.tox/3.9-unit/include -I/opt/hostedtoolcache/pyenv_root/2.2.4/x64/versions/nogil-3.9.9/include/python3.9 -c c/_cffi_backend.c -o build/temp.linux-x86_64-3.9/c/_cffi_backend.o
|             c/_cffi_backend.c: In function ‘get_unique_type’:
|             c/_cffi_backend.c:4638:20: error: ‘PyObject’ {aka ‘struct _object’} has no member named ‘ob_refcnt’
|              4638 |     ((PyObject *)x)->ob_refcnt--;
|                   |                    ^~
|             error: command '/usr/bin/gcc' failed with exit code 1
|             [end of output]
|       
|         note: This error originates from a subprocess, and is likely not a problem with pip.
|       error: legacy-install-failure
|       
|       × Encountered error while trying to install package.
|       ╰─> cffi
|       
|       note: This is an issue with the package mentioned above, not pip.
|       hint: See above for output from the failure.
|       [end of output]

Segfault with profiling a scikit-learn pipeline with viztracer

The following happens when using the issue56 branch as discussed in #56.

$ viztracer --tracer_entries 10000002 ~/code/sanbox/spline_pipeline_randomized_search.py 
sys.version='3.9.10 (heads/issue56:851b1aac3e, May  2 2022, 11:56:36)\n[nogil, GCC 11.2.0]', joblib_backend_name='threading', n_jobs=8, nogil=True
Fitting 5 folds for each of 3 candidates, totalling 15 fits
Segmentation fault (core dumped)

Here is the source code of spline_pipeline_randomized_search.py :

import sys
from time import perf_counter
import numpy as np
from scipy.sparse import csr_matrix
from sklearn.datasets import fetch_covtype
from sklearn.preprocessing import QuantileTransformer
from sklearn.preprocessing import SplineTransformer
from sklearn.preprocessing import PolynomialFeatures
from sklearn.kernel_approximation import Nystroem
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from joblib import parallel_backend
from threadpoolctl import threadpool_limits


nogil = getattr(sys.flags, "nogil", False)
joblib_backend_name = "threading" if nogil else "loky"
n_jobs = 8

print(f"{sys.version=}, {joblib_backend_name=!r}, {n_jobs=}, {nogil=}")

X, y = fetch_covtype(return_X_y=True, as_frame=False)
X = X[:, :5]
X_train, X_test, y_train, y_test = train_test_split(
    X, y, train_size=2_000, test_size=10_000, random_state=0
)

pipeline = Pipeline(
    [
        ("preproc", None),
        ("splines", SplineTransformer()),
        # ("poly", PolynomialFeatures(degree=2, interaction_only=True)),
        ("kernel", Nystroem(n_components=300, gamma=1e-3, random_state=0)),
        (
            "classifier",
            SGDClassifier(
                early_stopping=True,
                validation_fraction=0.2,
                n_iter_no_change=5,
                random_state=0,
            ),
        ),
    ]
)


param_grid = {
    "preproc": [None, QuantileTransformer()],
    "splines__degree": [2, 3, 4],
    "splines__n_knots": [3, 5, 10],
    "kernel__gamma": np.logspace(-5, 3, 100),
    "kernel__n_components": [10, 50, 100, 500],
    "classifier__loss": ["hinge", "log_loss"],
    "classifier__alpha": np.logspace(-5, 1, 100),
}

tic = perf_counter()
with parallel_backend(joblib_backend_name, n_jobs=n_jobs):
    with threadpool_limits(limits=1 if nogil else None):
        search = RandomizedSearchCV(
            pipeline,
            param_distributions=param_grid,
            n_iter=3,
            verbose=1,
            random_state=0,
        ).fit(X_train, y_train)
toc = perf_counter()
print(f"search completed in {toc - tic:.1f}s")
print(search.best_params_)
print(search.score(X_test, y_test))

Here is the gdb backtrace:

#0  _Py_IncRefShared (op=<unknown at remote 0x5555558aaec8>) at Objects/object.c:2334
#1  0x00007ffff6d59dd7 in _Py_INCREF (op=<optimized out>) at /home/ogrisel/code/nogil/Include/object.h:517
#2  snaptrace_tracefunc (obj=obj@entry=<viztracer.Tracer at remote 0x293469ca280>, frame=frame@entry=Frame 0x29349870a90, for file /home/ogrisel/code/nogil/Lib/inspect.py, line 2819, in <genexpr> (), 
    what=what@entry=3, arg=arg@entry=('knots', <Parameter at remote 0x29349811d20>)) at src/viztracer/modules/snaptrace.c:387
#3  0x00005555556a125f in call_profile (ts=ts@entry=0x555555b40d10, frame=Frame 0x29349870a90, for file /home/ogrisel/code/nogil/Lib/inspect.py, line 2819, in <genexpr> (), what=what@entry=3, 
    arg=arg@entry=('knots', <Parameter at remote 0x29349811d20>)) at Python/ceval_meta.c:3511
#4  0x00005555556ab049 in vm_profile (ts=ts@entry=0x555555b40d10, last_pc=last_pc@entry=0x293445e6890 "\\\002\002M\001W", acc=..., acc@entry=('knots', <Parameter at remote 0x29349811d20>))
    at Python/ceval_meta.c:3644
#5  0x00005555556ab148 in vm_trace_handler (ts=0x555555b40d10, last_pc=0x293445e6890 "\\\002\002M\001W", acc=('knots', <Parameter at remote 0x29349811d20>)) at Python/ceval_meta.c:3778
#6  0x00005555558103c1 in _PyEval_Fast (ts=0x555555b40d10, initial_acc=Register(as_int64 = 10000003), initial_pc=0x293445e6893 "M\001W") at Python/ceval.c:2784
#7  0x00005555556a97e0 in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x555555b40d10) at Python/ceval_meta.c:2831
#8  PyEval2_EvalGen (gen=gen@entry=0x293498f0290, opt_value=None) at Python/ceval_meta.c:2862
#9  0x00005555557c23ac in gen_send_internal (gen=0x293498f0290, opt_value=<optimized out>) at Objects/genobject.c:244
#10 0x00005555557a63b0 in PyIter_Next (iter=iter@entry=<generator at remote 0x293498f0290>) at Objects/abstract.c:2702
#11 0x00005555555fbcc1 in PyDict_MergeFromSeq2 (d=d@entry=<OrderedDict at remote 0x29349850c10>, seq2=seq2@entry=<generator at remote 0x293498f0290>, override=override@entry=1) at Objects/dictobject.c:1895
#12 0x00005555555fc178 in dict_update_arg (self=<OrderedDict at remote 0x29349850c10>, arg=<generator at remote 0x293498f0290>) at Objects/dictobject.c:1827
#13 0x00005555555fc4a9 in dict_update_common (methname=0x555555882419 "dict", kwds=0x0, args=<optimized out>, self=<OrderedDict at remote 0x29349850c10>) at Objects/dictobject.c:1841
#14 dict_init (self=<OrderedDict at remote 0x29349850c10>, args=<optimized out>, kwds=0x0) at Objects/dictobject.c:2757
#15 0x00005555556242d7 in type_call (type=<optimized out>, args=(<generator at remote 0x293498f0290>,), kwds=0x0) at Objects/typeobject.c:1044
#16 0x00005555555c5a6d in _PyObject_MakeTpCall (tstate=0x555555b40d10, callable=<type at remote 0x29343e6fc10>, args=<optimized out>, nargs=1, keywords=0x0) at Objects/call.c:191
#17 0x00005555556a4bfb in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=<optimized out>, args=0x7fffccc25348, callable=<type at remote 0x29343e6fc10>, tstate=0x555555b40d10)
    at ./Include/cpython/abstract.h:116
#18 _PyObject_VectorcallTstate (kwnames=0x0, nargsf=<optimized out>, args=0x7fffccc25348, callable=<type at remote 0x29343e6fc10>, tstate=0x555555b40d10) at ./Include/cpython/abstract.h:103
#19 vm_call_function (ts=0x555555b40d10, acc=...) at Python/ceval_meta.c:1341
#20 0x000055555581127b in _PyEval_Fast (ts=0x555555b40d10, initial_acc=Register(as_int64 = 10000003), initial_pc=0x293446e9e07 "F\017\001") at Python/ceval.c:982
#21 0x00005555556a8d2f in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x555555b40d10) at Python/ceval_meta.c:2831
#22 _PyFunction_Vectorcall (func=<function at remote 0x293447750b0>, stack=0x29349801e48, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3228
#23 0x00005555555c7e68 in _PyObject_FastCallDictTstate (kwargs={'return_annotation': <type at remote 0x293446eec10>, '__validate_parameters__': False}, nargsf=2, args=0x7fffccc254c0, 
    callable=<function at remote 0x293447750b0>, tstate=0x555555b40d10) at Objects/call.c:129
#24 _PyObject_Call_Prepend (tstate=tstate@entry=0x555555b40d10, callable=callable@entry=<function at remote 0x293447750b0>, obj=obj@entry=<Signature at remote 0x293498209d0>, 
    args=args@entry=([<Parameter at remote 0x29349811a50>, <Parameter at remote 0x29349811b40>, <Parameter at remote 0x29349811c30>, <Parameter at remote 0x29349811d20>, <Parameter at remote 0x29349811e10>, <Parameter at remote 0x29349811f00>, <Parameter at remote 0x29349811eb0>],), kwargs=kwargs@entry={'return_annotation': <type at remote 0x293446eec10>, '__validate_parameters__': False}) at Objects/call.c:387
#25 0x0000555555631d84 in slot_tp_init (self=<Signature at remote 0x293498209d0>, 
    args=([<Parameter at remote 0x29349811a50>, <Parameter at remote 0x29349811b40>, <Parameter at remote 0x29349811c30>, <Parameter at remote 0x29349811d20>, <Parameter at remote 0x29349811e10>, <Parameter at remote 0x29349811f00>, <Parameter at remote 0x29349811eb0>],), kwds={'return_annotation': <type at remote 0x293446eec10>, '__validate_parameters__': False}) at Objects/typeobject.c:7059
#26 0x00005555556242d7 in type_call (type=<optimized out>, 
    args=([<Parameter at remote 0x29349811a50>, <Parameter at remote 0x29349811b40>, <Parameter at remote 0x29349811c30>, <Parameter at remote 0x29349811d20>, <Parameter at remote 0x29349811e10>, <Parameter at remote 0x29349811f00>, <Parameter at remote 0x29349811eb0>],), kwds={'return_annotation': <type at remote 0x293446eec10>, '__validate_parameters__': False}) at Objects/typeobject.c:1044
#27 0x00005555555c5a6d in _PyObject_MakeTpCall (tstate=0x555555b40d10, callable=<type at remote 0x29344574610>, args=<optimized out>, nargs=1, keywords=('return_annotation', '__validate_parameters__'))
    at Objects/call.c:191
#28 0x00005555556a4981 in _PyObject_VectorcallTstate (kwnames=<optimized out>, nargsf=9223372036854775809, args=0x7fffc0000bf8, callable=<type at remote 0x29344574610>, tstate=0x555555b40d10)
    at ./Include/cpython/abstract.h:116
#29 _PyObject_VectorcallTstate (kwnames=<optimized out>, nargsf=9223372036854775809, args=0x7fffc0000bf8, callable=<type at remote 0x29344574610>, tstate=0x555555b40d10) at ./Include/cpython/abstract.h:103
#30 vm_call_cfunction_slow (ts=0x555555b40d10, acc=...) at Python/ceval_meta.c:1296
#31 0x000055555581127b in _PyEval_Fast (ts=0x555555b40d10, initial_acc=Register(as_int64 = 10000003), initial_pc=0x29343d12c28 "F!\001\002K") at Python/ceval.c:982
#32 0x00005555556a8d2f in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x555555b40d10) at Python/ceval_meta.c:2831
#33 _PyFunction_Vectorcall (func=<function at remote 0x29348a982b0>, stack=0x29349900008, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3228
#34 0x00005555555c7e68 in _PyObject_FastCallDictTstate (
    kwargs={'train': <numpy.ndarray at remote 0x29349291ce0>, 'test': <numpy.ndarray at remote 0x29349291c70>, 'parameters': {'splines__n_knots': 10, 'splines__degree': 4, 'preproc': <QuantileTransformer(n_quantiles=1000, output_distribution='uniform', ignore_implicit_zeros=False, subsample=100000, random_state=None, copy=True) at remote 0x29349196550>, 'kernel__n_components': 500, 'kernel__gamma': <numpy.float64 at remote 0x29348d1f9c0>, 'classifier__loss': 'hinge', 'classifier__alpha': <numpy.float64 at remote 0x29348d1faa0>}, 'split_progress': (1, 5), 'candidate_progress': (0, 3), 'scorer': <function at remote 0x29348eca1f0>, 'fit_params': {}, 'return_train_score': False, 'return_n_test_samples': True, 'return_times': True, 'return_parameters': False, 'error_score': <float at remote 0x29345562380>, 'verbose': 1}, nargsf=4, 
    args=0x7fffccc25760, callable=<function at remote 0x29348a982b0>, tstate=0x555555b40d10) at Objects/call.c:129
#35 _PyObject_Call_Prepend (tstate=tstate@entry=0x555555b40d10, callable=callable@entry=<function at remote 0x29348a982b0>, 

The py-bt gdb commands returns:

Traceback (most recent call first):
  File "/home/ogrisel/code/nogil/Lib/inspect.py", line 2819, in <genexpr>
    params = OrderedDict((param.name, param) for param in parameters)
  0x0

nogil fails to build under pyperformance --compile

I get the error:

Assembler messages:
Fatal error: can't create Objects/mimalloc/alloc-aligned.o: No such file or directory

It appears pyperformance is building out of tree, and Objects/mimalloc/ doesn't exist in the build directory.
Manually creating the .../bench_tmpdir/build/Objects/mimalloc/ during the build allowed the build to complete.

Maybe add a Objects/mimalloc target to Makefile.pre.in ?

Error installing `uwsgi`

Thanks for all the great work so far!

Was interested in testing this out with a webapp I work on that uses uwsgi, but looks like it runs into an error when installing the latest version. Should this work?

Minimal reproduction with docker build .:

# Dockerfile
FROM nogil/python
RUN pip install uwsgi==2.0.20

Error:

#5 12.94     plugins/python/profiler.c: In function ‘uwsgi_python_profiler_call’:
#5 12.94     plugins/python/profiler.c:40:91: error: ‘PyCodeObject’ {aka ‘struct PyCodeObject’} has no member named ‘co_stacksize’; did you mean ‘co_framesize’?
#5 12.94        40 |     PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount, frame->f_code->co_stacksize);
#5 12.94           |                                                                                           ^~~~~~~~~~~~
#5 12.94           |                                                                                           co_framesize
#5 12.94     plugins/python/profiler.c:50:73: error: ‘PyCodeObject’ {aka ‘struct PyCodeObject’} has no member named ‘co_stacksize’; did you mean ‘co_framesize’?
#5 12.94        50 |     PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize);
#5 12.94           |                                                                         ^~~~~~~~~~~~
#5 12.94           |                                                                         co_framesize
#5 12.94     ----------------------------------------
Full error
λ docker build --file Dockerfile2 .
[+] Building 13.7s (5/5) FINISHED
 => [internal] load build definition from Dockerfile2                                                          0.0s
 => => transferring dockerfile: 92B                                                                            0.0s
 => [internal] load .dockerignore                                                                              0.0s
 => => transferring context: 35B                                                                               0.0s
 => [internal] load metadata for docker.io/nogil/python:latest                                                 0.0s
 => CACHED [1/2] FROM docker.io/nogil/python                                                                   0.0s
 => ERROR [2/2] RUN pip install uwsgi==2.0.20                                                                 13.6s
------
 > [2/2] RUN pip install uwsgi==2.0.20:
#5 2.207 Looking in indexes: https://d1yxz45j0ypngg.cloudfront.net/, https://pypi.org/simple
#5 2.740 Collecting uwsgi==2.0.20
#5 2.888   Downloading uwsgi-2.0.20.tar.gz (804 kB)
#5 3.253   Preparing metadata (setup.py): started
#5 3.783   Preparing metadata (setup.py): finished with status 'done'
#5 3.785 Using legacy 'setup.py install' for uwsgi, since package 'wheel' is not installed.
#5 3.845 Installing collected packages: uwsgi
#5 3.847     Running setup.py install for uwsgi: started
#5 12.94     Running setup.py install for uwsgi: finished with status 'error'
#5 12.94     ERROR: Command errored out with exit status 1:
#5 12.94      command: /usr/local/bin/python3.9 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-z3opkux3/uwsgi_7056e9a5299e4dd49f5d9bf0d7f1272d/setup.py'"'"'; __file__='"'"'/tmp/pip-install-z3opkux3/uwsgi_7056e9a5299e4dd49f5d9bf0d7f1272d/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-i681v31u/install-record.txt --single-version-externally-managed --compile --install-headers /usr/local/include/python3.9/uwsgi
#5 12.94          cwd: /tmp/pip-install-z3opkux3/uwsgi_7056e9a5299e4dd49f5d9bf0d7f1272d/
#5 12.94     Complete output (108 lines):
#5 12.94     /usr/local/lib/python3.9/distutils/dist.py:274: UserWarning: Unknown distribution option: 'descriptions'
#5 12.94       warnings.warn(msg)
#5 12.94     running install
#5 12.94     using profile: buildconf/default.ini
#5 12.94     detected include path: ['/usr/lib/gcc/x86_64-linux-gnu/10/include', '/usr/local/include', '/usr/include/x86_64-linux-gnu', '/usr/include']
#5 12.94     Patching "bin_name" to properly install_scripts dir
#5 12.94     detected CPU cores: 4
#5 12.94     configured CFLAGS: -O2 -I. -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -DUWSGI_HAS_IFADDRS -DUWSGI_ZLIB -DUWSGI_LOCK_USE_MUTEX -DUWSGI_EVENT_USE_EPOLL -DUWSGI_EVENT_TIMER_USE_TIMERFD -DUWSGI_EVENT_FILEMONITOR_USE_INOTIFY  -DUWSGI_PCRE -DUWSGI_ROUTING -DUWSGI_UUID -DUWSGI_VERSION="\"2.0.20\"" -DUWSGI_VERSION_BASE="2" -DUWSGI_VERSION_MAJOR="0" -DUWSGI_VERSION_MINOR="20" -DUWSGI_VERSION_REVISION="0" -DUWSGI_VERSION_CUSTOM="\"\"" -DUWSGI_YAML -DUWSGI_SSL -I/usr/include/libxml2 -DUWSGI_XML -DUWSGI_XML_LIBXML2 -DUWSGI_PLUGIN_DIR="\".\"" -DUWSGI_DECLARE_EMBEDDED_PLUGINS="UDEP(python);UDEP(gevent);UDEP(ping);UDEP(cache);UDEP(nagios);UDEP(rrdtool);UDEP(carbon);UDEP(rpc);UDEP(corerouter);UDEP(fastrouter);UDEP(http);UDEP(ugreen);UDEP(signal);UDEP(syslog);UDEP(rsyslog);UDEP(logsocket);UDEP(router_uwsgi);UDEP(router_redirect);UDEP(router_basicauth);UDEP(zergpool);UDEP(redislog);UDEP(mongodblog);UDEP(router_rewrite);UDEP(router_http);UDEP(logfile);UDEP(router_cache);UDEP(rawrouter);UDEP(router_static);UDEP(sslrouter);UDEP(spooler);UDEP(cheaper_busyness);UDEP(symcall);UDEP(transformation_tofile);UDEP(transformation_gzip);UDEP(transformation_chunked);UDEP(transformation_offload);UDEP(router_memcached);UDEP(router_redis);UDEP(router_hash);UDEP(router_expires);UDEP(router_metrics);UDEP(transformation_template);UDEP(stats_pusher_socket);" -DUWSGI_LOAD_EMBEDDED_PLUGINS="ULEP(python);ULEP(gevent);ULEP(ping);ULEP(cache);ULEP(nagios);ULEP(rrdtool);ULEP(carbon);ULEP(rpc);ULEP(corerouter);ULEP(fastrouter);ULEP(http);ULEP(ugreen);ULEP(signal);ULEP(syslog);ULEP(rsyslog);ULEP(logsocket);ULEP(router_uwsgi);ULEP(router_redirect);ULEP(router_basicauth);ULEP(zergpool);ULEP(redislog);ULEP(mongodblog);ULEP(router_rewrite);ULEP(router_http);ULEP(logfile);ULEP(router_cache);ULEP(rawrouter);ULEP(router_static);ULEP(sslrouter);ULEP(spooler);ULEP(cheaper_busyness);ULEP(symcall);ULEP(transformation_tofile);ULEP(transformation_gzip);ULEP(transformation_chunked);ULEP(transformation_offload);ULEP(router_memcached);ULEP(router_redis);ULEP(router_hash);ULEP(router_expires);ULEP(router_metrics);ULEP(transformation_template);ULEP(stats_pusher_socket);"
#5 12.94     *** uWSGI compiling server core ***
#5 12.94     [thread 2][gcc -pthread] core/utils.o
#5 12.94     [thread 1][gcc -pthread] core/protocol.o
#5 12.94     [thread 3][gcc -pthread] core/socket.o
#5 12.94     [thread 0][gcc -pthread] core/logging.o
#5 12.94     [thread 1][gcc -pthread] core/master.o
#5 12.94     [thread 0][gcc -pthread] core/master_utils.o
#5 12.94     [thread 3][gcc -pthread] core/emperor.o
#5 12.94     [thread 1][gcc -pthread] core/notify.o
#5 12.94     [thread 1][gcc -pthread] core/mule.o
#5 12.94     [thread 2][gcc -pthread] core/subscription.o
#5 12.94     [thread 0][gcc -pthread] core/stats.o
#5 12.94     [thread 1][gcc -pthread] core/sendfile.o
#5 12.94     [thread 3][gcc -pthread] core/async.o
#5 12.94     [thread 1][gcc -pthread] core/master_checks.o
#5 12.94     [thread 0][gcc -pthread] core/fifo.o
#5 12.94     [thread 2][gcc -pthread] core/offload.o
#5 12.94     [thread 3][gcc -pthread] core/io.o
#5 12.94     [thread 0][gcc -pthread] core/static.o
#5 12.94     [thread 1][gcc -pthread] core/websockets.o
#5 12.94     [thread 2][gcc -pthread] core/spooler.o
#5 12.94     [thread 0][gcc -pthread] core/snmp.o
#5 12.94     [thread 1][gcc -pthread] core/exceptions.o
#5 12.94     [thread 3][gcc -pthread] core/config.o
#5 12.94     [thread 2][gcc -pthread] core/setup_utils.o
#5 12.94     [thread 0][gcc -pthread] core/clock.o
#5 12.94     [thread 1][gcc -pthread] core/init.o
#5 12.94     [thread 2][gcc -pthread] core/buffer.o
#5 12.94     [thread 0][gcc -pthread] core/reader.o
#5 12.94     [thread 3][gcc -pthread] core/writer.o
#5 12.94     [thread 1][gcc -pthread] core/alarm.o
#5 12.94     [thread 2][gcc -pthread] core/cron.o
#5 12.94     [thread 0][gcc -pthread] core/hooks.o
#5 12.94     [thread 1][gcc -pthread] core/plugins.o
#5 12.94     [thread 2][gcc -pthread] core/lock.o
#5 12.94     [thread 3][gcc -pthread] core/cache.o
#5 12.94     [thread 1][gcc -pthread] core/daemons.o
#5 12.94     [thread 0][gcc -pthread] core/errors.o
#5 12.94     [thread 2][gcc -pthread] core/hash.o
#5 12.94     [thread 0][gcc -pthread] core/master_events.o
#5 12.94     [thread 2][gcc -pthread] core/chunked.o
#5 12.94     [thread 1][gcc -pthread] core/queue.o
#5 12.94     [thread 0][gcc -pthread] core/event.o
#5 12.94     [thread 2][gcc -pthread] core/signal.o
#5 12.94     [thread 1][gcc -pthread] core/strings.o
#5 12.94     [thread 3][gcc -pthread] core/progress.o
#5 12.94     [thread 3][gcc -pthread] core/timebomb.o
#5 12.94     [thread 0][gcc -pthread] core/ini.o
#5 12.94     [thread 2][gcc -pthread] core/fsmon.o
#5 12.94     [thread 1][gcc -pthread] core/mount.o
#5 12.94     [thread 3][gcc -pthread] core/metrics.o
#5 12.94     [thread 0][gcc -pthread] core/plugins_builder.o
#5 12.94     [thread 2][gcc -pthread] core/sharedarea.o
#5 12.94     [thread 1][gcc -pthread] core/rpc.o
#5 12.94     [thread 0][gcc -pthread] core/gateway.o
#5 12.94     [thread 1][gcc -pthread] core/loop.o
#5 12.94     [thread 2][gcc -pthread] core/cookie.o
#5 12.94     [thread 0][gcc -pthread] core/querystring.o
#5 12.94     [thread 3][gcc -pthread] core/rb_timers.o
#5 12.94     [thread 1][gcc -pthread] core/transformations.o
#5 12.94     [thread 2][gcc -pthread] core/uwsgi.o
#5 12.94     [thread 0][gcc -pthread] proto/base.o
#5 12.94     [thread 3][gcc -pthread] proto/uwsgi.o
#5 12.94     [thread 1][gcc -pthread] proto/http.o
#5 12.94     [thread 0][gcc -pthread] proto/fastcgi.o
#5 12.94     [thread 3][gcc -pthread] proto/scgi.o
#5 12.94     [thread 3][gcc -pthread] proto/puwsgi.o
#5 12.94     [thread 1][gcc -pthread] lib/linux_ns.o
#5 12.94     [thread 0][gcc -pthread] core/zlib.o
#5 12.94     [thread 3][gcc -pthread] core/regexp.o
#5 12.94     [thread 0][gcc -pthread] core/routing.o
#5 12.94     [thread 1][gcc -pthread] core/yaml.o
#5 12.94     [thread 3][gcc -pthread] core/ssl.o
#5 12.94     [thread 1][gcc -pthread] core/legion.o
#5 12.94     [thread 3][gcc -pthread] core/xmlconf.o
#5 12.94     [thread 2][gcc -pthread] core/dot_h.o
#5 12.94     [thread 2][gcc -pthread] core/config_py.o
#5 12.94     *** uWSGI compiling embedded plugins ***
#5 12.94     [thread 2][gcc -pthread] plugins/python/python_plugin.o
#5 12.94     [thread 3][gcc -pthread] plugins/python/pyutils.o
#5 12.94     [thread 0][gcc -pthread] plugins/python/pyloader.o
#5 12.94     [thread 1][gcc -pthread] plugins/python/wsgi_handlers.o
#5 12.94     [thread 3][gcc -pthread] plugins/python/wsgi_headers.o
#5 12.94     [thread 1][gcc -pthread] plugins/python/wsgi_subhandler.o
#5 12.94     [thread 0][gcc -pthread] plugins/python/web3_subhandler.o
#5 12.94     [thread 2][gcc -pthread] plugins/python/pump_subhandler.o
#5 12.94     [thread 3][gcc -pthread] plugins/python/gil.o
#5 12.94     [thread 3][gcc -pthread] plugins/python/uwsgi_pymodule.o
#5 12.94     [thread 1][gcc -pthread] plugins/python/profiler.o
#5 12.94     [thread 0][gcc -pthread] plugins/python/symimporter.o
#5 12.94     [thread 2][gcc -pthread] plugins/python/tracebacker.o
#5 12.94     plugins/python/profiler.c: In function ‘uwsgi_python_profiler_call’:
#5 12.94     plugins/python/profiler.c:40:91: error: ‘PyCodeObject’ {aka ‘struct PyCodeObject’} has no member named ‘co_stacksize’; did you mean ‘co_framesize’?
#5 12.94        40 |     PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount, frame->f_code->co_stacksize);
#5 12.94           |                                                                                           ^~~~~~~~~~~~
#5 12.94           |                                                                                           co_framesize
#5 12.94     plugins/python/profiler.c:50:73: error: ‘PyCodeObject’ {aka ‘struct PyCodeObject’} has no member named ‘co_stacksize’; did you mean ‘co_framesize’?
#5 12.94        50 |     PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize);
#5 12.94           |                                                                         ^~~~~~~~~~~~
#5 12.94           |                                                                         co_framesize
#5 12.94     ----------------------------------------
#5 12.94 ERROR: Command errored out with exit status 1: /usr/local/bin/python3.9 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-z3opkux3/uwsgi_7056e9a5299e4dd49f5d9bf0d7f1272d/setup.py'"'"'; __file__='"'"'/tmp/pip-install-z3opkux3/uwsgi_7056e9a5299e4dd49f5d9bf0d7f1272d/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-i681v31u/install-record.txt --single-version-externally-managed --compile --install-headers /usr/local/include/python3.9/uwsgi Check the logs for full command output.
------
executor failed running [/bin/sh -c pip install uwsgi==2.0.20]: exit code: 1

ubuntu 20.04 cannot install numba 0.54

Hello,
I would like to report an issue.
I downloaded numba from here: https://d1yxz45j0ypngg.cloudfront.net/numba/
I run "pip install numba-0.54.0-nogil39-nogil_39_x86_64_linux_gnu-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
It gives me the following error
"ERROR: numba-0.54.0-nogil39-nogil_39_x86_64_linux_gnu-manylinux_2_17_x86_64.manylinux2014_x86_64.whl is not a supported wheel on this platform."

Would you mind to double check this whl? Thank you.

Is GC still working?

Sorry if this is just noise. However, I was reading quite a bit of your code. It looks like a very interesting approach to this problem.

However I do not seem to find the place where the _PyGCHead_SET_NEXT and _PyGCHead_SET_PREV macros are called or where _gc_prev and _gc_next are set in your code. This might lead to GC not working at all, which means probably better benchmarks, but memory leaks.

Is this something I'm misunderstanding? Maybe your patches towards Modules/gcmodule.c somehow still track those objects. However, I do not understand where that would happen, since the content of _PyObject_GC_TRACK seems to have moved nowhere specific.

Please let me know what you think!

types.CodeType arguments differ from CPython

import types

types.CodeType(
    0,
    0,
    0,
    0,
    0,
    19,
    b"\x06\x004\x00K",
    (None, "test.<locals>.func"),
    (),
    (),
    "/tmp/test.py",
    "func",
    17,
    b"\x02\x00\x00\x01",
    (),
    (),
)

With nogil:

TypeError: an integer is required (got type bytes)

The same snippet works fine with CPython 3.9.

Context: I was trying to run the joblib test suite and one of the error happens when pickling a local function with cloudpickle:

import cloudpickle
import pickle

import types


def test():
    def func():
        pass

    pickled = cloudpickle.dumps(func)
    unpickled = pickle.loads(pickled)

test()
py-tb
Traceback (most recent call last):
  File "/tmp/test.py", line 14, in <module>
    test()
  File "/tmp/test.py", line 12, in test
    unpickled = pickle.loads(pickled)
TypeError: an integer is required (got type bytes)

Side-comment: CPython error are a bit nicer when wrong arguments are passed to types.CodeType for example something like this:

TypeError: code() argument 7 must be bytes, not int

Having similar more informative error messages in nogil would be very useful!

Configuring using --with-trace-refs doesn't produce a buildable configuration

For some other (now defunct) work I was doing, I had a build script which configured using --with-trace-refs by default. This doesn't seem to work, producting a compilation error in Objects/object.c (at least). If it shouldn't build with that config setting, perhaps make it a no-op or remove it from configure.ac altogether.

Fails to build in Docker for linux/arm64 (M1 Mac)

Not sure if this is related to #36, but running

docker build --build-arg commit=2607880dd93de52cf34045f1b7e850639a06c137 -t colesbury/python-nogil .

on an M1 Mac (defaulting to linux/arm64 for the platform) results in the following:

<...>
#6 26.47 In file included from ./Include/pytime.h:6,
#6 26.47                  from ./Include/Python.h:67,
#6 26.47                  from ./Include/internal/pegen_interface.h:11,
#6 26.47                  from Parser/pegen/peg_api.c:1:
#6 26.47 ./Include/object.h: In function ‘PyPegen_ASTFromString’:
#6 26.47 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.47   468 |     __asm__ (
#6 26.47       |     ^~~~~~~
#6 26.48 ./Include/object.h: In function ‘PyPegen_ASTFromFilename’:
#6 26.48 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.48   468 |     __asm__ (
#6 26.48       |     ^~~~~~~
#6 26.48 make[3]: *** [Makefile:1835: Parser/pegen/peg_api.o] Error 1
#6 26.48 make[3]: *** Waiting for unfinished jobs....
#6 26.48 In file included from ./Include/pytime.h:6,
#6 26.48                  from ./Include/Python.h:67,
#6 26.48                  from Parser/pegen/parse_string.c:3:
#6 26.48 ./Include/object.h: In function ‘make_str_node_and_del’:
#6 26.48 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.48   468 |     __asm__ (
#6 26.48       |     ^~~~~~~
#6 26.49 ./Include/object.h: In function ‘_PyPegen_FstringParser_ConcatAndDel’:
#6 26.49 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.49   468 |     __asm__ (
#6 26.49       |     ^~~~~~~
#6 26.49 ./Include/object.h: In function ‘warn_invalid_escape_sequence’:
#6 26.49 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.49   468 |     __asm__ (
#6 26.49       |     ^~~~~~~
#6 26.49 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.49   468 |     __asm__ (
#6 26.49       |     ^~~~~~~
#6 26.49 ./Include/object.h: In function ‘_PyPegen_FstringParser_Dealloc’:
#6 26.49 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.49   468 |     __asm__ (
#6 26.49       |     ^~~~~~~
#6 26.50 ./Include/object.h: In function ‘decode_unicode_with_escapes’:
#6 26.50 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.50   468 |     __asm__ (
#6 26.50       |     ^~~~~~~
#6 26.50 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.50   468 |     __asm__ (
#6 26.50       |     ^~~~~~~
#6 26.50 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.50   468 |     __asm__ (
#6 26.50       |     ^~~~~~~
#6 26.50 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.50   468 |     __asm__ (
#6 26.50       |     ^~~~~~~
#6 26.50 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.50   468 |     __asm__ (
#6 26.50       |     ^~~~~~~
#6 26.51 ./Include/object.h: In function ‘_PyPegen_parsestr’:
#6 26.51 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.51   468 |     __asm__ (
#6 26.51       |     ^~~~~~~
#6 26.52 ./Include/object.h: In function ‘_PyPegen_FstringParser_ConcatFstring’:
#6 26.52 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.52   468 |     __asm__ (
#6 26.52       |     ^~~~~~~
#6 26.52 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.52   468 |     __asm__ (
#6 26.52       |     ^~~~~~~
#6 26.53 In file included from ./Include/pytime.h:6,
#6 26.53                  from ./Include/Python.h:67,
#6 26.53                  from Parser/pegen/pegen.c:1:
#6 26.53 ./Include/object.h: In function ‘_PyPegen_alias_for_star’:
#6 26.53 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.53   468 |     __asm__ (
#6 26.53       |     ^~~~~~~
#6 26.53 ./Include/object.h: In function ‘fstring_find_expr’:
#6 26.53 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.53   468 |     __asm__ (
#6 26.53       |     ^~~~~~~
#6 26.54 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.54   468 |     __asm__ (
#6 26.54       |     ^~~~~~~
#6 26.54 ./Include/object.h: In function ‘_PyPegen_join_names_with_dot’:
#6 26.54 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.54   468 |     __asm__ (
#6 26.54       |     ^~~~~~~
#6 26.54 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.54   468 |     __asm__ (
#6 26.54       |     ^~~~~~~
#6 26.54 make[3]: *** [Makefile:1835: Parser/pegen/parse_string.o] Error 1
#6 26.55 ./Include/object.h: In function ‘_PyPegen_get_memo_statistics’:
#6 26.55 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.55   468 |     __asm__ (
#6 26.55       |     ^~~~~~~
#6 26.55 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.55   468 |     __asm__ (
#6 26.55       |     ^~~~~~~
#6 26.55 ./Include/object.h: In function ‘_PyPegen_new_type_comment’:
#6 26.55 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.55   468 |     __asm__ (
#6 26.55       |     ^~~~~~~
#6 26.56 ./Include/object.h: In function ‘_PyPegen_new_identifier’:
#6 26.56 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.56   468 |     __asm__ (
#6 26.56       |     ^~~~~~~
#6 26.56 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.56   468 |     __asm__ (
#6 26.56       |     ^~~~~~~
#6 26.56 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.56   468 |     __asm__ (
#6 26.56       |     ^~~~~~~
#6 26.56 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.56   468 |     __asm__ (
#6 26.56       |     ^~~~~~~
#6 26.56 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.56   468 |     __asm__ (
#6 26.56       |     ^~~~~~~
#6 26.56 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.56   468 |     __asm__ (
#6 26.56       |     ^~~~~~~
#6 26.56 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.56   468 |     __asm__ (
#6 26.56       |     ^~~~~~~
#6 26.57 ./Include/object.h: In function ‘_PyPegen_Parser_Free’:
#6 26.57 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.57   468 |     __asm__ (
#6 26.57       |     ^~~~~~~
#6 26.57 ./Include/object.h: In function ‘raise_tokenizer_init_error’:
#6 26.57 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.57   468 |     __asm__ (
#6 26.57       |     ^~~~~~~
#6 26.57 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.57   468 |     __asm__ (
#6 26.57       |     ^~~~~~~
#6 26.57 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.57   468 |     __asm__ (
#6 26.57       |     ^~~~~~~
#6 26.57 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.57   468 |     __asm__ (
#6 26.57       |     ^~~~~~~
#6 26.57 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.57   468 |     __asm__ (
#6 26.57       |     ^~~~~~~
#6 26.57 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.57   468 |     __asm__ (
#6 26.57       |     ^~~~~~~
#6 26.58 ./Include/object.h: In function ‘_PyPegen_raise_error_known_location’:
#6 26.58 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.58   468 |     __asm__ (
#6 26.58       |     ^~~~~~~
#6 26.58 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.58   468 |     __asm__ (
#6 26.58       |     ^~~~~~~
#6 26.58 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.58   468 |     __asm__ (
#6 26.58       |     ^~~~~~~
#6 26.58 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.58   468 |     __asm__ (
#6 26.58       |     ^~~~~~~
#6 26.58 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.58   468 |     __asm__ (
#6 26.58       |     ^~~~~~~
#6 26.58 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.58   468 |     __asm__ (
#6 26.58       |     ^~~~~~~
#6 26.59 ./Include/object.h: In function ‘_PyPegen_run_parser_from_string’:
#6 26.59 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.59   468 |     __asm__ (
#6 26.59       |     ^~~~~~~
#6 26.59 ./Include/object.h: In function ‘_PyPegen_run_parser_from_file_pointer’:
#6 26.59 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.59   468 |     __asm__ (
#6 26.59       |     ^~~~~~~
#6 26.59 ./Include/object.h: In function ‘raise_decode_error’:
#6 26.59 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.59   468 |     __asm__ (
#6 26.59       |     ^~~~~~~
#6 26.59 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.59   468 |     __asm__ (
#6 26.59       |     ^~~~~~~
#6 26.59 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.59   468 |     __asm__ (
#6 26.59       |     ^~~~~~~
#6 26.59 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.59   468 |     __asm__ (
#6 26.59       |     ^~~~~~~
#6 26.60 ./Include/object.h: In function ‘_PyPegen_concatenate_strings’:
#6 26.60 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.60   468 |     __asm__ (
#6 26.60       |     ^~~~~~~
#6 26.60 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.60   468 |     __asm__ (
#6 26.60       |     ^~~~~~~
#6 26.61 ./Include/object.h: In function ‘_PyPegen_fill_token’:
#6 26.61 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.61   468 |     __asm__ (
#6 26.61       |     ^~~~~~~
#6 26.61 ./Include/object.h: In function ‘_PyPegen_number_token’:
#6 26.61 ./Include/object.h:468:5: error: unknown ‘asm’ flag output ‘=@ccz’
#6 26.61   468 |     __asm__ (
#6 26.61       |     ^~~~~~~
# Copied from https://github.com/docker-library/python/blob/master/3.9/bullseye/Dockerfile
#6 26.62 make[3]: *** [Makefile:1835: Parser/pegen/pegen.o] Error 1
#6 29.41 make[3]: Leaving directory '/usr/src/python'
#6 29.41 make[2]: Leaving directory '/usr/src/python'
#6 29.41 make[2]: *** [Makefile:553: build_all_generate_profile] Error 2
#6 29.41 make[1]: Leaving directory '/usr/src/python'
#6 29.41 make[1]: *** [Makefile:529: profile-gen-stamp] Error 2
#6 29.41 make: *** [Makefile:541: profile-run-stamp] Error 2
<...>

ARM64 Linux builds are listed as supported in the README. Are modifications to the Dockerfile necessary to successfully build an image for this platform?

networkx 2.6: TypeError by passing None as closure to types.FunctionType()

Hi, I tried to import networkx and encountered an error:

>>> import networkx as nx
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/fumito/nogil/nogil_build/lib/python3.9/site-packages/networkx/__init__.py", line 79, in <module>
    from networkx import algorithms
  File "/home/fumito/nogil/nogil_build/lib/python3.9/site-packages/networkx/algorithms/__init__.py", line 74, in <module>
    from networkx.algorithms import isomorphism
  File "/home/fumito/nogil/nogil_build/lib/python3.9/site-packages/networkx/algorithms/isomorphism/__init__.py", line 3, in <module>
    from networkx.algorithms.isomorphism.matchhelpers import *
  File "/home/fumito/nogil/nogil_build/lib/python3.9/site-packages/networkx/algorithms/isomorphism/matchhelpers.py", line 194, in <module>
    numerical_edge_match = copyfunc(numerical_node_match, "numerical_edge_match")
  File "/home/fumito/nogil/nogil_build/lib/python3.9/site-packages/networkx/algorithms/isomorphism/matchhelpers.py", line 22, in copyfunc
    return types.FunctionType(
TypeError: arg 5 (closure) must be tuple

numerical_node_match.__closure__ is None, so None is passed to copyfunc instead of a tuple. The original CPython doesn't rasie the error.

Should cProfile be working? nogil is slow for me and profiling doesn't work.

I posted a thread on Reddit summarising some testing I performed where I found nogil to be very slow. I tried to use cProfile to understand the performance but the output from cProfile doesn't seem to make any sense - it reports a runtime far less than the actual observed runtime and the profile itself doesn't parse properly (I'm using Snakeviz). I've observed similar issues with the Docker image and with my own build of nogil.

I'm aware this is not a well-formed issue report, but just looking to gain some understanding. Should I expect cProfile to work on this fork?

Segfault when importing within ptpython

Built with and without enable optimisations on

System:
  Host: home Kernel: 5.10.0-9-amd64 x86_64 bits: 64 Desktop: dwm 6.2
  Distro: Debian GNU/Linux 11 (bullseye)
CPU:
  Info: 6-Core AMD Ryzen 5 3600 [MT MCP] speed: 2198 MHz
  min/max: 2200/3600 MHz

./pip3 install --upgrade ptpython

./python3 -m ptpython

Imports cause seg faults (not true in python or ipython shells):

>>> import sys; print(sys.version)
3.9.0a4+ (heads/nogil:84c1b14af4, Oct 17 2021, 07:52:16) 
[GCC 10.2.1 20210110]
Segmentation fault

Undefined commands like ls without bang also cause a seg fault.

Interesting work thank you. I'll try it out some more later with the backtrader module.

Error: Stack smashing detected.

Hi, last days my program crash on high load (when users get active) and i get error:

*** stack smashing detected ***: <unknown> terminated

And i don't know how track this. Also i only get it when my application receive much client updates.

Is there a way i can fix this or do anything?

pytest InternalError when exception in pyx numpy code

To reproduce:

# /tmp/test.py

import numpy as np

def test_format_exc_with_compiled_code():
    np.random.uniform('invalid_value')
==================================================================== test session starts ====================================================================
platform linux -- Python 3.9.10, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /tmp
collected 1 item                                                                                                                                            

../../tmp/test.py 
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/main.py", line 269, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/main.py", line 323, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/main.py", line 348, in pytest_runtestloop
INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/runner.py", line 109, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/runner.py", line 126, in runtestprotocol
INTERNALERROR>     reports.append(call_and_report(item, "call", log))
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/runner.py", line 217, in call_and_report
INTERNALERROR>     report: TestReport = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 55, in _multicall
INTERNALERROR>     gen.send(outcome)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/skipping.py", line 272, in pytest_runtest_makereport
INTERNALERROR>     rep = outcome.get_result()
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/runner.py", line 337, in pytest_runtest_makereport
INTERNALERROR>     return TestReport.from_item_and_call(item, call)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/reports.py", line 322, in from_item_and_call
INTERNALERROR>     longrepr = item.repr_failure(excinfo)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/python.py", line 1677, in repr_failure
INTERNALERROR>     return self._repr_failure_py(excinfo, style=style)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/nodes.py", line 398, in _repr_failure_py
INTERNALERROR>     return excinfo.getrepr(
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/_code/code.py", line 648, in getrepr
INTERNALERROR>     return fmt.repr_excinfo(self)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/_code/code.py", line 905, in repr_excinfo
INTERNALERROR>     reprtraceback = self.repr_traceback(excinfo_)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/_code/code.py", line 846, in repr_traceback
INTERNALERROR>     reprentry = self.repr_traceback_entry(entry, einfo)
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/_code/code.py", line 797, in repr_traceback_entry
INTERNALERROR>     reprargs = self.repr_args(entry) if not short else None
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/_code/code.py", line 706, in repr_args
INTERNALERROR>     for argname, argvalue in entry.frame.getargs(var=True):
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/_code/code.py", line 177, in getargs
INTERNALERROR>     for arg in self.code.getargs(var):
INTERNALERROR>   File "/home/lesteve/venvs/nogil/lib/python3.9/site-packages/_pytest/_code/code.py", line 120, in getargs
INTERNALERROR>     return raw.co_varnames[:argcount]
INTERNALERROR> TypeError: 'NoneType' object is not subscriptable

=================================================================== no tests ran in 0.13s ===================================================================

Not getting numpy

In a now-closed issue Sam wrote:

The "nogil" branch pulls the patched NumPy wheel (it contains a modified "pip" that pulls from https://d1yxz45j0ypngg.cloudfront.net/).

I built from the nogil branch (not nogil-3.9), ran ensure pip to get the modified pip, then tried to install numpy.

Looking at the pip-ish bits included in the nogil branch, it seems to have two versions of pip, 19.2.3 and 21.2.4:

(python39) nogil% find . -name '*pip*' '*pip*'
...
./Lib/ensurepip
./Lib/ensurepip/_bundled/pip-19.2.3-py2.py3-none-any.whl
./Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl
...

Ensure-pip installed the 21.2.4 version:

(python39) nogil% ./python -m pip --version
pip 21.2.4 from /home/skip/.local/lib/python3.9/site-packages/pip (python 3.9)

When I tried to install numpy I was rebuffed:

% ./python -m pip --verbose install numpy 
Using pip 21.2.4 from /home/skip/.local/lib/python3.9/site-packages/pip (python 3.9)
WARNING: Value for scheme.headers does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
distutils: /usr/local/include/python3.9d/UNKNOWN
sysconfig: /home/skip/src/python/nogil/Include/UNKNOWN
WARNING: Additional context:
user = False
home = None
root = None
prefix = None
Defaulting to user installation because normal site-packages is not writeable
Looking in indexes: https://d1yxz45j0ypngg.cloudfront.net/, https://pypi.org/simple
ERROR: Could not find a version that satisfies the requirement numpy (from versions: none)
ERROR: No matching distribution found for numpy
WARNING: You are using pip version 21.2.4; however, version 21.3 is available.
You should consider upgrading via the '/home/skip/src/python/nogil/python -m pip install --upgrade pip' command.

Looking on the cloudfront.net index for numpy I saw two wheels:

numpy-1.19.3-nogil39-nogil_39_x86_64_linux_gnu-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
numpy-1.19.4-nogil39-nogil_39_x86_64_linux_gnu-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Why wasn't one of them installed? I'm running on an XUbuntu 20.04 system. I wasn't able to (with my feeble pip-fu) coax pip into emitting more information about the requirements it was looking for.

Any plan to seperate mimalloc modifications?

I have noticed that mimalloc integrated in nogil has some custom code. Can we refactor the custom modifications into other files such that users can try difference versions of mimalloc? This is convenience in case there are bug fixes in further mimalloc versions.

thread-safety related exception in `np.nanpercentile`: TypeError: partition() got an unexpected keyword argument 'axis'

I randomly observe the following exceptions when running the following scikit-learn code that use Python-level thread parallelism:

import sys
from time import perf_counter
import numpy as np
from scipy.sparse import csr_matrix
from sklearn.datasets import fetch_covtype
from sklearn.preprocessing import QuantileTransformer
from sklearn.preprocessing import SplineTransformer
from sklearn.preprocessing import PolynomialFeatures
from sklearn.kernel_approximation import Nystroem
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from joblib import parallel_backend
from threadpoolctl import threadpool_limits


nogil = getattr(sys.flags, "nogil", False)
joblib_backend_name = "threading" if nogil else "loky"
n_jobs = 8

print(f"{sys.version=}, {joblib_backend_name=!r}, {n_jobs=}, {nogil=}")

X, y = fetch_covtype(return_X_y=True, as_frame=False)
X = X[:, :5]
X_train, X_test, y_train, y_test = train_test_split(
    X, y, train_size=2_000, test_size=10_000, random_state=0
)

pipeline = Pipeline(
    [
        ("preproc", None),
        ("splines", SplineTransformer()),
        # ("poly", PolynomialFeatures(degree=2, interaction_only=True)),
        ("kernel", Nystroem(n_components=300, gamma=1e-3, random_state=0)),
        (
            "classifier",
            SGDClassifier(
                early_stopping=True,
                validation_fraction=0.2,
                n_iter_no_change=5,
                random_state=0,
            ),
        ),
    ]
)


param_grid = {
    "preproc": [None, QuantileTransformer()],
    "splines__degree": [2, 3, 4],
    "splines__n_knots": [3, 5, 10],
    "kernel__gamma": np.logspace(-5, 3, 100),
    "kernel__n_components": [10, 50, 100, 500],
    "classifier__loss": ["hinge", "log_loss"],
    "classifier__alpha": np.logspace(-5, 1, 100),
}

tic = perf_counter()
with parallel_backend(joblib_backend_name, n_jobs=n_jobs):
    with threadpool_limits(limits=1 if nogil else None):
        search = RandomizedSearchCV(
            pipeline,
            param_distributions=param_grid,
            n_iter=3,
            verbose=1,
            random_state=0,
        ).fit(X_train, y_train)
toc = perf_counter()
print(f"search completed in {toc - tic:.1f}s")
print(search.best_params_)
print(search.score(X_test, y_test))

Here is the full output of a typical failure:

$ python spline_pipeline_randomized_search.py 
sys.version='3.9.10 (heads/issue56:69f561fa09, May 12 2022, 14:16:43)\n[nogil, GCC 11.2.0]', joblib_backend_name='threading', n_jobs=8, nogil=True
Fitting 5 folds for each of 3 candidates, totalling 15 fits
/home/ogrisel/code/scikit-learn/sklearn/model_selection/_validation.py:378: FitFailedWarning: 
2 fits failed out of a total of 15.
The score on these train-test partitions for these parameters will be set to nan.
If these failures are not expected, you can try to debug them by setting error_score='raise'.

Below are more details about the failures:
--------------------------------------------------------------------------------
1 fits failed with the following error:
Traceback (most recent call last):
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 57, in _wrapfunc
    return bound(*args, **kwds)
TypeError: take() got an unexpected keyword argument 'axis'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ogrisel/code/scikit-learn/sklearn/model_selection/_validation.py", line 686, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 378, in fit
    Xt = self._fit(X, y, **fit_params_steps)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 336, in _fit
    X, fitted_transformer = fit_transform_one_cached(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/memory.py", line 349, in __call__
    return self.func(*args, **kwargs)
  File "/home/ogrisel/code/nogil/Lib/contextlib.py", line 137, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ogrisel/code/scikit-learn/sklearn/utils/__init__.py", line 933, in _print_elapsed_time
    yield
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 870, in _fit_transform_one
    res = transformer.fit_transform(X, y, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/base.py", line 870, in fit_transform
    return self.fit(X, y, **fit_params).transform(X)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2597, in fit
    self._dense_fit(X, rng)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2486, in _dense_fit
    self.quantiles_.append(np.nanpercentile(col, references))
  File "<__array_function__ internals>", line 180, in nanpercentile
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1385, in nanpercentile
    return _nanquantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1560, in _nanquantile_unchecked
    r, k = function_base._ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1582, in _nanquantile_ureduce_func
    result = _nanquantile_1d(part, q, overwrite_input, method)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1608, in _nanquantile_1d
    return function_base._quantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4383, in _quantile_unchecked
    r, k = _ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4552, in _quantile_ureduce_func
    result = _quantile(arr,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4657, in _quantile
    slices_having_nans = np.isnan(
  File "<__array_function__ internals>", line 180, in take
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 190, in take
    return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 66, in _wrapfunc
    return _wrapit(obj, method, *args, **kwds)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 43, in _wrapit
    result = getattr(asarray(obj), method)(*args, **kwds)
TypeError: take() got an unexpected keyword argument 'axis'

--------------------------------------------------------------------------------
1 fits failed with the following error:
Traceback (most recent call last):
  File "/home/ogrisel/code/scikit-learn/sklearn/model_selection/_validation.py", line 686, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 378, in fit
    Xt = self._fit(X, y, **fit_params_steps)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 336, in _fit
    X, fitted_transformer = fit_transform_one_cached(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/memory.py", line 349, in __call__
    return self.func(*args, **kwargs)
  File "/home/ogrisel/code/nogil/Lib/contextlib.py", line 137, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ogrisel/code/scikit-learn/sklearn/utils/__init__.py", line 933, in _print_elapsed_time
    yield
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 870, in _fit_transform_one
    res = transformer.fit_transform(X, y, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/base.py", line 870, in fit_transform
    return self.fit(X, y, **fit_params).transform(X)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2597, in fit
    self._dense_fit(X, rng)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2486, in _dense_fit
    self.quantiles_.append(np.nanpercentile(col, references))
  File "<__array_function__ internals>", line 180, in nanpercentile
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1385, in nanpercentile
    return _nanquantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1560, in _nanquantile_unchecked
    r, k = function_base._ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1582, in _nanquantile_ureduce_func
    result = _nanquantile_1d(part, q, overwrite_input, method)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1608, in _nanquantile_1d
    return function_base._quantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4383, in _quantile_unchecked
    r, k = _ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4552, in _quantile_ureduce_func
    result = _quantile(arr,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4650, in _quantile
    arr.partition(
TypeError: partition() got an unexpected keyword argument 'axis'

  warnings.warn(some_fits_failed_message, FitFailedWarning)
/home/ogrisel/code/scikit-learn/sklearn/model_selection/_search.py:953: UserWarning: One or more of the test scores are non-finite: [   nan 0.5215 0.482 ]
  warnings.warn(
search completed in 0.6s
{'splines__n_knots': 5, 'splines__degree': 4, 'preproc': QuantileTransformer(), 'kernel__n_components': 10, 'kernel__gamma': 0.011768119524349991, 'classifier__loss': 'hinge', 'classifier__alpha': 3.053855508833412e-05}
0.4991

Note that the problem is random. Some other times I get a mix of the exception above and another one: TypeError: take() got an unexpected keyword argument 'out':

$ python spline_pipeline_randomized_search.py 
sys.version='3.9.10 (heads/issue56:69f561fa09, May 12 2022, 14:16:43)\n[nogil, GCC 11.2.0]', joblib_backend_name='threading', n_jobs=8, nogil=True
Fitting 5 folds for each of 3 candidates, totalling 15 fits
/home/ogrisel/code/scikit-learn/sklearn/model_selection/_validation.py:378: FitFailedWarning: 
7 fits failed out of a total of 15.
The score on these train-test partitions for these parameters will be set to nan.
If these failures are not expected, you can try to debug them by setting error_score='raise'.

Below are more details about the failures:
--------------------------------------------------------------------------------
4 fits failed with the following error:
Traceback (most recent call last):
  File "/home/ogrisel/code/scikit-learn/sklearn/model_selection/_validation.py", line 686, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 378, in fit
    Xt = self._fit(X, y, **fit_params_steps)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 336, in _fit
    X, fitted_transformer = fit_transform_one_cached(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/memory.py", line 349, in __call__
    return self.func(*args, **kwargs)
  File "/home/ogrisel/code/nogil/Lib/contextlib.py", line 137, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ogrisel/code/scikit-learn/sklearn/utils/__init__.py", line 933, in _print_elapsed_time
    yield
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 870, in _fit_transform_one
    res = transformer.fit_transform(X, y, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/base.py", line 870, in fit_transform
    return self.fit(X, y, **fit_params).transform(X)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2597, in fit
    self._dense_fit(X, rng)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2486, in _dense_fit
    self.quantiles_.append(np.nanpercentile(col, references))
  File "<__array_function__ internals>", line 180, in nanpercentile
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1385, in nanpercentile
    return _nanquantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1560, in _nanquantile_unchecked
    r, k = function_base._ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1582, in _nanquantile_ureduce_func
    result = _nanquantile_1d(part, q, overwrite_input, method)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1608, in _nanquantile_1d
    return function_base._quantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4383, in _quantile_unchecked
    r, k = _ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4552, in _quantile_ureduce_func
    result = _quantile(arr,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4650, in _quantile
    arr.partition(
TypeError: partition() got an unexpected keyword argument 'axis'

--------------------------------------------------------------------------------
2 fits failed with the following error:
Traceback (most recent call last):
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 57, in _wrapfunc
    return bound(*args, **kwds)
TypeError: take() got an unexpected keyword argument 'axis'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ogrisel/code/scikit-learn/sklearn/model_selection/_validation.py", line 686, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 378, in fit
    Xt = self._fit(X, y, **fit_params_steps)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 336, in _fit
    X, fitted_transformer = fit_transform_one_cached(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/memory.py", line 349, in __call__
    return self.func(*args, **kwargs)
  File "/home/ogrisel/code/nogil/Lib/contextlib.py", line 137, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ogrisel/code/scikit-learn/sklearn/utils/__init__.py", line 933, in _print_elapsed_time
    yield
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 870, in _fit_transform_one
    res = transformer.fit_transform(X, y, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/base.py", line 870, in fit_transform
    return self.fit(X, y, **fit_params).transform(X)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2597, in fit
    self._dense_fit(X, rng)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2486, in _dense_fit
    self.quantiles_.append(np.nanpercentile(col, references))
  File "<__array_function__ internals>", line 180, in nanpercentile
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1385, in nanpercentile
    return _nanquantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1560, in _nanquantile_unchecked
    r, k = function_base._ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1582, in _nanquantile_ureduce_func
    result = _nanquantile_1d(part, q, overwrite_input, method)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1608, in _nanquantile_1d
    return function_base._quantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4383, in _quantile_unchecked
    r, k = _ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4552, in _quantile_ureduce_func
    result = _quantile(arr,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4657, in _quantile
    slices_having_nans = np.isnan(
  File "<__array_function__ internals>", line 180, in take
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 190, in take
    return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 66, in _wrapfunc
    return _wrapit(obj, method, *args, **kwds)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 43, in _wrapit
    result = getattr(asarray(obj), method)(*args, **kwds)
TypeError: take() got an unexpected keyword argument 'axis'

--------------------------------------------------------------------------------
1 fits failed with the following error:
Traceback (most recent call last):
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 57, in _wrapfunc
    return bound(*args, **kwds)
TypeError: take() got an unexpected keyword argument 'out'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ogrisel/code/scikit-learn/sklearn/model_selection/_validation.py", line 686, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 378, in fit
    Xt = self._fit(X, y, **fit_params_steps)
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 336, in _fit
    X, fitted_transformer = fit_transform_one_cached(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/joblib/memory.py", line 349, in __call__
    return self.func(*args, **kwargs)
  File "/home/ogrisel/code/nogil/Lib/contextlib.py", line 137, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ogrisel/code/scikit-learn/sklearn/utils/__init__.py", line 933, in _print_elapsed_time
    yield
  File "/home/ogrisel/code/scikit-learn/sklearn/pipeline.py", line 870, in _fit_transform_one
    res = transformer.fit_transform(X, y, **fit_params)
  File "/home/ogrisel/code/scikit-learn/sklearn/base.py", line 870, in fit_transform
    return self.fit(X, y, **fit_params).transform(X)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2597, in fit
    self._dense_fit(X, rng)
  File "/home/ogrisel/code/scikit-learn/sklearn/preprocessing/_data.py", line 2486, in _dense_fit
    self.quantiles_.append(np.nanpercentile(col, references))
  File "<__array_function__ internals>", line 180, in nanpercentile
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1385, in nanpercentile
    return _nanquantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1560, in _nanquantile_unchecked
    r, k = function_base._ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1582, in _nanquantile_ureduce_func
    result = _nanquantile_1d(part, q, overwrite_input, method)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/nanfunctions.py", line 1608, in _nanquantile_1d
    return function_base._quantile_unchecked(
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4383, in _quantile_unchecked
    r, k = _ureduce(a,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 3702, in _ureduce
    r = func(a, **kwargs)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4552, in _quantile_ureduce_func
    result = _quantile(arr,
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/lib/function_base.py", line 4657, in _quantile
    slices_having_nans = np.isnan(
  File "<__array_function__ internals>", line 180, in take
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 190, in take
    return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 66, in _wrapfunc
    return _wrapit(obj, method, *args, **kwds)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 43, in _wrapit
    result = getattr(asarray(obj), method)(*args, **kwds)
TypeError: take() got an unexpected keyword argument 'out'

  warnings.warn(some_fits_failed_message, FitFailedWarning)
/home/ogrisel/code/scikit-learn/sklearn/model_selection/_search.py:953: UserWarning: One or more of the test scores are non-finite: [  nan   nan 0.482]
  warnings.warn(
search completed in 0.6s
{'splines__n_knots': 10, 'splines__degree': 4, 'preproc': QuantileTransformer(), 'kernel__n_components': 50, 'kernel__gamma': 29.15053062825182, 'classifier__loss': 'log_loss', 'classifier__alpha': 0.1}
0.4847

and other times the program completes without any error. So there must be some kind of race condition.

Jump too big RuntimeError raised while importing some commonly used libraries

Importing some commonly used libraries (youtube==2021.6.6 and beautifulsoup4==4.10.0 are the two examples I can reproduce this behaviour on myself) leads to the following runtime error being raised by compile2.c:

Traceback (most recent call last):
  File "//main.py", line 1, in <module>
    import bs4
  File "/usr/local/lib/python3.9/site-packages/bs4/__init__.py", line 38, in <module>
    from .builder import builder_registry, ParserRejectedMarkup
  File "/usr/local/lib/python3.9/site-packages/bs4/builder/__init__.py", line 7, in <module>
    from bs4.element import (
  File "/usr/local/lib/python3.9/site-packages/bs4/element.py", line 19, in <module>
    from bs4.formatter import (
  File "/usr/local/lib/python3.9/site-packages/bs4/formatter.py", line 1, in <module>
    from bs4.dammit import EntitySubstitution
RuntimeError: jump too big: 41352

This leads to compatibility issues as this error isn't seen on the reference Cpython 3.9.0.a3 release (since compile2.c is unique to this fork)

For reference I'm running this on the latest tag of https://hub.docker.com/r/colesbury/python-nogil with the following files:

#main.py

import bs4
#import youtube_dl

#Dockerfile

FROM colesbury/python-nogil

COPY ./main.py ./main.py

RUN python -m pip install --upgrade pip wheel
RUN python -m pip install youtube_dl==2021.6.6
RUN python -m pip install beautifulsoup4==4.10.0

ENTRYPOINT python main.py

All I can really contribute myself right now is a link to the offending line

PyErr_Format(PyExc_RuntimeError, "jump too big: %d", (int)delta);

Make this fork available in pyenv

This fork would be much easier to test if it was available for installation using pyenv.

Some people don't know how make or autotools work but they do know Python well enough to be familiar with pyenv.
Let's make it easier for them to test the project.

Segfault when using viztracer to profile a numpy program

Minimal reproducer:

$ pip install viztracer numpy
$ python -m viztracer -c "import numpy"
Saving trace data, this could take a whileSegmentation fault (core dumped)

Here is the gdb backtrace:

Saving trace data, this could take a while                                      
Thread 1 "python" received signal SIGSEGV, Segmentation fault.
__strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex.S:77
77	../sysdeps/x86_64/multiarch/strlen-evex.S: No such file or directory.
(gdb) bt
#0  __strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex.S:77
#1  0x00007ffff7d23ac9 in __GI__IO_fputs (str=0x0, fp=fp@entry=0x5555559b03c0) at iofputs.c:33
#2  0x00007ffff6ec6191 in fprintfeename (fptr=fptr@entry=0x5555559b03c0, node=node@entry=0x4be89f6bcf0) at src/viztracer/modules/eventnode.c:163
#3  0x00007ffff6ec7b32 in snaptrace_dump (self=0x4be7d589e20, args=<optimized out>) at src/viztracer/modules/snaptrace.c:925
#4  0x00005555557bc6ef in method_vectorcall_VARARGS (func=<method_descriptor at remote 0x4be7d42c190>, args=0x7fffffffd3e8, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/descrobject.c:316
#5  0x000055555580de52 in _PyEval_Fast (ts=0x5555559b2570, initial_acc=Register(as_int64 = 0), initial_pc=0x5555558d7d2f <func_vector_call> "\t") at Python/ceval.c:737
#6  0x00005555556a8d1f in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x5555559b2570) at Python/ceval_meta.c:2831
#7  _PyFunction_Vectorcall (func=<function at remote 0x4be7d7e4390>, stack=0x7fffffffd4a0, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3228
#8  0x00005555555c7d78 in _PyObject_FastCallDictTstate (kwargs=0x0, nargsf=1, args=0x7fffffffd4a0, callable=<function at remote 0x4be7d7e4390>, tstate=0x5555559b2570) at Objects/call.c:118
#9  _PyObject_Call_Prepend (tstate=tstate@entry=0x5555559b2570, callable=callable@entry=<function at remote 0x4be7d7e4390>, 
    obj=obj@entry=<Finalize(_weakref=<weakref at remote 0x4be7bcb7e50>, _callback=<method at remote 0x4be7bcb7db0>, _args=(), _kwargs={}, _key=(-1, 0), _pid=379537) at remote 0x4be7bc778d0>, 
    args=args@entry=(), kwargs=kwargs@entry=0x0) at Objects/call.c:387
#10 0x0000555555631bec in slot_tp_call (
    self=<Finalize(_weakref=<weakref at remote 0x4be7bcb7e50>, _callback=<method at remote 0x4be7bcb7db0>, _args=(), _kwargs={}, _key=(-1, 0), _pid=379537) at remote 0x4be7bc778d0>, args=(), kwds=0x0)
    at Objects/typeobject.c:6819
#11 0x00005555555c5a6d in _PyObject_MakeTpCall (tstate=0x5555559b2570, 
    callable=<Finalize(_weakref=<weakref at remote 0x4be7bcb7e50>, _callback=<method at remote 0x4be7bcb7db0>, _args=(), _kwargs={}, _key=(-1, 0), _pid=379537) at remote 0x4be7bc778d0>, args=<optimized out>, 
    nargs=0, keywords=0x0) at Objects/call.c:191
#12 0x00005555556a4beb in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=<optimized out>, args=0x7fffffffd5b8, 
    callable=<Finalize(_weakref=<weakref at remote 0x4be7bcb7e50>, _callback=<method at remote 0x4be7bcb7db0>, _args=(), _kwargs={}, _key=(-1, 0), _pid=379537) at remote 0x4be7bc778d0>, tstate=0x5555559b2570)
    at ./Include/cpython/abstract.h:116
#13 _PyObject_VectorcallTstate (kwnames=0x0, nargsf=<optimized out>, args=0x7fffffffd5b8, 
    callable=<Finalize(_weakref=<weakref at remote 0x4be7bcb7e50>, _callback=<method at remote 0x4be7bcb7db0>, _args=(), _kwargs={}, _key=(-1, 0), _pid=379537) at remote 0x4be7bc778d0>, tstate=0x5555559b2570)
    at ./Include/cpython/abstract.h:103
#14 vm_call_function (ts=0x5555559b2570, acc=...) at Python/ceval_meta.c:1341
#15 0x00005555558111ab in _PyEval_Fast (ts=0x5555559b2570, initial_acc=Register(as_int64 = 0), initial_pc=0x4be7d7a69a1 "F\f") at Python/ceval.c:982
#16 0x00005555556a8d1f in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x5555559b2570) at Python/ceval_meta.c:2831
#17 _PyFunction_Vectorcall (func=<function at remote 0x4be7d7e4f70>, stack=0x5555559542f0 <_Py_EmptyTupleStruct+48>, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3228
#18 0x000055555576a272 in atexit_callfuncs (module=<optimized out>) at ./Modules/atexitmodule.c:93
#19 0x000055555576a46d in atexit_run_exitfuncs (self=<optimized out>, unused=<optimized out>) at ./Modules/atexitmodule.c:192
#20 0x0000555555810c89 in _PyEval_Fast (ts=0x5555559b2570, initial_acc=Register(as_int64 = 0), initial_pc=0x5555558d9c71 <cfunc_header_noargs> "\n") at Python/ceval.c:769
#21 0x00005555556a7a11 in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x5555559b2570) at Python/ceval_meta.c:2831
[...]

Not sure if this is a bug in viztracer or in nogil CPython.

Segmentation Fault when importing scipy.stats: SystemError: NYI: function() with closure

Steps to reproduce:

pip install scipy

then:

$ gdb python
[...]
(gdb) run -c "import scipy.stats"
Starting program: /home/ogrisel/nogil-venv/bin/python -c "import scipy.stats"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/scipy/stats/__init__.py", line 441, in <module>
    from .stats import *
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/scipy/stats/stats.py", line 43, in <module>
    from . import distributions
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/scipy/stats/distributions.py", line 8, in <module>
    from ._distn_infrastructure import (rv_discrete, rv_continuous, rv_frozen)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/scipy/stats/_distn_infrastructure.py", line 27, in <module>
    from scipy import integrate
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/scipy/integrate/__init__.py", line 90, in <module>
    from ._quadrature import *
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/scipy/integrate/_quadrature.py", line 31, in <module>
    trapezoid = _copy_func(trapezoid)
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/scipy/integrate/_quadrature.py", line 24, in _copy_func
    g = types.FunctionType(f.__code__, f.__globals__, name=f.__name__,
SystemError: NYI: function() with closure

Program received signal SIGSEGV, Segmentation fault.
visit_decref (op=0x100000000, arg=0x0) at Modules/gcmodule.c:599
599         if (_PyObject_IS_GC(op)) {
(gdb) bt
#0  visit_decref (op=0x100000000, arg=0x0) at Modules/gcmodule.c:599
#1  0x00005555557c7d02 in func_traverse (op=0x4ab5df2fdd0, visit=0x5555557189b0 <visit_decref>, arg=0x0) at Objects/funcobject.c:646
#2  0x000055555571a55d in update_refs (args=0x7fffffffd7e0, gc=0x4ab5df2fdc0) at Modules/gcmodule.c:719
#3  visit_page (visitor=0x555555718460 <update_refs>, arg=0x7fffffffd7e0, page=0x4ab5dc011a8) at Modules/gcmodule.c:349
#4  visit_heap (visitor=0x555555718460 <update_refs>, arg=0x7fffffffd7e0) at Modules/gcmodule.c:399
#5  collect (tstate=tstate@entry=0x5555559a97d0, reason=reason@entry=GC_REASON_MANUAL) at Modules/gcmodule.c:1606
#6  0x000055555571c607 in PyGC_Collect () at Modules/gcmodule.c:2382
#7  _PyGC_CollectIfEnabled () at Modules/gcmodule.c:2391
#8  0x00005555556e9453 in Py_FinalizeEx () at Python/pylifecycle.c:1439
#9  0x00005555556ed0fd in Py_FinalizeEx () at Python/pylifecycle.c:1526
#10 0x00005555555b8035 in Py_RunMain () at Modules/main.c:679
#11 pymain_main (args=0x7fffffffd920) at Modules/main.c:707
#12 Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at Modules/main.c:731
#13 0x00007ffff7ccdfd0 in __libc_start_call_main (main=main@entry=0x5555555b5eb0 <main>, argc=argc@entry=3, argv=argv@entry=0x7fffffffdab8) at ../sysdeps/nptl/libc_start_call_main.h:58
#14 0x00007ffff7cce07d in __libc_start_main_impl (main=0x5555555b5eb0 <main>, argc=3, argv=0x7fffffffdab8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdaa8) at ../csu/libc-start.c:409
#15 0x00005555555b6725 in _start ()

Segmentation Fault in multithreaded numpy calls in NPY_AUXDATA_FREE(auxdata)

This might be a bug in numpy that might not be thread-safe when called without the GIL but as I am not sure, here is a report:

Reproducer:

import numpy as np
import threading, queue


def f(*args, **kwargs):
    a = np.zeros(1000)
    return a.max()


q = queue.Queue()

def worker():
    while True:
        item = q.get()
        f(item)
        q.task_done()

for i in range(2):
    threading.Thread(target=worker, daemon=True, name=f"worker-{i}").start()

for item in range(100000):
    q.put(item)

q.join()
print("done")

Most of the time, this code segfaults with the following backtrace for the segfaulting thread:

(gdb) bt full 
#0  0x0000000000000000 in ?? ()
No symbol table info available.
#1  0x00007ffff744c717 in PyUFunc_ReduceWrapper (context=context@entry=0x7ffff37a9880, operand=operand@entry=0x763584903f0, out=out@entry=0x0, wheremask=wheremask@entry=0x0, axis_flags=axis_flags@entry=0x7ffff37a9920 "\001\024", 
    reorderable=reorderable@entry=1, keepdims=<optimized out>, identity=<optimized out>, loop=<optimized out>, data=<optimized out>, buffersize=<optimized out>, funcname=<optimized out>, errormask=<optimized out>)
    at numpy/core/src/umath/reduction.c:390
        result = 0x76358490460
        skip_first_count = 1
        iter = 0x76358440a00
        op = {0x0, 0x763584903f0, 0x0}
        op_dtypes = {0x7ffff76eb5a0 <DOUBLE_Descr>, 0x7ffff76eb5a0 <DOUBLE_Descr>, 0x0}
        it_flags = <optimized out>
        op_flags = {51445760, 135397376, 4076500728}
        auxdata = 0x76357823200
        result_axes = {1073741823, 0, 1432964862, 21845, 0, 0, 7, 0, 1, 0, 0, 0, 0, 0, 32, 0, -210070176, 32767, 1481180144, 1891, 1, 0, -148001903, 32767, -144562068, 32767, -210070216, 32767, 1481180144, 1891, 1481180144, 1891}
        op_axes = {0x7ffff37a93a0, 0x0, 0x0}
        curr_axis = <optimized out>
        strided_loop = 0x7ffff757a2a0 <generic_wrapped_legacy_loop>
        flags = 0
        needs_api = <optimized out>
        fixed_strides = {0, 8, 0}
#2  0x00007ffff758605d in PyUFunc_Reduce (wheremask=0x0, initial=<optimized out>, keepdims=<optimized out>, signature=0x7ffff37a97a0, axes=0x7ffff37a98a0, naxes=<optimized out>, out=<optimized out>, arr=0x763584903f0, ufunc=<optimized out>)
    at numpy/core/src/umath/ufunc_object.c:2994
        ndim = <optimized out>
        reorderable = <optimized out>
        ufunc_name = 0x7ffff761f1f0 "maximum"
        ufuncimpl = <optimized out>
        iaxes = <optimized out>
        axis_flags = "\001\024\000\344\377\177\000\000@\037", '\000' <repeats 14 times>, "fh)\367\377\177\000"
        errormask = 521
        descrs = {0x7ffff76eb5a0 <DOUBLE_Descr>, 0x7ffff76eb5a0 <DOUBLE_Descr>, 0x7ffff76eb5a0 <DOUBLE_Descr>}
        identity = <optimized out>
        buffersize = 8192
        context = {caller = 0x76356cbb510, method = 0x76357541da0, descriptors = 0x7ffff37a9860}
        result = <optimized out>
        iaxes = <optimized out>
        ndim = <optimized out>
        reorderable = <optimized out>
        axis_flags = <optimized out>
        identity = <optimized out>
        ufunc_name = <optimized out>
        buffersize = <optimized out>
        errormask = <optimized out>
        descrs = <optimized out>
        ufuncimpl = <optimized out>
        context = <optimized out>
        result = <optimized out>
        axis = <optimized out>
        i = <optimized out>
#3  PyUFunc_GenericReduction (ufunc=<optimized out>, args=<optimized out>, len_args=<optimized out>, kwnames=<optimized out>, operation=<optimized out>) at numpy/core/src/umath/ufunc_object.c:4155
        i = <optimized out>
        naxes = <optimized out>
        ndim = <optimized out>
        axes = {0, 32767, 130000, 11, -469762016, 32767, 8000, 0, -469756880, 32767, 35478272, 211012178, 1436352528, 21845, 8000, 0, 1436521568, 21845, 1433340642, 21845, 1436521568, 21845, 8000, 0, 8000, 0, -469756864, 32767, 1436521568, 21845, 
          -143743520, 32767}
        full_args = {in = 0x76358420d50, out = 0x0}
        axes_obj = 0x555555948a80 <_Py_NoneStruct>
        mp = <optimized out>
        wheremask = 0x0
        ret = 0x0
        op = 0x763584903f0
        indices = <optimized out>
        signature = {0x76356d05800, 0x76356d05800, 0x76356d05800}
        out = 0x0
        keepdims = 0
        initial = 0x0
        out_is_passed_by_position = <optimized out>
        _reduce_type = {0x7ffff762286c "reduce", 0x7ffff7622873 "accumulate", 0x7ffff762533b "reduceat", 0x0}
        otype_obj = 0x555555948a80 <_Py_NoneStruct>
        out_obj = 0x555555948a80 <_Py_NoneStruct>
        indices_obj = 0x0
        keepdims_obj = 0x55555593c080 <_Py_FalseStruct>
        wheremask_obj = 0x55555593c040 <_Py_TrueStruct>
        override = 0x0
        errval = <optimized out>
#4  0x00005555557cb811 in cfunction_vectorcall_FASTCALL_KEYWORDS (func=0x763574fb4d0, args=0x7ffff37a9b88, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/methodobject.c:464
--Type <RET> for more, q to quit, c to continue without paging--
        tstate = 0x5555559f9460
        nargs = 7
        meth = <optimized out>
        result = <optimized out>
#5  0x000055555580cdc6 in _PyEval_Fast (ts=0x5555559f9460, initial_acc=..., initial_pc=0x5555558d0bcc <func_vector_call> "\t") at Python/ceval.c:731
        nargs = 8123251307008
        func = <optimized out>
        nargsf = <optimized out>
        res = 0x76357823200
        frame_delta = 8123251307008
        opcode_targets_base = {0x0, 0x55555580e54c <_PyEval_Fast+6604>, 0x55555580e4f0 <_PyEval_Fast+6512>, 0x55555580e4cd <_PyEval_Fast+6477>, 0x55555580e494 <_PyEval_Fast+6420>, 0x55555580e42d <_PyEval_Fast+6317>, 
          0x55555580f525 <_PyEval_Fast+10661>, 0x55555580ddca <_PyEval_Fast+4682>, 0x5555555b5ea2 <_PyEval_Fast.cold>, 0x55555580cd0f <_PyEval_Fast+399>, 0x55555580cd02 <_PyEval_Fast+386>, 0x55555580dcde <_PyEval_Fast+4446>, 
          0x55555580fa35 <_PyEval_Fast+11957>, 0x55555580f93d <_PyEval_Fast+11709>, 0x55555580fb3a <_PyEval_Fast+12218>, 0x55555580e1ea <_PyEval_Fast+5738>, 0x55555580e243 <_PyEval_Fast+5827>, 0x55555580e2f5 <_PyEval_Fast+6005>, 
          0x55555580e350 <_PyEval_Fast+6096>, 0x55555580e29c <_PyEval_Fast+5916>, 0x55555580d9f1 <_PyEval_Fast+3697>, 0x55555580d983 <_PyEval_Fast+3587>, 0x55555580d7d7 <_PyEval_Fast+3159>, 0x55555580d842 <_PyEval_Fast+3266>, 
          0x55555580e376 <_PyEval_Fast+6134>, 0x55555580d76c <_PyEval_Fast+3052>, 0x55555580d66d <_PyEval_Fast+2797>, 0x55555580d918 <_PyEval_Fast+3480>, 0x55555580d8ad <_PyEval_Fast+3373>, 0x55555580da5c <_PyEval_Fast+3804>, 
          0x55555580dac7 <_PyEval_Fast+3911>, 0x55555580db32 <_PyEval_Fast+4018>, 0x55555580db9d <_PyEval_Fast+4125>, 0x55555580dc08 <_PyEval_Fast+4232>, 0x55555580e125 <_PyEval_Fast+5541>, 0x55555580e181 <_PyEval_Fast+5633>, 
          0x55555580e0b6 <_PyEval_Fast+5430>, 0x55555580d4be <_PyEval_Fast+2366>, 0x55555580d453 <_PyEval_Fast+2259>, 0x55555580dc73 <_PyEval_Fast+4339>, 0x55555580d312 <_PyEval_Fast+1938>, 0x55555580d37d <_PyEval_Fast+2045>, 
          0x55555580d602 <_PyEval_Fast+2690>, 0x55555580d0b8 <_PyEval_Fast+1336>, 0x55555580d11f <_PyEval_Fast+1439>, 0x55555580d18a <_PyEval_Fast+1546>, 0x55555580e789 <_PyEval_Fast+7177>, 0x55555580d3e8 <_PyEval_Fast+2152>, 
          0x55555580d597 <_PyEval_Fast+2583>, 0x55555580d529 <_PyEval_Fast+2473>, 0x55555580e751 <_PyEval_Fast+7121>, 0x55555580ce6d <_PyEval_Fast+749>, 0x55555580f3af <_PyEval_Fast+10287>, 0x55555580cfc4 <_PyEval_Fast+1092>, 
          0x55555580cea9 <_PyEval_Fast+809>, 0x55555580d1f5 <_PyEval_Fast+1653>, 0x55555580e58e <_PyEval_Fast+6670>, 0x55555580ded0 <_PyEval_Fast+4944>, 0x55555580e3e1 <_PyEval_Fast+6241>, 0x55555580cf54 <_PyEval_Fast+980>, 
          0x55555580e6ea <_PyEval_Fast+7018>, 0x55555580e615 <_PyEval_Fast+6805>, 0x55555580e679 <_PyEval_Fast+6905>, 0x55555580e5d6 <_PyEval_Fast+6742>, 0x55555580df0a <_PyEval_Fast+5002>, 0x55555580df4e <_PyEval_Fast+5070>, 
          0x55555580dfbf <_PyEval_Fast+5183>, 0x55555580df84 <_PyEval_Fast+5124>, 0x55555580e016 <_PyEval_Fast+5270>, 0x55555580e06f <_PyEval_Fast+5359>, 0x55555580f613 <_PyEval_Fast+10899>, 0x55555580f62e <_PyEval_Fast+10926>, 
          0x55555580f5ad <_PyEval_Fast+10797>, 0x55555580f2b8 <_PyEval_Fast+10040>, 0x55555580f31d <_PyEval_Fast+10141>, 0x55555580f87c <_PyEval_Fast+11516>, 0x55555580ef19 <_PyEval_Fast+9113>, 0x55555580f6e6 <_PyEval_Fast+11110>, 
          0x55555580f720 <_PyEval_Fast+11168>, 0x55555580f3cd <_PyEval_Fast+10317>, 0x55555580f493 <_PyEval_Fast+10515>, 0x55555580f4e9 <_PyEval_Fast+10601>, 0x55555580ef4d <_PyEval_Fast+9165>, 0x55555580f3f7 <_PyEval_Fast+10359>, 
          0x55555580f452 <_PyEval_Fast+10450>, 0x55555580cc3e <_PyEval_Fast+190>, 0x55555580e7f4 <_PyEval_Fast+7284>, 0x55555580e8c3 <_PyEval_Fast+7491>, 0x55555580d6d8 <_PyEval_Fast+2904>, 0x55555580d720 <_PyEval_Fast+2976>, 
          0x55555580de90 <_PyEval_Fast+4880>, 0x55555580ea87 <_PyEval_Fast+7943>, 0x55555580eb7c <_PyEval_Fast+8188>, 0x55555580eab8 <_PyEval_Fast+7992>, 0x55555580eb46 <_PyEval_Fast+8134>, 0x55555580ec04 <_PyEval_Fast+8324>, 
          0x55555580efb0 <_PyEval_Fast+9264>, 0x55555580f01c <_PyEval_Fast+9372>, 0x55555580f069 <_PyEval_Fast+9449>, 0x55555580eedf <_PyEval_Fast+9055>, 0x55555580e853 <_PyEval_Fast+7379>, 0x55555580e91b <_PyEval_Fast+7579>, 
          0x55555580e9b1 <_PyEval_Fast+7729>, 0x55555580f16a <_PyEval_Fast+9706>, 0x55555580ea59 <_PyEval_Fast+7897>, 0x55555580ee4e <_PyEval_Fast+8910>, 0x55555580f577 <_PyEval_Fast+10743>, 0x55555580f0c8 <_PyEval_Fast+9544>, 
          0x55555580f13c <_PyEval_Fast+9660>, 0x55555580f102 <_PyEval_Fast+9602>, 0x55555580ed42 <_PyEval_Fast+8642>, 0x55555580ece9 <_PyEval_Fast+8553>, 0x55555580ed9c <_PyEval_Fast+8732>, 0x55555580edf5 <_PyEval_Fast+8821>, 
          0x55555580ec8b <_PyEval_Fast+8459>, 0x55555580ec32 <_PyEval_Fast+8370>, 0x55555580f287 <_PyEval_Fast+9991>, 0x55555580f257 <_PyEval_Fast+9943>, 0x55555580f399 <_PyEval_Fast+10265>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 11 times>, 
          0x5555558119c9 <_PyEval_Fast+20041>, 0x555555811a08 <_PyEval_Fast+20104>, 0x555555811a29 <_PyEval_Fast+20137>, 0x555555811a60 <_PyEval_Fast+20192>, 0x55555581080f <_PyEval_Fast+15503>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 13 times>, 
          0x55555581228f <_PyEval_Fast+22287>, 0x5555558122fc <_PyEval_Fast+22396>, 0x555555811f94 <_PyEval_Fast+21524>, 0x555555811f27 <_PyEval_Fast+21415>, 0x5555558123fd <_PyEval_Fast+22653>, 0x555555810700 <_PyEval_Fast+15232>, 
          0x555555810aa1 <_PyEval_Fast+16161>, 0x5555558107a2 <_PyEval_Fast+15394>, 0x555555812001 <_PyEval_Fast+21633>, 0x5555558120db <_PyEval_Fast+21851>, 0x55555581206e <_PyEval_Fast+21742>, 0x5555558121b5 <_PyEval_Fast+22069>, 
          0x555555812148 <_PyEval_Fast+21960>, 0x555555812222 <_PyEval_Fast+22178>, 0x5555558124d5 <_PyEval_Fast+22869>, 0x55555581246a <_PyEval_Fast+22762>, 0x555555811c3c <_PyEval_Fast+20668>, 0x555555810e0c <_PyEval_Fast+17036>, 
          0x555555810e79 <_PyEval_Fast+17145>, 0x5555558118d7 <_PyEval_Fast+19799>, 0x5555558125a4 <_PyEval_Fast+23076>, 0x555555812537 <_PyEval_Fast+22967>, 0x555555810cc2 <_PyEval_Fast+16706>, 0x555555810c55 <_PyEval_Fast+16597>, 
          0x555555810be8 <_PyEval_Fast+16488>, 0x555555810b7b <_PyEval_Fast+16379>, 0x555555810b0e <_PyEval_Fast+16270>, 0x555555811dda <_PyEval_Fast+21082>, 0x555555810d2f <_PyEval_Fast+16815>, 0x555555810d9c <_PyEval_Fast+16924>, 
          0x555555811aec <_PyEval_Fast+20332>, 0x555555812611 <_PyEval_Fast+23185>, 0x555555810ee6 <_PyEval_Fast+17254>, 0x5555558117d0 <_PyEval_Fast+19536>, 0x55555581062f <_PyEval_Fast+15023>, 0x555555811711 <_PyEval_Fast+19345>, 
          0x555555811982 <_PyEval_Fast+19970>, 0x55555581282e <_PyEval_Fast+23726>, 0x555555811aac <_PyEval_Fast+20268>, 0x5555558116a2 <_PyEval_Fast+19234>, 0x555555811562 <_PyEval_Fast+18914>, 0x55555581163f <_PyEval_Fast+19135>, 
          0x5555558115ca <_PyEval_Fast+19018>, 0x555555811944 <_PyEval_Fast+19908>, 0x5555558127eb <_PyEval_Fast+23659>, 0x55555581076d <_PyEval_Fast+15341>, 0x555555811d4a <_PyEval_Fast+20938>, 0x555555811da0 <_PyEval_Fast+21024>, 
          0x555555811cf2 <_PyEval_Fast+20850>, 0x555555811cac <_PyEval_Fast+20780>, 0x555555811481 <_PyEval_Fast+18689>, 0x55555581236c <_PyEval_Fast+22508>, 0x5555558114dc <_PyEval_Fast+18780>, 0x555555812787 <_PyEval_Fast+23559>, 
          0x555555812743 <_PyEval_Fast+23491>, 0x5555555b5ea2 <_PyEval_Fast.cold>...}
        pc = 0x5555558d0bcc <func_vector_call> "\t"
        opcode = <optimized out>
        acc = <optimized out>
        regs = <optimized out>
        constants = 0x763574ce9f8
        tid = <optimized out>
#6  0x00005555556a86bf in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x5555559f9460) at Python/ceval_meta.c:2788
        ret = <optimized out>
        cargs = {0x1, 0x763584903f0, 0x555555948a80 <_Py_NoneStruct>, 0x555555948a80 <_Py_NoneStruct>, 0x555555948a80 <_Py_NoneStruct>, 0x55555593c080 <_Py_FalseStruct>, 0x76356eb63d0, 0x55555593c040 <_Py_TrueStruct>, 0x1}
        prevargs = 0x7ffff37a9d08
        ret = <optimized out>
        cargs = <optimized out>
        prevargs = <optimized out>
#7  _PyFunction_Vectorcall (func=0x763575e7130, stack=0x76358420e30, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3185
        tstate = 0x5555559f9460
        nargs = 1
        nkwargs = <optimized out>
        ret = 0x0
        acc = {as_int64 = 1}
        err = 0
        extra = <optimized out>
#8  0x00007ffff739ce87 in forward_ndarray_method (self=<optimized out>, args=0x55555594b2d0 <_Py_EmptyTupleStruct+16>, kwds=0x0, forwarding_callable=0x763575e7130) at numpy/core/src/multiarray/methods.c:89
        sargs = 0x76358420e10
        ret = <optimized out>
        i = <optimized out>
        n = <optimized out>
#9  0x00005555557bdbfb in method_vectorcall_VARARGS_KEYWORDS (func=0x7635743c6d0, args=0x7ffff37a9d08, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/descrobject.c:349
        tstate = 0x5555559f9460
        nargs = 1
        argstuple = 0x55555594b2d0 <_Py_EmptyTupleStruct+16>
        result = 0x0
        kwdict = 0x0
        meth = <optimized out>
#10 0x000055555580cdc6 in _PyEval_Fast (ts=0x5555559f9460, initial_acc=..., initial_pc=0x5555558cec6f <func_vector_call> "\t") at Python/ceval.c:731
--Type <RET> for more, q to quit, c to continue without paging--
        nargs = 8123251307008
        func = <optimized out>
        nargsf = <optimized out>
        res = 0x76357823200
        frame_delta = 8123251307008
        opcode_targets_base = {0x0, 0x55555580e54c <_PyEval_Fast+6604>, 0x55555580e4f0 <_PyEval_Fast+6512>, 0x55555580e4cd <_PyEval_Fast+6477>, 0x55555580e494 <_PyEval_Fast+6420>, 0x55555580e42d <_PyEval_Fast+6317>, 
          0x55555580f525 <_PyEval_Fast+10661>, 0x55555580ddca <_PyEval_Fast+4682>, 0x5555555b5ea2 <_PyEval_Fast.cold>, 0x55555580cd0f <_PyEval_Fast+399>, 0x55555580cd02 <_PyEval_Fast+386>, 0x55555580dcde <_PyEval_Fast+4446>, 
          0x55555580fa35 <_PyEval_Fast+11957>, 0x55555580f93d <_PyEval_Fast+11709>, 0x55555580fb3a <_PyEval_Fast+12218>, 0x55555580e1ea <_PyEval_Fast+5738>, 0x55555580e243 <_PyEval_Fast+5827>, 0x55555580e2f5 <_PyEval_Fast+6005>, 
          0x55555580e350 <_PyEval_Fast+6096>, 0x55555580e29c <_PyEval_Fast+5916>, 0x55555580d9f1 <_PyEval_Fast+3697>, 0x55555580d983 <_PyEval_Fast+3587>, 0x55555580d7d7 <_PyEval_Fast+3159>, 0x55555580d842 <_PyEval_Fast+3266>, 
          0x55555580e376 <_PyEval_Fast+6134>, 0x55555580d76c <_PyEval_Fast+3052>, 0x55555580d66d <_PyEval_Fast+2797>, 0x55555580d918 <_PyEval_Fast+3480>, 0x55555580d8ad <_PyEval_Fast+3373>, 0x55555580da5c <_PyEval_Fast+3804>, 
          0x55555580dac7 <_PyEval_Fast+3911>, 0x55555580db32 <_PyEval_Fast+4018>, 0x55555580db9d <_PyEval_Fast+4125>, 0x55555580dc08 <_PyEval_Fast+4232>, 0x55555580e125 <_PyEval_Fast+5541>, 0x55555580e181 <_PyEval_Fast+5633>, 
          0x55555580e0b6 <_PyEval_Fast+5430>, 0x55555580d4be <_PyEval_Fast+2366>, 0x55555580d453 <_PyEval_Fast+2259>, 0x55555580dc73 <_PyEval_Fast+4339>, 0x55555580d312 <_PyEval_Fast+1938>, 0x55555580d37d <_PyEval_Fast+2045>, 
          0x55555580d602 <_PyEval_Fast+2690>, 0x55555580d0b8 <_PyEval_Fast+1336>, 0x55555580d11f <_PyEval_Fast+1439>, 0x55555580d18a <_PyEval_Fast+1546>, 0x55555580e789 <_PyEval_Fast+7177>, 0x55555580d3e8 <_PyEval_Fast+2152>, 
          0x55555580d597 <_PyEval_Fast+2583>, 0x55555580d529 <_PyEval_Fast+2473>, 0x55555580e751 <_PyEval_Fast+7121>, 0x55555580ce6d <_PyEval_Fast+749>, 0x55555580f3af <_PyEval_Fast+10287>, 0x55555580cfc4 <_PyEval_Fast+1092>, 
          0x55555580cea9 <_PyEval_Fast+809>, 0x55555580d1f5 <_PyEval_Fast+1653>, 0x55555580e58e <_PyEval_Fast+6670>, 0x55555580ded0 <_PyEval_Fast+4944>, 0x55555580e3e1 <_PyEval_Fast+6241>, 0x55555580cf54 <_PyEval_Fast+980>, 
          0x55555580e6ea <_PyEval_Fast+7018>, 0x55555580e615 <_PyEval_Fast+6805>, 0x55555580e679 <_PyEval_Fast+6905>, 0x55555580e5d6 <_PyEval_Fast+6742>, 0x55555580df0a <_PyEval_Fast+5002>, 0x55555580df4e <_PyEval_Fast+5070>, 
          0x55555580dfbf <_PyEval_Fast+5183>, 0x55555580df84 <_PyEval_Fast+5124>, 0x55555580e016 <_PyEval_Fast+5270>, 0x55555580e06f <_PyEval_Fast+5359>, 0x55555580f613 <_PyEval_Fast+10899>, 0x55555580f62e <_PyEval_Fast+10926>, 
          0x55555580f5ad <_PyEval_Fast+10797>, 0x55555580f2b8 <_PyEval_Fast+10040>, 0x55555580f31d <_PyEval_Fast+10141>, 0x55555580f87c <_PyEval_Fast+11516>, 0x55555580ef19 <_PyEval_Fast+9113>, 0x55555580f6e6 <_PyEval_Fast+11110>, 
          0x55555580f720 <_PyEval_Fast+11168>, 0x55555580f3cd <_PyEval_Fast+10317>, 0x55555580f493 <_PyEval_Fast+10515>, 0x55555580f4e9 <_PyEval_Fast+10601>, 0x55555580ef4d <_PyEval_Fast+9165>, 0x55555580f3f7 <_PyEval_Fast+10359>, 
          0x55555580f452 <_PyEval_Fast+10450>, 0x55555580cc3e <_PyEval_Fast+190>, 0x55555580e7f4 <_PyEval_Fast+7284>, 0x55555580e8c3 <_PyEval_Fast+7491>, 0x55555580d6d8 <_PyEval_Fast+2904>, 0x55555580d720 <_PyEval_Fast+2976>, 
          0x55555580de90 <_PyEval_Fast+4880>, 0x55555580ea87 <_PyEval_Fast+7943>, 0x55555580eb7c <_PyEval_Fast+8188>, 0x55555580eab8 <_PyEval_Fast+7992>, 0x55555580eb46 <_PyEval_Fast+8134>, 0x55555580ec04 <_PyEval_Fast+8324>, 
          0x55555580efb0 <_PyEval_Fast+9264>, 0x55555580f01c <_PyEval_Fast+9372>, 0x55555580f069 <_PyEval_Fast+9449>, 0x55555580eedf <_PyEval_Fast+9055>, 0x55555580e853 <_PyEval_Fast+7379>, 0x55555580e91b <_PyEval_Fast+7579>, 
          0x55555580e9b1 <_PyEval_Fast+7729>, 0x55555580f16a <_PyEval_Fast+9706>, 0x55555580ea59 <_PyEval_Fast+7897>, 0x55555580ee4e <_PyEval_Fast+8910>, 0x55555580f577 <_PyEval_Fast+10743>, 0x55555580f0c8 <_PyEval_Fast+9544>, 
          0x55555580f13c <_PyEval_Fast+9660>, 0x55555580f102 <_PyEval_Fast+9602>, 0x55555580ed42 <_PyEval_Fast+8642>, 0x55555580ece9 <_PyEval_Fast+8553>, 0x55555580ed9c <_PyEval_Fast+8732>, 0x55555580edf5 <_PyEval_Fast+8821>, 
          0x55555580ec8b <_PyEval_Fast+8459>, 0x55555580ec32 <_PyEval_Fast+8370>, 0x55555580f287 <_PyEval_Fast+9991>, 0x55555580f257 <_PyEval_Fast+9943>, 0x55555580f399 <_PyEval_Fast+10265>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 11 times>, 
          0x5555558119c9 <_PyEval_Fast+20041>, 0x555555811a08 <_PyEval_Fast+20104>, 0x555555811a29 <_PyEval_Fast+20137>, 0x555555811a60 <_PyEval_Fast+20192>, 0x55555581080f <_PyEval_Fast+15503>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 13 times>, 
          0x55555581228f <_PyEval_Fast+22287>, 0x5555558122fc <_PyEval_Fast+22396>, 0x555555811f94 <_PyEval_Fast+21524>, 0x555555811f27 <_PyEval_Fast+21415>, 0x5555558123fd <_PyEval_Fast+22653>, 0x555555810700 <_PyEval_Fast+15232>, 
          0x555555810aa1 <_PyEval_Fast+16161>, 0x5555558107a2 <_PyEval_Fast+15394>, 0x555555812001 <_PyEval_Fast+21633>, 0x5555558120db <_PyEval_Fast+21851>, 0x55555581206e <_PyEval_Fast+21742>, 0x5555558121b5 <_PyEval_Fast+22069>, 
          0x555555812148 <_PyEval_Fast+21960>, 0x555555812222 <_PyEval_Fast+22178>, 0x5555558124d5 <_PyEval_Fast+22869>, 0x55555581246a <_PyEval_Fast+22762>, 0x555555811c3c <_PyEval_Fast+20668>, 0x555555810e0c <_PyEval_Fast+17036>, 
          0x555555810e79 <_PyEval_Fast+17145>, 0x5555558118d7 <_PyEval_Fast+19799>, 0x5555558125a4 <_PyEval_Fast+23076>, 0x555555812537 <_PyEval_Fast+22967>, 0x555555810cc2 <_PyEval_Fast+16706>, 0x555555810c55 <_PyEval_Fast+16597>, 
          0x555555810be8 <_PyEval_Fast+16488>, 0x555555810b7b <_PyEval_Fast+16379>, 0x555555810b0e <_PyEval_Fast+16270>, 0x555555811dda <_PyEval_Fast+21082>, 0x555555810d2f <_PyEval_Fast+16815>, 0x555555810d9c <_PyEval_Fast+16924>, 
          0x555555811aec <_PyEval_Fast+20332>, 0x555555812611 <_PyEval_Fast+23185>, 0x555555810ee6 <_PyEval_Fast+17254>, 0x5555558117d0 <_PyEval_Fast+19536>, 0x55555581062f <_PyEval_Fast+15023>, 0x555555811711 <_PyEval_Fast+19345>, 
          0x555555811982 <_PyEval_Fast+19970>, 0x55555581282e <_PyEval_Fast+23726>, 0x555555811aac <_PyEval_Fast+20268>, 0x5555558116a2 <_PyEval_Fast+19234>, 0x555555811562 <_PyEval_Fast+18914>, 0x55555581163f <_PyEval_Fast+19135>, 
          0x5555558115ca <_PyEval_Fast+19018>, 0x555555811944 <_PyEval_Fast+19908>, 0x5555558127eb <_PyEval_Fast+23659>, 0x55555581076d <_PyEval_Fast+15341>, 0x555555811d4a <_PyEval_Fast+20938>, 0x555555811da0 <_PyEval_Fast+21024>, 
          0x555555811cf2 <_PyEval_Fast+20850>, 0x555555811cac <_PyEval_Fast+20780>, 0x555555811481 <_PyEval_Fast+18689>, 0x55555581236c <_PyEval_Fast+22508>, 0x5555558114dc <_PyEval_Fast+18780>, 0x555555812787 <_PyEval_Fast+23559>, 
          0x555555812743 <_PyEval_Fast+23491>, 0x5555555b5ea2 <_PyEval_Fast.cold>...}
        pc = 0x5555558cec6f <func_vector_call> "\t"
        opcode = <optimized out>
        acc = <optimized out>
        regs = <optimized out>
        constants = 0x76356ea2b40
        tid = <optimized out>
#11 0x00005555556a86bf in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x5555559f9460) at Python/ceval_meta.c:2788
        ret = <optimized out>
        cargs = {0x0, 0x763584903f0, 0x55555593c080 <_Py_FalseStruct>, 0x7ffff2fa9ac0, 0x7ffff2fa9b60, 0x4, 0x2, 0x3200000008, 0x0}
        prevargs = 0x0
        ret = <optimized out>
        cargs = <optimized out>
        prevargs = <optimized out>
#12 _PyFunction_Vectorcall (func=0x76356df0470, stack=0x7ffff37a9da8, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3185
        tstate = 0x5555559f9460
        nargs = 1
        nkwargs = <optimized out>
        ret = 0x0
        acc = {as_int64 = 1}
        err = 0
        extra = <optimized out>
#13 0x00005555557b3ab4 in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=1, args=0x7ffff37a9da8, callable=0x76356df0470, tstate=0x5555559f9460) at ./Include/cpython/abstract.h:118
        func = <optimized out>
        res = <optimized out>
        nargs = <optimized out>
#14 method_vectorcall (method=<optimized out>, args=0x55555594b2f0 <_Py_EmptyTupleStruct+48>, nargsf=<optimized out>, kwnames=0x0) at Objects/classobject.c:62
        nkwargs = <optimized out>
        totalargs = <optimized out>
        newargs_stack = {0x7fffffffd35f, 0x5555559f9460, 0x5555559f9460, 0xc93ca52021d5b00, 0x55555599bc60 <_PyRuntime+640>}
        newargs = <optimized out>
        tstate = 0x5555559f9460
        self = 0x763568f8e90
        func = 0x76356df0470
        nargs = 0
        result = <optimized out>
#15 0x0000555555771a41 in t_bootstrap (boot_raw=0x7635795ba30) at ./Modules/_threadmodule.c:1289
        boot = 0x7635795ba30
        tstate = 0x5555559f9460
        res = <optimized out>
--Type <RET> for more, q to quit, c to continue without paging--
#16 0x00005555557064bb in pythread_wrapper (arg=<optimized out>) at Python/thread_pthread.h:245
        callback = <optimized out>
        func = 0x5555557719f0 <t_bootstrap>
        func_arg = 0x7635795ba30
#17 0x00007ffff7d38947 in start_thread (arg=<optimized out>) at pthread_create.c:435
        ret = <optimized out>
        pd = <optimized out>
        out = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140737278289472, -7107990009691300924, 140737488343902, 140737488343903, 0, 140737269899264, 7108015344611171268, 7108007434102184900}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, 
            data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
#18 0x00007ffff7dc8a44 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
No locals.
(gdb) bt full 
#0  0x0000000000000000 in ?? ()
No symbol table info available.
#1  0x00007ffff744c717 in PyUFunc_ReduceWrapper (context=context@entry=0x7ffff37a9880, operand=operand@entry=0x763584903f0, out=out@entry=0x0, wheremask=wheremask@entry=0x0, axis_flags=axis_flags@entry=0x7ffff37a9920 "\001\024", 
    reorderable=reorderable@entry=1, keepdims=<optimized out>, identity=<optimized out>, loop=<optimized out>, data=<optimized out>, buffersize=<optimized out>, funcname=<optimized out>, errormask=<optimized out>)
    at numpy/core/src/umath/reduction.c:390
        result = 0x76358490460
        skip_first_count = 1
        iter = 0x76358440a00
        op = {0x0, 0x763584903f0, 0x0}
        op_dtypes = {0x7ffff76eb5a0 <DOUBLE_Descr>, 0x7ffff76eb5a0 <DOUBLE_Descr>, 0x0}
        it_flags = <optimized out>
        op_flags = {51445760, 135397376, 4076500728}
        auxdata = 0x76357823200
        result_axes = {1073741823, 0, 1432964862, 21845, 0, 0, 7, 0, 1, 0, 0, 0, 0, 0, 32, 0, -210070176, 32767, 1481180144, 1891, 1, 0, -148001903, 32767, -144562068, 32767, -210070216, 32767, 1481180144, 1891, 1481180144, 1891}
        op_axes = {0x7ffff37a93a0, 0x0, 0x0}
        curr_axis = <optimized out>
        strided_loop = 0x7ffff757a2a0 <generic_wrapped_legacy_loop>
        flags = 0
        needs_api = <optimized out>
        fixed_strides = {0, 8, 0}
#2  0x00007ffff758605d in PyUFunc_Reduce (wheremask=0x0, initial=<optimized out>, keepdims=<optimized out>, signature=0x7ffff37a97a0, axes=0x7ffff37a98a0, naxes=<optimized out>, out=<optimized out>, arr=0x763584903f0, ufunc=<optimized out>)
    at numpy/core/src/umath/ufunc_object.c:2994
        ndim = <optimized out>
        reorderable = <optimized out>
        ufunc_name = 0x7ffff761f1f0 "maximum"
        ufuncimpl = <optimized out>
        iaxes = <optimized out>
        axis_flags = "\001\024\000\344\377\177\000\000@\037", '\000' <repeats 14 times>, "fh)\367\377\177\000"
        errormask = 521
        descrs = {0x7ffff76eb5a0 <DOUBLE_Descr>, 0x7ffff76eb5a0 <DOUBLE_Descr>, 0x7ffff76eb5a0 <DOUBLE_Descr>}
        identity = <optimized out>
        buffersize = 8192
        context = {caller = 0x76356cbb510, method = 0x76357541da0, descriptors = 0x7ffff37a9860}
        result = <optimized out>
        iaxes = <optimized out>
        ndim = <optimized out>
        reorderable = <optimized out>
        axis_flags = <optimized out>
        identity = <optimized out>
        ufunc_name = <optimized out>
        buffersize = <optimized out>
        errormask = <optimized out>
        descrs = <optimized out>
        ufuncimpl = <optimized out>
        context = <optimized out>
        result = <optimized out>
        axis = <optimized out>
        i = <optimized out>
#3  PyUFunc_GenericReduction (ufunc=<optimized out>, args=<optimized out>, len_args=<optimized out>, kwnames=<optimized out>, operation=<optimized out>) at numpy/core/src/umath/ufunc_object.c:4155
        i = <optimized out>
        naxes = <optimized out>
        ndim = <optimized out>
        axes = {0, 32767, 130000, 11, -469762016, 32767, 8000, 0, -469756880, 32767, 35478272, 211012178, 1436352528, 21845, 8000, 0, 1436521568, 21845, 1433340642, 21845, 1436521568, 21845, 8000, 0, 8000, 0, -469756864, 32767, 1436521568, 21845, 
          -143743520, 32767}
        full_args = {in = 0x76358420d50, out = 0x0}
        axes_obj = 0x555555948a80 <_Py_NoneStruct>
        mp = <optimized out>
        wheremask = 0x0
        ret = 0x0
        op = 0x763584903f0
        indices = <optimized out>
        signature = {0x76356d05800, 0x76356d05800, 0x76356d05800}
        out = 0x0
        keepdims = 0
        initial = 0x0
        out_is_passed_by_position = <optimized out>
        _reduce_type = {0x7ffff762286c "reduce", 0x7ffff7622873 "accumulate", 0x7ffff762533b "reduceat", 0x0}
        otype_obj = 0x555555948a80 <_Py_NoneStruct>
        out_obj = 0x555555948a80 <_Py_NoneStruct>
        indices_obj = 0x0
        keepdims_obj = 0x55555593c080 <_Py_FalseStruct>
        wheremask_obj = 0x55555593c040 <_Py_TrueStruct>
        override = 0x0
        errval = <optimized out>
#4  0x00005555557cb811 in cfunction_vectorcall_FASTCALL_KEYWORDS (func=0x763574fb4d0, args=0x7ffff37a9b88, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/methodobject.c:464
--Type <RET> for more, q to quit, c to continue without paging--
        tstate = 0x5555559f9460
        nargs = 7
        meth = <optimized out>
        result = <optimized out>
#5  0x000055555580cdc6 in _PyEval_Fast (ts=0x5555559f9460, initial_acc=..., initial_pc=0x5555558d0bcc <func_vector_call> "\t") at Python/ceval.c:731
        nargs = 8123251307008
        func = <optimized out>
        nargsf = <optimized out>
        res = 0x76357823200
        frame_delta = 8123251307008
        opcode_targets_base = {0x0, 0x55555580e54c <_PyEval_Fast+6604>, 0x55555580e4f0 <_PyEval_Fast+6512>, 0x55555580e4cd <_PyEval_Fast+6477>, 0x55555580e494 <_PyEval_Fast+6420>, 0x55555580e42d <_PyEval_Fast+6317>, 
          0x55555580f525 <_PyEval_Fast+10661>, 0x55555580ddca <_PyEval_Fast+4682>, 0x5555555b5ea2 <_PyEval_Fast.cold>, 0x55555580cd0f <_PyEval_Fast+399>, 0x55555580cd02 <_PyEval_Fast+386>, 0x55555580dcde <_PyEval_Fast+4446>, 
          0x55555580fa35 <_PyEval_Fast+11957>, 0x55555580f93d <_PyEval_Fast+11709>, 0x55555580fb3a <_PyEval_Fast+12218>, 0x55555580e1ea <_PyEval_Fast+5738>, 0x55555580e243 <_PyEval_Fast+5827>, 0x55555580e2f5 <_PyEval_Fast+6005>, 
          0x55555580e350 <_PyEval_Fast+6096>, 0x55555580e29c <_PyEval_Fast+5916>, 0x55555580d9f1 <_PyEval_Fast+3697>, 0x55555580d983 <_PyEval_Fast+3587>, 0x55555580d7d7 <_PyEval_Fast+3159>, 0x55555580d842 <_PyEval_Fast+3266>, 
          0x55555580e376 <_PyEval_Fast+6134>, 0x55555580d76c <_PyEval_Fast+3052>, 0x55555580d66d <_PyEval_Fast+2797>, 0x55555580d918 <_PyEval_Fast+3480>, 0x55555580d8ad <_PyEval_Fast+3373>, 0x55555580da5c <_PyEval_Fast+3804>, 
          0x55555580dac7 <_PyEval_Fast+3911>, 0x55555580db32 <_PyEval_Fast+4018>, 0x55555580db9d <_PyEval_Fast+4125>, 0x55555580dc08 <_PyEval_Fast+4232>, 0x55555580e125 <_PyEval_Fast+5541>, 0x55555580e181 <_PyEval_Fast+5633>, 
          0x55555580e0b6 <_PyEval_Fast+5430>, 0x55555580d4be <_PyEval_Fast+2366>, 0x55555580d453 <_PyEval_Fast+2259>, 0x55555580dc73 <_PyEval_Fast+4339>, 0x55555580d312 <_PyEval_Fast+1938>, 0x55555580d37d <_PyEval_Fast+2045>, 
          0x55555580d602 <_PyEval_Fast+2690>, 0x55555580d0b8 <_PyEval_Fast+1336>, 0x55555580d11f <_PyEval_Fast+1439>, 0x55555580d18a <_PyEval_Fast+1546>, 0x55555580e789 <_PyEval_Fast+7177>, 0x55555580d3e8 <_PyEval_Fast+2152>, 
          0x55555580d597 <_PyEval_Fast+2583>, 0x55555580d529 <_PyEval_Fast+2473>, 0x55555580e751 <_PyEval_Fast+7121>, 0x55555580ce6d <_PyEval_Fast+749>, 0x55555580f3af <_PyEval_Fast+10287>, 0x55555580cfc4 <_PyEval_Fast+1092>, 
          0x55555580cea9 <_PyEval_Fast+809>, 0x55555580d1f5 <_PyEval_Fast+1653>, 0x55555580e58e <_PyEval_Fast+6670>, 0x55555580ded0 <_PyEval_Fast+4944>, 0x55555580e3e1 <_PyEval_Fast+6241>, 0x55555580cf54 <_PyEval_Fast+980>, 
          0x55555580e6ea <_PyEval_Fast+7018>, 0x55555580e615 <_PyEval_Fast+6805>, 0x55555580e679 <_PyEval_Fast+6905>, 0x55555580e5d6 <_PyEval_Fast+6742>, 0x55555580df0a <_PyEval_Fast+5002>, 0x55555580df4e <_PyEval_Fast+5070>, 
          0x55555580dfbf <_PyEval_Fast+5183>, 0x55555580df84 <_PyEval_Fast+5124>, 0x55555580e016 <_PyEval_Fast+5270>, 0x55555580e06f <_PyEval_Fast+5359>, 0x55555580f613 <_PyEval_Fast+10899>, 0x55555580f62e <_PyEval_Fast+10926>, 
          0x55555580f5ad <_PyEval_Fast+10797>, 0x55555580f2b8 <_PyEval_Fast+10040>, 0x55555580f31d <_PyEval_Fast+10141>, 0x55555580f87c <_PyEval_Fast+11516>, 0x55555580ef19 <_PyEval_Fast+9113>, 0x55555580f6e6 <_PyEval_Fast+11110>, 
          0x55555580f720 <_PyEval_Fast+11168>, 0x55555580f3cd <_PyEval_Fast+10317>, 0x55555580f493 <_PyEval_Fast+10515>, 0x55555580f4e9 <_PyEval_Fast+10601>, 0x55555580ef4d <_PyEval_Fast+9165>, 0x55555580f3f7 <_PyEval_Fast+10359>, 
          0x55555580f452 <_PyEval_Fast+10450>, 0x55555580cc3e <_PyEval_Fast+190>, 0x55555580e7f4 <_PyEval_Fast+7284>, 0x55555580e8c3 <_PyEval_Fast+7491>, 0x55555580d6d8 <_PyEval_Fast+2904>, 0x55555580d720 <_PyEval_Fast+2976>, 
          0x55555580de90 <_PyEval_Fast+4880>, 0x55555580ea87 <_PyEval_Fast+7943>, 0x55555580eb7c <_PyEval_Fast+8188>, 0x55555580eab8 <_PyEval_Fast+7992>, 0x55555580eb46 <_PyEval_Fast+8134>, 0x55555580ec04 <_PyEval_Fast+8324>, 
          0x55555580efb0 <_PyEval_Fast+9264>, 0x55555580f01c <_PyEval_Fast+9372>, 0x55555580f069 <_PyEval_Fast+9449>, 0x55555580eedf <_PyEval_Fast+9055>, 0x55555580e853 <_PyEval_Fast+7379>, 0x55555580e91b <_PyEval_Fast+7579>, 
          0x55555580e9b1 <_PyEval_Fast+7729>, 0x55555580f16a <_PyEval_Fast+9706>, 0x55555580ea59 <_PyEval_Fast+7897>, 0x55555580ee4e <_PyEval_Fast+8910>, 0x55555580f577 <_PyEval_Fast+10743>, 0x55555580f0c8 <_PyEval_Fast+9544>, 
          0x55555580f13c <_PyEval_Fast+9660>, 0x55555580f102 <_PyEval_Fast+9602>, 0x55555580ed42 <_PyEval_Fast+8642>, 0x55555580ece9 <_PyEval_Fast+8553>, 0x55555580ed9c <_PyEval_Fast+8732>, 0x55555580edf5 <_PyEval_Fast+8821>, 
          0x55555580ec8b <_PyEval_Fast+8459>, 0x55555580ec32 <_PyEval_Fast+8370>, 0x55555580f287 <_PyEval_Fast+9991>, 0x55555580f257 <_PyEval_Fast+9943>, 0x55555580f399 <_PyEval_Fast+10265>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 11 times>, 
          0x5555558119c9 <_PyEval_Fast+20041>, 0x555555811a08 <_PyEval_Fast+20104>, 0x555555811a29 <_PyEval_Fast+20137>, 0x555555811a60 <_PyEval_Fast+20192>, 0x55555581080f <_PyEval_Fast+15503>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 13 times>, 
          0x55555581228f <_PyEval_Fast+22287>, 0x5555558122fc <_PyEval_Fast+22396>, 0x555555811f94 <_PyEval_Fast+21524>, 0x555555811f27 <_PyEval_Fast+21415>, 0x5555558123fd <_PyEval_Fast+22653>, 0x555555810700 <_PyEval_Fast+15232>, 
          0x555555810aa1 <_PyEval_Fast+16161>, 0x5555558107a2 <_PyEval_Fast+15394>, 0x555555812001 <_PyEval_Fast+21633>, 0x5555558120db <_PyEval_Fast+21851>, 0x55555581206e <_PyEval_Fast+21742>, 0x5555558121b5 <_PyEval_Fast+22069>, 
          0x555555812148 <_PyEval_Fast+21960>, 0x555555812222 <_PyEval_Fast+22178>, 0x5555558124d5 <_PyEval_Fast+22869>, 0x55555581246a <_PyEval_Fast+22762>, 0x555555811c3c <_PyEval_Fast+20668>, 0x555555810e0c <_PyEval_Fast+17036>, 
          0x555555810e79 <_PyEval_Fast+17145>, 0x5555558118d7 <_PyEval_Fast+19799>, 0x5555558125a4 <_PyEval_Fast+23076>, 0x555555812537 <_PyEval_Fast+22967>, 0x555555810cc2 <_PyEval_Fast+16706>, 0x555555810c55 <_PyEval_Fast+16597>, 
          0x555555810be8 <_PyEval_Fast+16488>, 0x555555810b7b <_PyEval_Fast+16379>, 0x555555810b0e <_PyEval_Fast+16270>, 0x555555811dda <_PyEval_Fast+21082>, 0x555555810d2f <_PyEval_Fast+16815>, 0x555555810d9c <_PyEval_Fast+16924>, 
          0x555555811aec <_PyEval_Fast+20332>, 0x555555812611 <_PyEval_Fast+23185>, 0x555555810ee6 <_PyEval_Fast+17254>, 0x5555558117d0 <_PyEval_Fast+19536>, 0x55555581062f <_PyEval_Fast+15023>, 0x555555811711 <_PyEval_Fast+19345>, 
          0x555555811982 <_PyEval_Fast+19970>, 0x55555581282e <_PyEval_Fast+23726>, 0x555555811aac <_PyEval_Fast+20268>, 0x5555558116a2 <_PyEval_Fast+19234>, 0x555555811562 <_PyEval_Fast+18914>, 0x55555581163f <_PyEval_Fast+19135>, 
          0x5555558115ca <_PyEval_Fast+19018>, 0x555555811944 <_PyEval_Fast+19908>, 0x5555558127eb <_PyEval_Fast+23659>, 0x55555581076d <_PyEval_Fast+15341>, 0x555555811d4a <_PyEval_Fast+20938>, 0x555555811da0 <_PyEval_Fast+21024>, 
          0x555555811cf2 <_PyEval_Fast+20850>, 0x555555811cac <_PyEval_Fast+20780>, 0x555555811481 <_PyEval_Fast+18689>, 0x55555581236c <_PyEval_Fast+22508>, 0x5555558114dc <_PyEval_Fast+18780>, 0x555555812787 <_PyEval_Fast+23559>, 
          0x555555812743 <_PyEval_Fast+23491>, 0x5555555b5ea2 <_PyEval_Fast.cold>...}
        pc = 0x5555558d0bcc <func_vector_call> "\t"
        opcode = <optimized out>
        acc = <optimized out>
        regs = <optimized out>
        constants = 0x763574ce9f8
        tid = <optimized out>
#6  0x00005555556a86bf in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x5555559f9460) at Python/ceval_meta.c:2788
        ret = <optimized out>
        cargs = {0x1, 0x763584903f0, 0x555555948a80 <_Py_NoneStruct>, 0x555555948a80 <_Py_NoneStruct>, 0x555555948a80 <_Py_NoneStruct>, 0x55555593c080 <_Py_FalseStruct>, 0x76356eb63d0, 0x55555593c040 <_Py_TrueStruct>, 0x1}
        prevargs = 0x7ffff37a9d08
        ret = <optimized out>
        cargs = <optimized out>
        prevargs = <optimized out>
#7  _PyFunction_Vectorcall (func=0x763575e7130, stack=0x76358420e30, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3185
        tstate = 0x5555559f9460
        nargs = 1
        nkwargs = <optimized out>
        ret = 0x0
        acc = {as_int64 = 1}
        err = 0
        extra = <optimized out>
#8  0x00007ffff739ce87 in forward_ndarray_method (self=<optimized out>, args=0x55555594b2d0 <_Py_EmptyTupleStruct+16>, kwds=0x0, forwarding_callable=0x763575e7130) at numpy/core/src/multiarray/methods.c:89
        sargs = 0x76358420e10
        ret = <optimized out>
        i = <optimized out>
        n = <optimized out>
#9  0x00005555557bdbfb in method_vectorcall_VARARGS_KEYWORDS (func=0x7635743c6d0, args=0x7ffff37a9d08, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/descrobject.c:349
        tstate = 0x5555559f9460
        nargs = 1
        argstuple = 0x55555594b2d0 <_Py_EmptyTupleStruct+16>
        result = 0x0
        kwdict = 0x0
        meth = <optimized out>
#10 0x000055555580cdc6 in _PyEval_Fast (ts=0x5555559f9460, initial_acc=..., initial_pc=0x5555558cec6f <func_vector_call> "\t") at Python/ceval.c:731
--Type <RET> for more, q to quit, c to continue without paging--
        nargs = 8123251307008
        func = <optimized out>
        nargsf = <optimized out>
        res = 0x76357823200
        frame_delta = 8123251307008
        opcode_targets_base = {0x0, 0x55555580e54c <_PyEval_Fast+6604>, 0x55555580e4f0 <_PyEval_Fast+6512>, 0x55555580e4cd <_PyEval_Fast+6477>, 0x55555580e494 <_PyEval_Fast+6420>, 0x55555580e42d <_PyEval_Fast+6317>, 
          0x55555580f525 <_PyEval_Fast+10661>, 0x55555580ddca <_PyEval_Fast+4682>, 0x5555555b5ea2 <_PyEval_Fast.cold>, 0x55555580cd0f <_PyEval_Fast+399>, 0x55555580cd02 <_PyEval_Fast+386>, 0x55555580dcde <_PyEval_Fast+4446>, 
          0x55555580fa35 <_PyEval_Fast+11957>, 0x55555580f93d <_PyEval_Fast+11709>, 0x55555580fb3a <_PyEval_Fast+12218>, 0x55555580e1ea <_PyEval_Fast+5738>, 0x55555580e243 <_PyEval_Fast+5827>, 0x55555580e2f5 <_PyEval_Fast+6005>, 
          0x55555580e350 <_PyEval_Fast+6096>, 0x55555580e29c <_PyEval_Fast+5916>, 0x55555580d9f1 <_PyEval_Fast+3697>, 0x55555580d983 <_PyEval_Fast+3587>, 0x55555580d7d7 <_PyEval_Fast+3159>, 0x55555580d842 <_PyEval_Fast+3266>, 
          0x55555580e376 <_PyEval_Fast+6134>, 0x55555580d76c <_PyEval_Fast+3052>, 0x55555580d66d <_PyEval_Fast+2797>, 0x55555580d918 <_PyEval_Fast+3480>, 0x55555580d8ad <_PyEval_Fast+3373>, 0x55555580da5c <_PyEval_Fast+3804>, 
          0x55555580dac7 <_PyEval_Fast+3911>, 0x55555580db32 <_PyEval_Fast+4018>, 0x55555580db9d <_PyEval_Fast+4125>, 0x55555580dc08 <_PyEval_Fast+4232>, 0x55555580e125 <_PyEval_Fast+5541>, 0x55555580e181 <_PyEval_Fast+5633>, 
          0x55555580e0b6 <_PyEval_Fast+5430>, 0x55555580d4be <_PyEval_Fast+2366>, 0x55555580d453 <_PyEval_Fast+2259>, 0x55555580dc73 <_PyEval_Fast+4339>, 0x55555580d312 <_PyEval_Fast+1938>, 0x55555580d37d <_PyEval_Fast+2045>, 
          0x55555580d602 <_PyEval_Fast+2690>, 0x55555580d0b8 <_PyEval_Fast+1336>, 0x55555580d11f <_PyEval_Fast+1439>, 0x55555580d18a <_PyEval_Fast+1546>, 0x55555580e789 <_PyEval_Fast+7177>, 0x55555580d3e8 <_PyEval_Fast+2152>, 
          0x55555580d597 <_PyEval_Fast+2583>, 0x55555580d529 <_PyEval_Fast+2473>, 0x55555580e751 <_PyEval_Fast+7121>, 0x55555580ce6d <_PyEval_Fast+749>, 0x55555580f3af <_PyEval_Fast+10287>, 0x55555580cfc4 <_PyEval_Fast+1092>, 
          0x55555580cea9 <_PyEval_Fast+809>, 0x55555580d1f5 <_PyEval_Fast+1653>, 0x55555580e58e <_PyEval_Fast+6670>, 0x55555580ded0 <_PyEval_Fast+4944>, 0x55555580e3e1 <_PyEval_Fast+6241>, 0x55555580cf54 <_PyEval_Fast+980>, 
          0x55555580e6ea <_PyEval_Fast+7018>, 0x55555580e615 <_PyEval_Fast+6805>, 0x55555580e679 <_PyEval_Fast+6905>, 0x55555580e5d6 <_PyEval_Fast+6742>, 0x55555580df0a <_PyEval_Fast+5002>, 0x55555580df4e <_PyEval_Fast+5070>, 
          0x55555580dfbf <_PyEval_Fast+5183>, 0x55555580df84 <_PyEval_Fast+5124>, 0x55555580e016 <_PyEval_Fast+5270>, 0x55555580e06f <_PyEval_Fast+5359>, 0x55555580f613 <_PyEval_Fast+10899>, 0x55555580f62e <_PyEval_Fast+10926>, 
          0x55555580f5ad <_PyEval_Fast+10797>, 0x55555580f2b8 <_PyEval_Fast+10040>, 0x55555580f31d <_PyEval_Fast+10141>, 0x55555580f87c <_PyEval_Fast+11516>, 0x55555580ef19 <_PyEval_Fast+9113>, 0x55555580f6e6 <_PyEval_Fast+11110>, 
          0x55555580f720 <_PyEval_Fast+11168>, 0x55555580f3cd <_PyEval_Fast+10317>, 0x55555580f493 <_PyEval_Fast+10515>, 0x55555580f4e9 <_PyEval_Fast+10601>, 0x55555580ef4d <_PyEval_Fast+9165>, 0x55555580f3f7 <_PyEval_Fast+10359>, 
          0x55555580f452 <_PyEval_Fast+10450>, 0x55555580cc3e <_PyEval_Fast+190>, 0x55555580e7f4 <_PyEval_Fast+7284>, 0x55555580e8c3 <_PyEval_Fast+7491>, 0x55555580d6d8 <_PyEval_Fast+2904>, 0x55555580d720 <_PyEval_Fast+2976>, 
          0x55555580de90 <_PyEval_Fast+4880>, 0x55555580ea87 <_PyEval_Fast+7943>, 0x55555580eb7c <_PyEval_Fast+8188>, 0x55555580eab8 <_PyEval_Fast+7992>, 0x55555580eb46 <_PyEval_Fast+8134>, 0x55555580ec04 <_PyEval_Fast+8324>, 
          0x55555580efb0 <_PyEval_Fast+9264>, 0x55555580f01c <_PyEval_Fast+9372>, 0x55555580f069 <_PyEval_Fast+9449>, 0x55555580eedf <_PyEval_Fast+9055>, 0x55555580e853 <_PyEval_Fast+7379>, 0x55555580e91b <_PyEval_Fast+7579>, 
          0x55555580e9b1 <_PyEval_Fast+7729>, 0x55555580f16a <_PyEval_Fast+9706>, 0x55555580ea59 <_PyEval_Fast+7897>, 0x55555580ee4e <_PyEval_Fast+8910>, 0x55555580f577 <_PyEval_Fast+10743>, 0x55555580f0c8 <_PyEval_Fast+9544>, 
          0x55555580f13c <_PyEval_Fast+9660>, 0x55555580f102 <_PyEval_Fast+9602>, 0x55555580ed42 <_PyEval_Fast+8642>, 0x55555580ece9 <_PyEval_Fast+8553>, 0x55555580ed9c <_PyEval_Fast+8732>, 0x55555580edf5 <_PyEval_Fast+8821>, 
          0x55555580ec8b <_PyEval_Fast+8459>, 0x55555580ec32 <_PyEval_Fast+8370>, 0x55555580f287 <_PyEval_Fast+9991>, 0x55555580f257 <_PyEval_Fast+9943>, 0x55555580f399 <_PyEval_Fast+10265>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 11 times>, 
          0x5555558119c9 <_PyEval_Fast+20041>, 0x555555811a08 <_PyEval_Fast+20104>, 0x555555811a29 <_PyEval_Fast+20137>, 0x555555811a60 <_PyEval_Fast+20192>, 0x55555581080f <_PyEval_Fast+15503>, 0x5555555b5ea2 <_PyEval_Fast.cold> <repeats 13 times>, 
          0x55555581228f <_PyEval_Fast+22287>, 0x5555558122fc <_PyEval_Fast+22396>, 0x555555811f94 <_PyEval_Fast+21524>, 0x555555811f27 <_PyEval_Fast+21415>, 0x5555558123fd <_PyEval_Fast+22653>, 0x555555810700 <_PyEval_Fast+15232>, 
          0x555555810aa1 <_PyEval_Fast+16161>, 0x5555558107a2 <_PyEval_Fast+15394>, 0x555555812001 <_PyEval_Fast+21633>, 0x5555558120db <_PyEval_Fast+21851>, 0x55555581206e <_PyEval_Fast+21742>, 0x5555558121b5 <_PyEval_Fast+22069>, 
          0x555555812148 <_PyEval_Fast+21960>, 0x555555812222 <_PyEval_Fast+22178>, 0x5555558124d5 <_PyEval_Fast+22869>, 0x55555581246a <_PyEval_Fast+22762>, 0x555555811c3c <_PyEval_Fast+20668>, 0x555555810e0c <_PyEval_Fast+17036>, 
          0x555555810e79 <_PyEval_Fast+17145>, 0x5555558118d7 <_PyEval_Fast+19799>, 0x5555558125a4 <_PyEval_Fast+23076>, 0x555555812537 <_PyEval_Fast+22967>, 0x555555810cc2 <_PyEval_Fast+16706>, 0x555555810c55 <_PyEval_Fast+16597>, 
          0x555555810be8 <_PyEval_Fast+16488>, 0x555555810b7b <_PyEval_Fast+16379>, 0x555555810b0e <_PyEval_Fast+16270>, 0x555555811dda <_PyEval_Fast+21082>, 0x555555810d2f <_PyEval_Fast+16815>, 0x555555810d9c <_PyEval_Fast+16924>, 
          0x555555811aec <_PyEval_Fast+20332>, 0x555555812611 <_PyEval_Fast+23185>, 0x555555810ee6 <_PyEval_Fast+17254>, 0x5555558117d0 <_PyEval_Fast+19536>, 0x55555581062f <_PyEval_Fast+15023>, 0x555555811711 <_PyEval_Fast+19345>, 
          0x555555811982 <_PyEval_Fast+19970>, 0x55555581282e <_PyEval_Fast+23726>, 0x555555811aac <_PyEval_Fast+20268>, 0x5555558116a2 <_PyEval_Fast+19234>, 0x555555811562 <_PyEval_Fast+18914>, 0x55555581163f <_PyEval_Fast+19135>, 
          0x5555558115ca <_PyEval_Fast+19018>, 0x555555811944 <_PyEval_Fast+19908>, 0x5555558127eb <_PyEval_Fast+23659>, 0x55555581076d <_PyEval_Fast+15341>, 0x555555811d4a <_PyEval_Fast+20938>, 0x555555811da0 <_PyEval_Fast+21024>, 
          0x555555811cf2 <_PyEval_Fast+20850>, 0x555555811cac <_PyEval_Fast+20780>, 0x555555811481 <_PyEval_Fast+18689>, 0x55555581236c <_PyEval_Fast+22508>, 0x5555558114dc <_PyEval_Fast+18780>, 0x555555812787 <_PyEval_Fast+23559>, 
          0x555555812743 <_PyEval_Fast+23491>, 0x5555555b5ea2 <_PyEval_Fast.cold>...}
        pc = 0x5555558cec6f <func_vector_call> "\t"
        opcode = <optimized out>
        acc = <optimized out>
        regs = <optimized out>
        constants = 0x76356ea2b40
        tid = <optimized out>
#11 0x00005555556a86bf in _PyEval_Eval (pc=<optimized out>, acc=..., tstate=0x5555559f9460) at Python/ceval_meta.c:2788
        ret = <optimized out>
        cargs = {0x0, 0x763584903f0, 0x55555593c080 <_Py_FalseStruct>, 0x7ffff2fa9ac0, 0x7ffff2fa9b60, 0x4, 0x2, 0x3200000008, 0x0}
        prevargs = 0x0
        ret = <optimized out>
        cargs = <optimized out>
        prevargs = <optimized out>
#12 _PyFunction_Vectorcall (func=0x76356df0470, stack=0x7ffff37a9da8, nargsf=<optimized out>, kwnames=<optimized out>) at Python/ceval_meta.c:3185
        tstate = 0x5555559f9460
        nargs = 1
        nkwargs = <optimized out>
        ret = 0x0
        acc = {as_int64 = 1}
        err = 0
        extra = <optimized out>
#13 0x00005555557b3ab4 in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=1, args=0x7ffff37a9da8, callable=0x76356df0470, tstate=0x5555559f9460) at ./Include/cpython/abstract.h:118
        func = <optimized out>
        res = <optimized out>
        nargs = <optimized out>
#14 method_vectorcall (method=<optimized out>, args=0x55555594b2f0 <_Py_EmptyTupleStruct+48>, nargsf=<optimized out>, kwnames=0x0) at Objects/classobject.c:62
        nkwargs = <optimized out>
        totalargs = <optimized out>
        newargs_stack = {0x7fffffffd35f, 0x5555559f9460, 0x5555559f9460, 0xc93ca52021d5b00, 0x55555599bc60 <_PyRuntime+640>}
        newargs = <optimized out>
        tstate = 0x5555559f9460
        self = 0x763568f8e90
        func = 0x76356df0470
        nargs = 0
        result = <optimized out>
#15 0x0000555555771a41 in t_bootstrap (boot_raw=0x7635795ba30) at ./Modules/_threadmodule.c:1289
        boot = 0x7635795ba30
        tstate = 0x5555559f9460
        res = <optimized out>
--Type <RET> for more, q to quit, c to continue without paging--
#16 0x00005555557064bb in pythread_wrapper (arg=<optimized out>) at Python/thread_pthread.h:245
        callback = <optimized out>
        func = 0x5555557719f0 <t_bootstrap>
        func_arg = 0x7635795ba30
#17 0x00007ffff7d38947 in start_thread (arg=<optimized out>) at pthread_create.c:435
        ret = <optimized out>
        pd = <optimized out>
        out = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140737278289472, -7107990009691300924, 140737488343902, 140737488343903, 0, 140737269899264, 7108015344611171268, 7108007434102184900}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, 
            data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
#18 0x00007ffff7dc8a44 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100

which is a call to NPY_AUXDATA_FREE(auxdata);

Note that, from time to time, I also observe the following exception before a deadlock:

Traceback (most recent call last):
  File "/home/ogrisel/code/nogil/Lib/threading.py", line 935, in _bootstrap_inner
    self.run()
  File "/home/ogrisel/code/nogil/Lib/threading.py", line 886, in run
    self._target(*self._args, **self._kwargs)
  File "/home/ogrisel/threaded_numpy.py", line 15, in worker
    f(item)
  File "/home/ogrisel/threaded_numpy.py", line 7, in f
    return a.max()
  File "/home/ogrisel/nogil-venv/lib/python3.9/site-packages/numpy/core/_methods.py", line 40, in _amax
    return umr_maximum(a, axis, None, out, keepdims, initial, where)
RuntimeError: Identity cache already includes the item.

Can I translate Google Doc in Korean?

I'm student loving and leaning Python and I could know your project by python newsletters.

Can I translate your Google Doc in Korean and share to others for a personal purpose?

Building lxml from source

Hi, thanks for a super promising project!

To test some stuff, I'd like to build lxml from source, as I understand it required some fixes, would you mind releasing the patched lxml source? For reference, the first error when building lxml from PyPI is

gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DCYTHON_CLINE_IN_TRACEBACK=0 -I/usr/include/libxml2 -Isrc -Isrc/lxml/includes -I/some/path/nogil/include -I/usr/local/include/python3.9 -c src/lxml/etree.c -o build/temp.linux-x86_64-3.9/src/lxml/etree.o -w
src/lxml/etree.c: In function ‘__pyx_tp_dealloc_4lxml_5etree__LogEntry’:
src/lxml/etree.c:221006:5: error: lvalue required as increment operand
    ++Py_REFCNT(o); 
    ^~

Installing on Apple silicon

I’m having trouble installing on M1 iMac, but it seems it’s not possible while config.sub is outdated. Do you have any plan to support Apple Silicon?

[history] when I tried this in 1996

Hey Sam! ... Good luck with this project. Looks great!

I removed the GIL back in 1996 from Python 1.4, primarily to create a re-entrant Python interpreter. We had embedded Python within IIS as the basis for Microsoft Merchant Server. in 2011, Dave Beazley provided a fantastic writeup/analysis of the patches that I developed. Please see it here:
http://dabeaz.blogspot.com/2011/08/inside-look-at-gil-removal-patch-of.html

Guido referenced my project in 2007, with a blog post here:
https://www.artima.com/weblogs/viewpost.jsp?thread=214235

Including a link to my short 2001 email about the performance that we observed.

My patchset was in use for only one, maybe two, product releases, so there was no impetus to maintain the patches or solve some of its problems.

The one thing that I'm most proud about, based those patches, is that Python grew the PyThreadState structure, and per-thread exception handling.

It looks like you're doing some great stuff, and I'll be following along. I don't think the above will be helpful for your project, but I do hope it will put a smile on your face, with its historical interest.

Failed to build greenlet package

Hunting around for packages which might overlap with the nogil threading changes, I settled first on greenlet. verified that it would build using 3.9.7 from Anaconda. Then I tried with nogil-3.9. It failed with what appear to be an error related to the nogil changes (‘_Py_RefTotal’ undeclared). pip install output below.

Script started on 2021-10-22 06:20:34-05:00 [TERM="xterm-256color" TTY="/dev/pts/2" COLUMNS="143" LINES="45"]
(base) nogil% ./python -m pip install greenlet --no-binary :all:
WARNING: Value for scheme.headers does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
distutils: /usr/local/include/python3.9d/UNKNOWN
sysconfig: /home/skip/src/python/nogil/Include/UNKNOWN
WARNING: Additional context:
user = False
home = None
root = None
prefix = None
Defaulting to user installation because normal site-packages is not writeable
Collecting greenlet
  Using cached greenlet-1.1.2.tar.gz (91 kB)
Skipping wheel build for greenlet, due to binaries being disabled for it.
Installing collected packages: greenlet
  WARNING: Value for scheme.headers does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
  distutils: /home/skip/.local/include/python3.9d/greenlet
  sysconfig: /home/skip/.local/include/python3.9/greenlet
  WARNING: Additional context:
  user = True
  home = None
  root = None
  prefix = None
    Running setup.py install for greenlet ... error
    ERROR: Command errored out with exit status 1:
     command: /home/skip/src/python/nogil/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-pn_majd7/greenlet_ff05a49f62b74e0dbdc3c52609b47610/setup.py'"'"'; __file__='"'"'/tmp/pip-install-pn_majd7/greenlet_ff05a49f62b74e0dbdc3c52609b47610/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-djeew82b/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /home/skip/.local/include/python3.9d/greenlet
         cwd: /tmp/pip-install-pn_majd7/greenlet_ff05a49f62b74e0dbdc3c52609b47610/
    Complete output (91 lines):
    running install
    running build
    running build_py
    /home/skip/.local/lib/python3.9/site-packages/setuptools/lib2to3_ex.py:10: PendingDeprecationWarning: lib2to3 package is deprecated and may not be able to parse Python 3.10+
      from lib2to3.refactor import RefactoringTool, get_fixers_from_package
    creating build
    creating build/lib.linux-x86_64-3.9-pydebug
    creating build/lib.linux-x86_64-3.9-pydebug/greenlet
    copying src/greenlet/__init__.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet
    creating build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_tracing.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_contextvars.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_leaks.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_weakref.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_version.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_extension_interface.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_stack_saved.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_throw.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_greenlet.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_generator.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_gc.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/__init__.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_generator_nested.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/test_cpp.py -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    running egg_info
    writing src/greenlet.egg-info/PKG-INFO
    writing dependency_links to src/greenlet.egg-info/dependency_links.txt
    writing requirements to src/greenlet.egg-info/requires.txt
    writing top-level names to src/greenlet.egg-info/top_level.txt
    reading manifest file 'src/greenlet.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    no previously-included directories found matching 'docs/_build'
    warning: no files found matching '*.py' under directory 'appveyor'
    warning: no previously-included files matching '*.pyc' found anywhere in distribution
    warning: no previously-included files matching '*.pyd' found anywhere in distribution
    warning: no previously-included files matching '*.so' found anywhere in distribution
    warning: no previously-included files matching '.coverage' found anywhere in distribution
    adding license file 'LICENSE'
    adding license file 'LICENSE.PSF'
    adding license file 'AUTHORS'
    writing manifest file 'src/greenlet.egg-info/SOURCES.txt'
    copying src/greenlet/greenlet.c -> build/lib.linux-x86_64-3.9-pydebug/greenlet
    copying src/greenlet/greenlet.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet
    copying src/greenlet/slp_platformselect.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet
    creating build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/setup_switch_x64_masm.cmd -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_aarch64_gcc.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_alpha_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_amd64_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_arm32_gcc.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_arm32_ios.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_csky_gcc.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_m68k_gcc.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_mips_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_ppc64_aix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_ppc64_linux.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_ppc_aix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_ppc_linux.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_ppc_macosx.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_ppc_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_riscv_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_s390_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_sparc_sun_gcc.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_x32_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_x64_masm.asm -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_x64_masm.obj -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_x64_msvc.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_x86_msvc.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/platform/switch_x86_unix.h -> build/lib.linux-x86_64-3.9-pydebug/greenlet/platform
    copying src/greenlet/tests/_test_extension.c -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    copying src/greenlet/tests/_test_extension_cpp.cpp -> build/lib.linux-x86_64-3.9-pydebug/greenlet/tests
    running build_ext
    building 'greenlet._greenlet' extension
    creating build/temp.linux-x86_64-3.9-pydebug
    creating build/temp.linux-x86_64-3.9-pydebug/src
    creating build/temp.linux-x86_64-3.9-pydebug/src/greenlet
    gcc -pthread -Wno-unused-result -Wsign-compare -O0 -g3 -Wall -fPIC -I/home/skip/src/python/nogil/Include -I/home/skip/src/python/nogil -c src/greenlet/greenlet.c -o build/temp.linux-x86_64-3.9-pydebug/src/greenlet/greenlet.o
    src/greenlet/greenlet.c: In function ‘green_dealloc’:
    src/greenlet/greenlet.c:123:34: error: ‘_Py_RefTotal’ undeclared (first use in this function); did you mean ‘_Py_GetRefTotal’?
      123 | #        define _Py_DEC_REFTOTAL _Py_RefTotal--
          |                                  ^~~~~~~~~~~~
    src/greenlet/greenlet.c:1239:13: note: in expansion of macro ‘_Py_DEC_REFTOTAL’
     1239 |             _Py_DEC_REFTOTAL;
          |             ^~~~~~~~~~~~~~~~
    src/greenlet/greenlet.c:123:34: note: each undeclared identifier is reported only once for each function it appears in
      123 | #        define _Py_DEC_REFTOTAL _Py_RefTotal--
          |                                  ^~~~~~~~~~~~
    src/greenlet/greenlet.c:1239:13: note: in expansion of macro ‘_Py_DEC_REFTOTAL’
     1239 |             _Py_DEC_REFTOTAL;
          |             ^~~~~~~~~~~~~~~~
    error: command '/usr/bin/gcc' failed with exit code 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /home/skip/src/python/nogil/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-pn_majd7/greenlet_ff05a49f62b74e0dbdc3c52609b47610/setup.py'"'"'; __file__='"'"'/tmp/pip-install-pn_majd7/greenlet_ff05a49f62b74e0dbdc3c52609b47610/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-djeew82b/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /home/skip/.local/include/python3.9d/greenlet Check the logs for full command output.

Crash with pydantic in nogil mode

Reported by @fengyang95

Modules/gcmodule.c:2674

# -*- coding: utf-8 -*-
from concurrent import futures
import logging
from typing import Dict, Any
from pydantic import BaseModel


class EntitySmall(BaseModel):
    name: str
    value: int


def func(data_dict: Dict[str, Any]) -> Dict[str, Any]:
    entity = EntitySmall(**data_dict)
    new_data_dict = entity.dict()
    return new_data_dict


test_datas = [
    {"name": f"name{i}", "value": i} for i in range(1000)
]

if __name__ == "__main__":
    to_do_map = {}
    with futures.ThreadPoolExecutor(max_workers=20) as THREAD_POOL:
        for i, data in enumerate(test_datas):
            future = THREAD_POOL.submit(func, data)
            to_do_map[future] = i
        done_iter = futures.as_completed(to_do_map, timeout=100)
        for future in done_iter:
            logging.error(f"future:{to_do_map[future]}")
            logging.error(future.result())

numpy.array crash in thread

Executing np.array in threaded function and the program crash.
Versions:
nogil : default branch from https://github.com/colesbury/nogil.git
numpy: v1.22.0-nogil from https://github.com/colesbury/numpy.git

Test program:

import sys
import numpy as np
from concurrent.futures import ThreadPoolExecutor


print(f"nogil={getattr(sys.flags, 'nogil', False)}")

def fib(n):
    b = np.array(((4,4,4,4),(4,4,4,4),(4,4,4,4),(4,4,4,4)), dtype=np.float64)
    if n < 2: return 1
    return fib(n-1) + fib(n-2)

threads = 8
if len(sys.argv) > 1:
    threads = int(sys.argv[1])

with ThreadPoolExecutor(max_workers=threads) as executor:
    for _ in range(threads):

     executor.submit(lambda: print(fib(18)))



Fatal error python

Hi yesterday i compile nogil python version and i found an unexpected behavior.

On startup my application prints

gc_get_refs(gc): -1
gc_get_refs(gc): -1
gc_get_refs(gc): -1
gc_get_refs(gc): -1
gc_get_refs(gc): -1
Process started (my app output)
gc_get_refs(gc): -1
gc_get_refs(gc): -1

and then after some minutes my app crashed with error:

Fatal Python error: _Py_queue_object: _Py_queue_object called with unowned object
Python runtime state: initialized

Numpy will need updating

Numpy references the ob_refcnt field. Will need some tweaks to compile. script(1) session attached. Relevant error message:

  gcc: numpy/core/src/multiarray/multiarraymodule.c
  In file included from numpy/core/include/numpy/arrayobject.h:4,
                   from numpy/core/src/multiarray/shape.c:7:
  numpy/core/src/multiarray/shape.c: In function ‘PyArray_Resize’:
  numpy/core/include/numpy/ndarrayobject.h:102:51: error: ‘PyObject’ {aka ‘struct _object’} has no member named ‘ob_refcnt’
    102 | #define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
        |                                                   ^~
  numpy/core/src/multiarray/shape.c:107:22: note: in expansion of macro ‘PyArray_REFCOUNT’
    107 |             refcnt = PyArray_REFCOUNT(self);
        |                      ^~~~~~~~~~~~~~~~

typescript.txt

Can not import pydantic with latest docker image

I get an error when trying to import pydantic using the latest image.

pip.log

root@f597b6f2e89e:~# python3
Python 3.9.0a4+ (default, Oct 17 2021, 19:16:30)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pydantic import BaseModel
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pydantic/__init__.py", line 2, in init pydantic.__init__
  File "pydantic/dataclasses.py", line 7, in init pydantic.dataclasses
    import builtins
  File "pydantic/main.py", line 376, in init pydantic.main
  File "pydantic/main.py", line 369, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/utils.py", line 205, in pydantic.utils.generate_model_signature
  File "/usr/local/lib/python3.9/inspect.py", line 3076, in signature
    return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
  File "/usr/local/lib/python3.9/inspect.py", line 2825, in from_callable
    return _signature_from_callable(obj, sigcls=cls,
  File "/usr/local/lib/python3.9/inspect.py", line 2280, in _signature_from_callable
    return _signature_from_builtin(sigcls, obj,
  File "/usr/local/lib/python3.9/inspect.py", line 2091, in _signature_from_builtin
    raise ValueError("no signature found for builtin {!r}".format(func))
ValueError: no signature found for builtin <cyfunction BaseModel.__init__ at 0x58f257d9bd0>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.