Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add support for freethreaded builds of Python 3.13 #326

Merged
merged 10 commits into from
Sep 26, 2024
Merged

Add support for freethreaded builds of Python 3.13 #326

merged 10 commits into from
Sep 26, 2024

Conversation

zanieb
Copy link
Member

@zanieb zanieb commented Sep 9, 2024

Closes #320

There are a couple important notes here:

  • We exceeded the GitHub matrix size limit in the Linux build so the 3.13 jobs were split out into a separate matrix.
  • There is no support for freethreaded musl builds because freethreading requires mimalloc which requires stdatomic which is not available in the much older LLVM we are using there. I am working on upgrading those to LLVM 18 separately.

optimizations: 'debug'
options: 'debug'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially I added a separate freethreaded: true flag but defining all the build options at once makes passing them around much easier.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should be variant? Or flavor, as they're called in the docs? Don't feel strongly.

Copy link
Member Author

@zanieb zanieb Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the documentation, this isn't the "flavor" it's the "build configuration". The "flavors" are install_only / full. These are options to configure the build.

Instead of --options and build_options we could do --config and build_config but I don't think that's clearer.

Comment on lines 359 to 361
if [ -n "${CPYTHON_FREETHREADED}" ]; then
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --disable-gil"
fi
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the "key" change.

@zanieb

This comment was marked as outdated.

@zanieb
Copy link
Member Author

zanieb commented Sep 26, 2024

Notes on failures

Resolved issues

build-313 (x86_64_v4-unknown-linux-musl, cpython-3.13, lto)
build-313 (x86_64_v3-unknown-linux-musl, cpython-3.13, lto, true)
build (x86_64_v4-unknown-linux-musl, cpython-3.9, lto)

cpython-3.13> /tools/host/bin/ld: warning: libcrypto-lib-x86_64-gf2m.o: missing .note.GNU-stack section implies executable stack
cpython-3.13> /tools/host/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
cpython-3.13> /tools/host/bin/ld: warning: libcrypto-lib-x86_64-gf2m.o: missing .note.GNU-stack section implies executable stack
cpython-3.13> /tools/host/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
cpython-3.13> /tools/host/bin/ld: /tools/llvm/lib/clang/14.0.3/lib/linux/libclang_rt.profile-x86_64.a(InstrProfilingFile.c.o): in function `parseAndSetFilename':
cpython-3.13> InstrProfilingFile.c:(.text.parseAndSetFilename+0xf9): undefined reference to `__strdup'
cpython-3.13> clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
cpython-3.13> make[2]: *** [Programs/_testembed] Error 1
cpython-3.13> Makefile:1531: recipe for target 'Programs/_testembed' failed
cpython-3.13> make[2]: *** Waiting for unfinished jobs....
cpython-3.13> /tools/host/bin/ld: /tools/llvm/lib/clang/14.0.3/lib/linux/libclang_rt.profile-x86_64.a(InstrProfilingFile.c.o): in function `parseAndSetFilename':
cpython-3.13> InstrProfilingFile.c:(.text.parseAndSetFilename+0xf9): undefined reference to `__strdup'
cpython-3.13> clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

build-313 (x86_64_v4-unknown-linux-gnu, cpython-3.13, freethreaded+lto)

cpython-3.13> # Next, run the profile task to generate the profile information.
cpython-3.13> LLVM_PROFILE_FILE="/build/Python-3.13.0rc2/code-%p.profclangr" LD_LIBRARY_PATH=/build/Python-3.13.0rc2 ./python -m test --pgo --timeout=
cpython-3.13> Illegal instruction (core dumped)
cpython-3.13> Makefile:845: recipe for target 'profile-run-stamp' failed

build-313 (ppc64le-unknown-linux-gnu, cpython-3.13, freethreaded+lto)
build-313 (aarch64-unknown-linux-gnu, cpython-3.13, freethreaded+lto)

cpython-3.13> # Next, run the profile task to generate the profile information.
cpython-3.13> LD_LIBRARY_PATH=/build/Python-3.13.0rc2 ./python -m test --pgo --timeout=
cpython-3.13> /bin/sh: 1: ./python: Exec format error
cpython-3.13> Makefile:845: recipe for target 'profile-run-stamp' failed

All the LTO failures are addressed by 0a53b06 which was a mistake in the options refactor.

build-313 (x86_64_v4-unknown-linux-musl, cpython-3.13, freethreaded+debug
build-313 (x86_64_v4-unknown-linux-musl, cpython-3.13, freethreaded+noopt)
build-313 (x86_64_v2-unknown-linux-musl, cpython-3.13, freethreaded+lto, true)
build-313 (x86_64-unknown-linux-musl, cpython-3.13, freethreaded+debug, true)

cpython-3.13> checking for builtin __atomic_load_n and __atomic_store_n functions...
cpython-3.13> yes
cpython-3.13> checking for --with-mimalloc...
cpython-3.13> configure: error: mimalloc requires stdatomic.h, use --without-mimalloc to disable mimalloc.

The musl builds are still on LLVM 14 which doesn't have C11 support as far as I can tell — we need to upgrade it to unblock. However, this is relatively low-priority since the musl builds are generally unusable (they don't allow loading Python extension modules).

I disabled them in a01c634

@zanieb zanieb marked this pull request as ready for review September 26, 2024 12:04
Comment on lines +502 to 511
if [ -n "${CPYTHON_FREETHREADED}" ]; then
PYTHON_BINARY_SUFFIX=t
PYTHON_LIB_SUFFIX=t
else
PYTHON_BINARY_SUFFIX=
PYTHON_LIB_SUFFIX=
fi
if [ -n "${CPYTHON_DEBUG}" ]; then
PYTHON_BINARY_SUFFIX="${PYTHON_BINARY_SUFFIX}d"
fi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should do flag in lexicographic order, at least i remember them being in this order, even if the PEP doesn't talk about order. I tried to to look in cpython but didn't find anything about order either.

Copy link
Member

@konstin konstin Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh sys.abiflags say td too

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ordering matches the order that is produced by CPython; we're not choosing the order, we're just constructing these variables to pull artifacts from the builds.

"--optimizations",
choices={"debug", "noopt", "pgo", "lto", "pgo+lto"},
"--options",
choices=optimizations.union({f"freethreaded+{o}" for o in optimizations}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I might just construct this inline on line 56, rather than splitting the construction between there and here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a bit annoying to construct in one line. Are you suggesting I just enumerate them all manually?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was suggesting:

optimizations = {"debug", "noopt", "pgo", "lto", "pgo+lto"}
optimizations = optimizations.union({f"freethreaded+{o}" for o in optimizations})
parser.add_argument(..., choices=optimizations)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thanks for clarifying. It'd be options = optimizations.union(...) and I'm hesitant to introduce another local variable (basically just personal preference).

msvc_version: str,
windows_sdk_version: str,
openssl_archive,
libffi_archive,
openssl_entry: str,
) -> pathlib.Path:
pgo = profile == "pgo"
parsed_build_options = set(build_options.split("+"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this wrong before? Or was it just never called with pgo+lto?

Copy link
Member Author

@zanieb zanieb Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah there are only "pgo" builds on Windows. I just changed this for consistency.

See https://github.com/indygreg/python-build-standalone/pull/326/files#r1777582385

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this seems like a good change.

Comment on lines +1866 to 1873
# TODO: Rename this to `--options` to match the Unix build script
optimizations = {"debug", "noopt", "pgo", "lto", "pgo+lto"}
parser.add_argument(
"--profile",
choices={"noopt", "pgo"},
"--options",
choices=optimizations.union({f"freethreaded+{o}" for o in optimizations}),
default="noopt",
help="How to compile Python",
help="Build options to apply when compiling Python",
)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things to follow up on here

  • I renamed this, I should remove the stale comment.
  • I added more optimization types here, that's wrong I should remove the other options.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Hesitant to do that in this pull request unless there are other changes since it takes so long to do builds)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff --git a/cpython-windows/build.py b/cpython-windows/build.py
index 3425a3b..92bca7d 100644
--- a/cpython-windows/build.py
+++ b/cpython-windows/build.py
@@ -1863,8 +1863,7 @@ def main() -> None:
         default="cpython-3.11",
         help="Python distribution to build",
     )
-    # TODO: Rename this to `--options` to match the Unix build script
-    optimizations = {"debug", "noopt", "pgo", "lto", "pgo+lto"}
+    optimizations = {"noopt", "pgo"}
     parser.add_argument(
         "--options",
         choices=optimizations.union({f"freethreaded+{o}" for o in optimizations}),

@zanieb zanieb merged commit 0d7e5e0 into main Sep 26, 2024
333 checks passed
zanieb added a commit that referenced this pull request Sep 26, 2024
These were unintentionally expanded in #326
zanieb added a commit that referenced this pull request Sep 26, 2024
These were unintentionally expanded in #326
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add python 3.13 free-threaded build
3 participants