Repository navigation
Fetch the sysimage on import and make it portable - #154
Merged
Merged
Conversation
Published images only worked on the machine that built them: PythonCall stores its install path in `const ROOT_DIR`, and juliacall reads it at startup, so on any other machine Julia failed with `SystemError: opening file "/home/runner/.julia/packages/PythonCall/...`. - Leave PythonCall out of the image, so it loads from the user's depot. - Add a format version to image names (`galley-v2-...`) so the fixed images don't collide with the broken ones already published. - On import, download the image for this environment if it isn't cached, and use it right away. One process downloads at a time; a 404 is remembered for a day; interrupted downloads resume; and each image is started once in a subprocess before it's used, so a bad image can never break `import galley_jl_python`. GALLEY_JL_PYTHON_SYSIMAGE=0 turns it off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Leaving PythonCall out made images portable but slow: loading it on top of the image invalidated much of the image's code, and the first matmul spent 39 s recompiling it. PythonCall only uses its frozen install path, when Python embeds Julia, to locate juliacall's init.jl. relocate_pythoncall.jl, run by PackageCompiler while writing the image, redefines init_stdlib to find the identical copy in the Python juliacall package instead. The build refuses anything but PythonCall 0.9.36, so an upgrade forces the copied function to be checked again. In a separate project whose Julia depot differs from the build's, import takes 2.6-3.1 s and the first matmul 3.6-4.2 s, with no recompilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
galley pins Julia 1.12, which bundles OpenSSL 3.5 in the same process as Python, so juliapkg only allows it with a Python linked against OpenSSL 3.5+. With older OpenSSL (common: Ubuntu 24.04 and pyenv builds use 3.0), juliapkg failed with no compatible Julia version. Fail at import with an error that names the cause and the fix instead, and document the requirement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Published images only worked on the machine that built them. In a separate project depending on galley-jl-python, the published Linux image made Julia fail at startup:
PythonCall defines
const ROOT_DIR = dirname(dirname(@__DIR__)). In a sysimage that constant keeps the build machine's path, and juliacall uses it at startup to loadinit.jl. So every image insysimage-1c37dac2d47a03b0, on all four platforms, is broken everywhere except the CI runner that built it.Nothing downloaded images for users. Downloading was a repo-only
pixi run fetch-sysimagetask, so a project depending on galley never got an image.Changes
scripts/sysimage/relocate_pythoncall.jl).init.jl.scriptoption. It redefinesPythonCall.Core.init_stdlibto find the identical copy ofinit.jlin the Pythonjuliacallpackage, which is already insys.modulesat that point. Only that one line differs from PythonCall 0.9.36's function.galley-v2-<platform>-<arch>-<key>. The fixed images get new names instead of colliding with the broken v1 assets, which the CI skip check would otherwise treat as already published._sysimage.fetch, called fromconfigure()before Julia starts):Rangerequests.import galley_jl_python.GALLEY_JL_PYTHON_SYSIMAGE=0disables all of this.pixi run fetch-sysimagenow calls the same code.Testing
JULIA_DEPOT_PATHpointing at a scratch depot, then loaded it from a separate downstream project using~/.julia, so every package path differed. It loads, the startup check accepts it, and the downstream matmul gives the correct result.test_fused,test_einsum,test_ioandtest_indexingall pass (217 passed, 9 skipped).After this merges, the Sysimage workflow publishes v2 images for all four platforms. The broken v1 assets become unused and can be deleted.
🤖 Generated with Claude Code