Repository navigation
lean: Share dependencies and fetch selective Mathlib caches - #8712
Closed
Heidi Howard (heidihoward) wants to merge 5 commits into
Closed
Heidi Howard (heidihoward) wants to merge 5 commits into
Heidi Howard (heidihoward) wants to merge 5 commits into
Conversation
…rnative-to-mathlib-removal
Retain Mathlib and the existing verification roots while reducing dependency provisioning and storage. Share remote packages locally, fetch only required cache closures, and key CI caches by the required module set so proof-only edits can reuse dependency builds. Add setup regression coverage and document migration, cache-path compatibility, and sequential use of the shared dependency tree.
Member
Author
|
Closing as we are doing #8702 instead |
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.
Motivation
This is an alternative to #8702 that retains Mathlib and the current mathematical definitions, theorem statements, proof implementations, dependency revisions, and lint drivers.
It targets dependency provisioning and storage rather than replacing the sequence and finite-set types used in the specifications.
Changes
lean/.lake/packages, retaining separate first-party build outputs.scripts/lean-setup.shto fetch only the cache closure required by each package's direct Mathlib imports and shared common imports, plus Batteries' lint-driver dependencies where needed.import all, deduplicate module names, and exclude generated.laketrees from discovery..lake/packagescompatibility symlinks before fetching caches.No
.leansource file or locked dependency revision changes.Kernel/axiom checks, import coverage, architecture checks, linters, replay fixtures, and the complete library roots are retained.
Local measurements
These are local sequential-package measurements, not measurements of GitHub Actions performance.
The benchmark used three fresh source snapshots at
956411001165b447107261089b9bc54584e4985a, Lean v4.35.0, Linux x86_64 with 8 logical processors and approximately 15 GiB RAM.Each variant started with empty project dependencies and separate empty
XDG_CACHE_HOME,MATHLIB_CACHE_DIR, andLAKE_CACHE_DIR.The Lean toolchain was already installed.
Packages ran in this order: common, KV, consistency, disaster recovery, consensus.
For each package, dependency setup was followed by
lake build.Variants ran sequentially rather than concurrently.
lean/tree.ltarcache filesDependency setup includes materializing/cloning packages, compiling the Mathlib cache executable, and fetching/unpacking the cache.
The time totals sum the timed commands; they exclude disk-measurement overhead.
Disk figures use allocated bytes from
du -s -B1and were recorded before additional validation.Compressed cache sizes are disk measurements, not measurements of total network traffic; Git dependency downloads are additional.
Together, the changes reduced dependency setup by 69.4%, setup plus first builds by 21.1%, and built-tree disk use by 95.2% in this run.
Selective fetching alone substantially reduced disk use but did not demonstrate an end-to-end speed improvement.
Native build timings varied considerably despite unchanged sources, including a 332 s first KV build in the shared run versus 144 s in the baseline.
This was one pass per variant on a shared machine, without OS page-cache flushing or statistical repetitions, so these timing differences are indicative rather than causal estimates or guarantees.
Cache-path compatibility finding
Changing
packagesDiralone is not enough with the pinned Mathlib cache tool.Mathlib's own archives are redirected to its resolved directory, but other dependencies' archives use embedded paths beneath
.lake/packages.Without the compatibility links, Batteries artifacts landed outside the configured shared dependency tree and the common first build rebuilt Batteries from source, taking 161.4 s.
That exploratory attempt was stopped and excluded from the comparison.
The shared measurement was restarted from a fresh snapshot and empty caches with the links present; its common first build took 7.8 s.
Detailed impact on CI performance
Where this helps
The Lean workflow has five isolated package jobs and three independent trace-replay jobs.
All eight switch from an unrestricted Mathlib cache fetch to fetching the required module closure.
ci.ymlThe strongest expected CI benefit is smaller dependency download/cache archives and less archive I/O, not faster proof checking.
Actual Actions archive sizes and transfer times still need measurement: the local compressed Mathlib cache directory is not the Actions cache archive, which also includes Git checkouts and native build outputs.
Why the local 21% result is not a CI prediction
The local benchmark builds all five packages in one checkout.
Its shared directory avoids repeated Git materialization, repeated compilation of the Mathlib cache executable, and some repeated dependency compilation across packages.
Separate CI jobs have separate filesystems and containers.
Changing their dependency directory does not make one job reuse another job's checkout or compiled dependencies.
Package caches remain keyed by package and architecture, and replay jobs remain independent.
This PR does not introduce a dependency-preparation job, cross-job artifact reuse, a shared mutable directory between jobs, or replay-binary transfer.
Those would be separate workflow changes.
Consequently, do not apply the 69% local setup reduction or 21% local total reduction to the parallel CI workflow.
The selective-only local result also shows why reducing download/disk footprint alone does not establish a total-time improvement.
No new GitHub Actions before/after timings are claimed here.
Work that remains unchanged
Selective fetching changes which unused prebuilt files are downloaded, not the modules actually imported by the specifications.
Mathlib remains in the checked import closures.
lake checkstill exports and independently rechecks those declarations and audits their axioms.The native modules needed by replay executables still need to be compiled/linked.
The existing package check targets, test roots, lint drivers, and axiom policy remain unchanged.
Unlike removing Mathlib, this does not remove its imported environment from kernel rechecking.
It should not be expected to reproduce the proof-checking or native-linking reductions reported by #8702.
Cold/warm comparison and follow-up measurement
The v3 key and changed dependency configuration deliberately invalidate the old, oversized caches.
The first successful run will pay cold setup and archive-upload costs.
It should not be compared directly with a warm-cache baseline as a steady-state result.
Before calling this a CI speedup, compare:
Record dependency-cache restore/save durations and bytes, selective Mathlib fetch duration and requested-module counts, build/kernel/axiom step duration, replay build duration, total job-seconds across the eight jobs, and the workflow's longest dependency path separately.
Also record toolchain installation, container/package-manager time, runner queue time, and native capture variation so unrelated variation is not attributed to this change.
Proof-only edits should retain the module-list hash; changing direct imports should invalidate the corresponding selective cache without requiring a Mathlib version bump.
Migration and limitations
For an existing checkout, move the old package-local
.lake/packagesdirectories aside before running the helper.It refuses to overwrite/delete an existing directory or replace a symlink pointing elsewhere.
All five packages must keep compatible dependency pins, and setup/build/update commands sharing one dependency tree must run sequentially.
Fresh CI checkouts and the new cache namespace do not require manual migration.
Validation
Passed locally using the implemented helper:
python3 tests/lean_setup_test.py: 10 regression tests, covering module discovery, lint dependencies, generated-directory exclusion, repeat setup, shared links, non-destructive migration failures, invalid inputs, Lake error propagation, side-effect-free module listing, and import-sensitive/proof-insensitive cache identity.lake build --wfail --fail-fast,lake exe check-imports, the common-library build needed for downstream linting, andlake lint.cd lean/common && lake check --inadvisably-no-sandbox: independent kernel and axiom check passed.packagesDir; no Lean sources changed.Full local validation is not claimed:
scripts/ci-checks.shwas run without auto-fix. After restoring the missinguvtool and formatting only the new test file, 15 of its 16 checks passed. The sole remaining blocker isscripts/test-buckets-checks.sh:cmake: command not found. The bucket inventory still needs checking in the configured C++ build environment.sphinx-build --fail-on-warning -b html doc doc/htmlwas attempted after installing the documented documentation requirements in an isolated virtual environment. It is blocked byFileNotFoundError: 'doxygen'. A full documentation build still needs the documentation build prerequisites.