Skip to content

Extend precompile workload for in-place QuadGKJL and HCubatureJL - #382

Merged
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:int-precompile-hcubature
Oct 16, 2026
Merged

ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:int-precompile-hcubature

Conversation

@ChrisRackauckas-Claude

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Summary

The existing src/precompile.jl workload only solves one out-of-place QuadGKJL problem. This extends it with an in-place QuadGKJL solve plus HCubatureJL 1-D and 2-D (Vector domain) solves, all using hard dependencies only (no optional extensions). The trade-off is longer package precompile for lower first-solve latency on those common user-defined integrand paths.

Before / after (process CPU, fresh process, min of 3)

Machine: amdci2, Julia 1.12.4, JULIA_NUM_THREADS=1 taskset -c 28. TTFS = process CPU (/proc/self/stat utime+stime) from after using Integrals through the first solve of a user-defined integrand. Precompile+load = /usr/bin/time %U+%S after clearing the Integrals compile cache.

workload before (s) after (s)
QuadGKJL out-of-place 0.88 0.85
QuadGKJL in-place 4.31 3.45
HCubatureJL 2D Vector domain 3.36 0.54
HCubatureJL 1-D 0.84 0.39
precompile+load CPU 12.9 / 13.2 24.3 / 25.1
using CPU ~2.20 ~2.26

Matches the auditor direction (HCub 2D 3.24→0.52, HCub 1-D 0.80→0.38, in-place QuadGK 4.24→3.40, precompile 14→25; using unchanged). Absolute precompile totals here are a bit lower than the auditor's 14.0 / 25.4 on a shared machine, but the delta is the same (~+12 s CPU).

Test-group tails

GROUP=Core (Julia 1.12.4):

Core/alt_transformation_tests.jl |   19     19
Core/gaussian_quadrature_tests.jl |   37     37
Core/hadaptiveintegration_tests.jl |    9      9
Core/inf_integral_tests.jl |  746    746
Core/interface_tests.jl |  871    871
Core/precompile_workload.jl |    1      1
Core/quadrule_tests.jl |    4      4
Core/sampled_tests.jl |   30     30
Core/verbosity_tests.jl |   25     25
Testing Integrals tests passed

GROUP=QA (Julia 1.12.4):

QA/qa.jl |   27     27
Testing Integrals tests passed

Julia 1.10.12: test/precompile_workload.jl + the three new workload shapes (in-place QuadGKJL, HCubatureJL 1-D, HCubatureJL 2-D Vector) all pass.

Runic --inplace and typos clean on src/precompile.jl.

Not verified

  • AD / ADBatch groups
  • Downstream packages that import Integrals
  • Precompile/TTFS on Julia 1.10 (only correctness smoke)
  • Windows / macOS precompile cost

Reviewer pushback

  • Is +~12 s package-precompile CPU worth the TTFS wins for in-place QuadGK and HCubature?
  • Should the workload also cover SVector domains, batched integrands, or infinite domains?
  • Prefer keeping the workload smaller and documenting first-solve costs instead?

Please ignore until reviewed by @ChrisRackauckas.

Risk assessment

Independent review: pending

🤖 Generated with Cursor Agent 2026.10.01-14929f9 (model: unknown (Cursor auto)), transcript /home/crackauc/sandbox/goals/performance/jobs/integrals/int-workload/log.txt on amdci2; orchestrated by Claude Code (claude-opus-5-5[1m]) https://claude.ai/code/session_01LPHREnnonfLg1VcE1EJovv

Made with Cursor

Independent review: Devin Fusion (fusion-claude-opus-5-5-high-sidekick-swe-2-medium) rated it low, verdict MERGE: #382 (comment)

Independent review (added by the fleet master)

Verdict: MERGE (reviewed head 9764f4f)

  • Risk: low
  • Blast radius: Package precompilation and first-solve latency for existing in-place QuadGKJL and scalar/vector-domain HCubatureJL paths. No solver implementation, dependency, public API, or numerical behavior changes; no SemVer bump is required for this workload addition.
  • Evidence: Rated low from the diff before reading the body. With JULIA_NUM_THREADS=4 JULIA_NUM_PRECOMPILE_TASKS=4 JULIA_DEPOT_PATH=<local> , ran julia +1 --project=review-env evidence/review382.jl: existing precompile test 1/1, three added workload-shape checks 3/3; results were [1/3], 1/3 and 1/4 as expected. Ran evidence/latency382.jl in separate fresh Julia 1.13.1 processes on exact base 63b17e8 and head: first in-place QuadGK solve 3.55→3.13 s, HCubature 1D 0.542→0.211 s, HCubature 2D 1.726→0.306 s; cached load 1.74→1.83 s. After removing only this review’s local Integrals compile-cache directory for the base and changing source for head, julia +1 --project=review-env -e '@time using Integrals' measured precompile+load 8.67→12.40 s. These are single wall-clock measurements, not statistically controlled benchmarks. The new source actually precompiled and loaded successfully. This is a performance addition, not a correctness bug; no failing-before test is expected. All 15 PR checks pass; latest default CI, downgrade, docs and formatting pass. Nothing is skipped, weakened, swallowed or removed. Full Core/QA/AD and LTS were not rerun locally.
  • Independent review: codex-cli gpt-6.1-sol rated it low, high confidence: all three workload shapes execute correctly and measured latency improvements justify the bounded precompilation cost.
  • Merge: auto-merge candidate — small workload-only change, green CI, independent harness from Cursor author, and no blocking findings.

🤖 Section added by an AI agent — harness: Claude Code 2.1.300 · model: claude-opus-5-5 (review by codex-cli, gpt-6.1-sol)
Conversation: https://claude.ai/code/session_01VZjwf7Ux9YtTzwHGHMqnsq

Cover in-place QuadGKJL plus HCubatureJL 1-D and 2-D Vector-domain solves so first-user solves of those paths pay less compile cost, at the expense of longer package precompile.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Cursor Agent <noreply@cursor.com>
Agent-Harness: Cursor Agent 2026.10.01-14929f9
Agent-Model: unknown (Cursor auto)
Agent-Session: local session, transcript /home/crackauc/sandbox/goals/performance/jobs/integrals/int-workload/log.txt on amdci2
@ChrisRackauckas

Copy link
Copy Markdown
Member

🤖 Automated comment from an AI agent running as @ChrisRackauckas — not written or reviewed by Chris.

Independent review (Devin CLI 3000.11.3, model fusion-claude-opus-5-5-high-sidekick-swe-2-medium): MERGE, risk low.

Full review

VERDICT: MERGE
RISK: low

Blocking findings

None.

Non-blocking findings

  1. Precompile cost roughly doubles for Integrals. This trade-off is the maintainer's call. (Confirmed by running.)
    • Measured with Pkg.precompile() wall time for Integrals alone on an M2 Max with Julia 1.12.7: 3.8 s on master, 6.8 s on the PR.

    • On Julia 1.10 (lts) the PR's precompile is 7.9 s. I did not measure master on 1.10.

    • The PR body puts the cost at about +12 s CPU on amdci2. That points the same way.

    • What the extra time buys, as time to first solve (TTFS) in a fresh process (Julia 1.12, 3 runs each, user-defined closures that differ from the workload's):

      workload master PR
      HCubatureJL 2-D Vector domain 2.1–2.8 s 0.54–0.62 s
      HCubatureJL 2-D in-place (not in the workload; still benefits) 2.0–2.4 s 0.65–0.71 s
      HCubatureJL 1-D 0.41–0.61 s 0.36–0.44 s
      QuadGKJL in-place 1.92–2.10 s 1.65–1.76 s (plus one 3.5 s outlier)
      QuadGKJL out-of-place ~0.5 s ~0.5 s (unchanged)
    • The HCubature gains are real and large. The in-place QuadGK gain is small (about 10–15% here, versus the PR's claimed 4.31→3.45 s), so that one line buys little.

  2. No test for the new workload shapes. (From reading.)
    • test/precompile_workload.jl still checks only the out-of-place QuadGKJL case.
    • The PR body says the in-place QuadGKJL, HCubatureJL 1-D and 2-D shapes were checked on 1.10, but no test was committed.
    • Strictly, the workload doesn't need a test: if it throws, precompilation fails.
    • CLAUDE.md's "always add tests" asks for one anyway. A cheap fix is to add correctness asserts for those three shapes to that file.
  3. The PR body cites unlinked material. (From reading.) It refers to an "auditor" and their numbers (3.24→0.52, etc.) with no link. That can't be verified and should be either linked or removed. The PR also links no issue.
  4. Core test failures on this machine are pre-existing, not caused by the PR. (Confirmed by running.)
    • GROUP=Core on the PR head on macOS aarch64 with Julia 1.12.7: 4 failures in Core/interface_tests.jl, "Caching interface" (lines 433/436/439/441).
    • All four are CubaSUAVE: -0.83931 vs -0.83021 at rtol=1e-2.
    • Running that testset alone on master gives the identical 4 failures with identical values (twice on each tree).
    • So they come from Cuba on this platform and are unrelated to this PR. The author's 871/871 was on x86 Linux.

What I ran

  • gh pr view 382; git diff origin/master...HEAD. The change is 7 added lines in src/precompile.jl only, all calls to hard dependencies (QuadGK and HCubature are in [deps]).
  • Exported master and the PR head to scratch/{master,pr}, with separate dev environments on Julia 1.12.7. Pkg.precompile() timings are in finding 1.
  • scratch/ttfs.jl: fresh-process TTFS and correctness against closed-form values (rtol 1e-6) for 6 shapes, 3 runs each, on both trees.
    • All results were correct, with retcode=Success.
    • A tuple-of-tuples 2-D domain throws a MethodError on master and the PR alike, so that is a limit of my probe, not a regression.
  • Julia 1.10 (lts): built a PR environment and precompiled it with no warnings. TTFS probes for in-place QuadGK, HCubature 1-D, 2-D and 2-D in-place all gave correct results.
  • GROUP=Core julia +1.12 --project -e 'using Pkg; Pkg.test()' on the PR tree: 867 passed, 4 failed. Every other Core file passed in full, including precompile_workload.jl.
  • scratch/caching_probe.jl (interface_tests.jl header plus the "Caching interface" testset), run twice each on master and the PR: the same 4 CubaSUAVE failures both times.
  • typos on src/precompile.jl: clean. Runic --check: clean.
  • Precompile output showed no verbosity or warning messages from the new workload calls.

What I did not verify

  • GROUP=QA, AD and ADBatch on the PR. The change cannot plausibly affect AD; I did not check QA (Aqua/JET).
  • Precompile or TTFS on x86 Linux and Windows; the amdci2 numbers in the PR body are taken as given.
  • Invalidations caused for downstream packages, and downstream precompile impact.
  • 32-bit x86 (the CI "Core 32-bit" group).

🤖 Posted by an AI agent — harness: Devin CLI 3000.11.3 (review), Claude Code 2.1.285 (posting) · model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium
Conversation: local Claude session 3c311569-dda6-4687-bc9f-65febb212c33 (fleet master)

@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review October 16, 2026 05:09
@ChrisRackauckas
ChrisRackauckas merged commit 840c20e into SciML:master Oct 16, 2026
15 checks passed
ChrisRackauckas referenced this pull request Oct 17, 2026
Bump version to 5.5.4
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Harness: Claude Code 2.1.301
Agent-Model: claude-opus-5-5
Claude-Session: https://claude.ai/code/session_01VZjwf7Ux9YtTzwHGHMqnsq
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.

2 participants