Has this happened in time for b1?
Yep, all of these build options (and the environment variable) are available on the tagged release: gh-118335: Configure Tier 2 interpreter at build time by gvanrossum · Pull Request #118339 · python/cpython (github.com)
This is as far as I got in the Fedora package by adding --enable-experimental-jit=yes-off
:
...
python3.13 /builddir/build/BUILD/Python-3.13.0b1/Tools/jit/build.py x86_64-redhat-linux-gnu --debug
==============================================================
JIT support for x86_64-redhat-linux-gnu is still experimental!
Please report any issues you encounter.
==============================================================
python3.13 /builddir/build/BUILD/Python-3.13.0b1/Tools/jit/build.py x86_64-redhat-linux-gnu --debug
==============================================================
JIT support for x86_64-redhat-linux-gnu is still experimental!
Please report any issues you encounter.
==============================================================
gcc -c -fno-strict-overflow -Wsign-compare -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -DDYNAMIC_ANNOTATIONS_ENABLED=1 -fexceptions -fcf-protection -fexceptions -fcf-protection -fexceptions -fcf-protection -O0 -Wno-cpp -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -D_GNU_SOURCE -fPIC -fwrapv -D_Py_TIER2=3 -D_Py_JIT -flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -g -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -fvisibility=hidden -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -D_GNU_SOURCE -fPIC -fwrapv -O0 -Wno-cpp -I/builddir/build/BUILD/Python-3.13.0b1/Include/internal -I/builddir/build/BUILD/Python-3.13.0b1/Include/internal/mimalloc -IObjects -IInclude -IPython -I. -I/builddir/build/BUILD/Python-3.13.0b1/Include -fPIC -DPy_BUILD_CORE -o Python/jit.o /builddir/build/BUILD/Python-3.13.0b1/Python/jit.c
In file included from /builddir/build/BUILD/Python-3.13.0b1/Python/jit.c:392:
./jit_stencils.h: In function ‘emit__DELETE_DEREF’:
./jit_stencils.h:15433:39: error: ‘_PyCriticalSection_BeginSlow’ undeclared (first use in this function)
15433 | patch_64(data + 0xf0, (uintptr_t)&_PyCriticalSection_BeginSlow);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./jit_stencils.h:15433:39: note: each undeclared identifier is reported only once for each function it appears in
./jit_stencils.h:15435:40: error: ‘_PyCriticalSection_Resume’ undeclared (first use in this function)
15435 | patch_64(data + 0x100, (uintptr_t)&_PyCriticalSection_Resume);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
./jit_stencils.h: In function ‘emit__LOAD_DEREF’:
./jit_stencils.h:29402:39: error: ‘_PyCriticalSection_BeginSlow’ undeclared (first use in this function)
29402 | patch_64(data + 0xb0, (uintptr_t)&_PyCriticalSection_BeginSlow);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./jit_stencils.h:29405:39: error: ‘_PyCriticalSection_Resume’ undeclared (first use in this function)
29405 | patch_64(data + 0xc8, (uintptr_t)&_PyCriticalSection_Resume);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
./jit_stencils.h: In function ‘emit__LOAD_FROM_DICT_OR_DEREF’:
./jit_stencils.h:31160:40: error: ‘_PyCriticalSection_BeginSlow’ undeclared (first use in this function)
31160 | patch_64(data + 0x1d8, (uintptr_t)&_PyCriticalSection_BeginSlow);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./jit_stencils.h:31163:40: error: ‘_PyCriticalSection_Resume’ undeclared (first use in this function)
31163 | patch_64(data + 0x1f0, (uintptr_t)&_PyCriticalSection_Resume);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
./jit_stencils.h: In function ‘emit__STORE_DEREF’:
./jit_stencils.h:38406:39: error: ‘_PyCriticalSection_BeginSlow’ undeclared (first use in this function)
./jit_stencils.h:38408:39: error: ‘_PyCriticalSection_Resume’ undeclared (first use in this function)
make: *** [Makefile:3018: Python/jit.o] Error 1
It looks like you’re trying to build with --disable-gil
too, which is something we hadn’t really tested yet. That issue is being tracked here.
Does the build succeed on normal, non-free-threaded builds?
When I only pass --enable-experimental-jit=yes-off
to the non-free-threaded builds, I get:
python3.13 /builddir/build/BUILD/Python-3.13.0b1/Tools/jit/build.py x86_64-redhat-linux-gnu --debug
==============================================================
JIT support for x86_64-redhat-linux-gnu is still experimental!
Please report any issues you encounter.
==============================================================
python3.13 /builddir/build/BUILD/Python-3.13.0b1/Tools/jit/build.py x86_64-redhat-linux-gnu --debug
==============================================================
JIT support for x86_64-redhat-linux-gnu is still experimental!
Please report any issues you encounter.
==============================================================
gcc -c -fno-strict-overflow -Wsign-compare -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -DDYNAMIC_ANNOTATIONS_ENABLED=1 -fcf-protection -fexceptions -fcf-protection -fexceptions -fcf-protection -fexceptions -O0 -Wno-cpp -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -D_GNU_SOURCE -fPIC -fwrapv -D_Py_TIER2=3 -D_Py_JIT -flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -g -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -fvisibility=hidden -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -D_GNU_SOURCE -fPIC -fwrapv -O0 -Wno-cpp -I/builddir/build/BUILD/Python-3.13.0b1/Include/internal -I/builddir/build/BUILD/Python-3.13.0b1/Include/internal/mimalloc -IObjects -IInclude -IPython -I. -I/builddir/build/BUILD/Python-3.13.0b1/Include -fPIC -DPy_BUILD_CORE -o Python/jit.o /builddir/build/BUILD/Python-3.13.0b1/Python/jit.c
/builddir/build/BUILD/Python-3.13.0b1/Python/jit.c: In function ‘emit__MATCH_MAPPING’:
/builddir/build/BUILD/Python-3.13.0b1/Python/jit.c:395:1: error: expected expression before ‘int’
395 | int
| ^~~
/builddir/build/BUILD/Python-3.13.0b1/Python/jit.c:479:1: error: expected declaration or statement at end of input
479 | }
| ^
In file included from /builddir/build/BUILD/Python-3.13.0b1/Python/jit.c:392:
./jit_stencils.h:30254:25: warning: unused variable ‘data_body’ [-Wunused-variable]
30254 | const unsigned char data_body[24] = {
| ^~~~~~~~~
./jit_stencils.h:30241:25: warning: unused variable ‘code_body’ [-Wunused-variable]
30241 | const unsigned char code_body[53] = {
| ^~~~~~~~~
/builddir/build/BUILD/Python-3.13.0b1/Python/jit.c: At top level:
/builddir/build/BUILD/Python-3.13.0b1/Python/jit.c:87:1: warning: ‘mark_executable’ defined but not used [-Wunused-function]
87 | mark_executable(unsigned char *memory, size_t size)
| ^~~~~~~~~~~~~~~
/builddir/build/BUILD/Python-3.13.0b1/Python/jit.c:70:1: warning: ‘jit_free’ defined but not used [-Wunused-function]
70 | jit_free(unsigned char *memory, size_t size)
| ^~~~~~~~
/builddir/build/BUILD/Python-3.13.0b1/Python/jit.c:49:1: warning: ‘jit_alloc’ defined but not used [-Wunused-function]
49 | jit_alloc(size_t size)
| ^~~~~~~~~
make: *** [Makefile:3018: Python/jit.o] Error 1
Hm, odd. Do you mind opening an issue, and tagging me? I’m also curious if there is some sort of invalid syntax in the generated jit_stencils.h
file around the definition of emit__MATCH_MAPPING
.
I’m also noticing now that the command-line to generate the JIT (and warning banner) are printed twice. That should only be running once per build, so I wonder if it’s a copy-paste error in your post, or if several builds are happening at once for some reason. If so, they could be stepping on each other and maybe truncating the generated file.
I can attach a full log for inspection when I open the issue.
Hello again. Possibly a silly question: What is the best way to verify the JIT is there? Calling a function several times and looking at the bytecode? Or is there some sys
etc. attribute I can observe?
Great question. Honestly, the JIT may be a bit too transparent right now, so there aren’t really any great APIs for this yet.
If you want to know if a configure
-based build enabled the JIT, you can use "_Py_JIT" in sysconfig.get_config_var("PY_CORE_CFLAGS")
.
If you want to know if a specific function contains jitted code, this is currently what we do in internal tests:
import _opcode
import types
def is_jitted(f: types.FunctionType) -> bool:
for i in range(0, len(f.__code__.co_code), 2):
try:
_opcode.get_executor(f.__code__, i)
except RuntimeError:
# This isn't a JIT build:
return False
except ValueError:
# No executor found:
continue
return True
return False
Here’s an example:
>>> def fibonacci(n):
... a, b = 0, 1
... for _ in range(n):
... a, b = b, a + b
... return a
...
>>> is_jitted(fibonacci)
False
>>> fibonacci(100)
354224848179261915075
>>> is_jitted(fibonacci)
True
This should help if you’re just curious, but if you’d like more robust/efficient APIs in sys
or dis
, then please open an issue letting us know what sort of functionality would be most useful to you!
Thanks. I just needed to verify if my changes to the Fedora package actually work as intended (JIT disabled by default, enabled with the environment variable).
I can use the example provided for a manual test.
A higher-level function/check might be easier for a smoke CI test, but it’s not required for Fedora.
In light of the discussion, we’re going to work on updating/revising the PEP.
While I start to compile the themes raised here, I also wanted to check in and see if there were any additional or new points that folks would like to see clarified that were not already mentioned.
24 posts were split to a new topic: JIT performance possibilities
This topic is temporarily closed for at least 4 hours due to a large number of community flags.
This topic was automatically opened after 12 hours.