-
Notifications
You must be signed in to change notification settings - Fork 3
Bench suite + Stable mode #8
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
Merged
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
8d0ccfa
fix: correct cbrt on Double64 (DoubleFloats v1.9 returns a tuple)
lucifer1004 0600304
test: add performance benchmark suite
lucifer1004 9c7b374
ci: add PR benchmark workflow via AirspeedVelocity
lucifer1004 0b340a5
perf(ebcm): factor 𝐐 once instead of explicit inv, reuse across Jacob…
lucifer1004 6526a92
perf(iitm): solve M \ X instead of forming inv(M) in the radial recur…
lucifer1004 8f48a60
feat(ebcm): numerically stable F⁺ core for spheroid integrands (S1)
lucifer1004 51e14ef
fix: handle nₘₐₓ=1 in ricattibessely
lucifer1004 cd5cdca
feat(ebcm): cancellation-free modified Bessel products for stabilized…
lucifer1004 e17fd0e
feat(ebcm): all-x stable F⁺ matrix via series-seeded Eq.51 recursion …
lucifer1004 7f88cc9
feat(ebcm): wire stabilized spheroid path into transition_matrix + m>…
lucifer1004 2fb69bf
perf(ebcm)+docs: precompute F⁺ last-row coeffs, benchmark, document s…
lucifer1004 a84ab97
chore: format code
lucifer1004 85427e9
feat(ebcm): Sh-matrix moment separation — m=0 P and U reconstruction
lucifer1004 10776a4
feat(ebcm): Sh-matrix m>0 K and L block reconstruction
lucifer1004 2c71973
feat(ebcm): Sh-matrix two-step API — prepare_sh + transition_matrix +…
lucifer1004 6a90cf5
test+bench+docs(ebcm): Sh-matrix moment separation
lucifer1004 cea3eb8
perf(ebcm): Sh-matrix — precompute coefficients + folded convolution
lucifer1004 fabed66
perf(ebcm): Sh-matrix — hoist geometry, drop Mdτ, hoist angular products
lucifer1004 7574270
perf(ebcm): Sh-matrix — precision-split the moment precompute
lucifer1004 3279a8d
perf(ebcm): Sh-matrix — analytic-zeroing fast precompute for spheroids
lucifer1004 1911617
feat(api)!: two-layer solver API — fixed solvers + Iterative wrapper
lucifer1004 71a9d23
test(ebcm): Sh-matrix reconstructs non-spheroid shapes
lucifer1004 49d4dc1
docs(examples): Pluto notebook — spectral sensitivity via Sh-matrix
lucifer1004 5883e18
docs(examples): add four showcase Pluto notebooks
lucifer1004 93b98fa
docs: fix build and filter internal docstrings from the API reference
lucifer1004 b8a7dc1
docs: render example notebooks into the site (PlutoStaticHTML)
lucifer1004 0097c64
fix(ebcm): relax prepare_sh Ng-even check; validate spectrum lengths
lucifer1004 feb9c98
docs: backfill CHANGELOG with per-tag history; current work as Unrele…
lucifer1004 de80920
fix(docs): pre-render example notebooks; CI builds from committed pages
lucifer1004 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| name: Benchmark | ||
|
|
||
| # Runs the benchmark suite (benchmark/benchmarks.jl, the global `SUITE`) on each | ||
| # relevant pull request and writes a comparison table to the job summary. | ||
| # | ||
| # How the comparison works (AirspeedVelocity.jl): | ||
| # * It benchmarks TWO git revisions — the base branch (`main`) and this PR's | ||
| # head commit — NOT a stored historical baseline. | ||
| # * Both revisions are checked out into separate temp environments and run in | ||
| # separate Julia processes, back-to-back on the SAME runner within this one | ||
| # job. The reported `ratio` is head/base (<1 faster, >1 slower). | ||
| # * Running both on the same machine cancels systematic hardware differences, | ||
| # but shared GitHub runners are still noisy (~±10–30% on microbenchmarks): | ||
| # trust this for order-of-magnitude / large regressions, not 5% wobble. | ||
| # | ||
| # Security: this uses the `pull_request` event (not `pull_request_target`), so a | ||
| # fork's PR code runs with a read-only token and no secrets. Output goes to the | ||
| # Actions job summary (`job-summary: "true"`) instead of a PR comment, so no | ||
| # write token is ever needed — nothing is posted to fork (or same-repo) PRs. | ||
| # View results under the workflow run's "Summary" tab. | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - "src/**" | ||
| - "benchmark/**" | ||
| - "Project.toml" | ||
| - ".github/workflows/Benchmark.yml" | ||
| workflow_dispatch: | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| benchmark: | ||
| name: Benchmark PR vs main | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: MilesCranmer/AirspeedVelocity.jl@action-v1 | ||
| with: | ||
| julia-version: "1" | ||
| job-summary: "true" | ||
| # Default compares `main` against this PR's head SHA. Uncomment to | ||
| # restrict to a fast, low-noise subset of the suite in CI: | ||
| # filter: "special_functions,ebcm,linearization,postprocessing" | ||
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # Changelog | ||
|
|
||
| All notable changes to this project are documented here. The format is based on | ||
| [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project | ||
| adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
|
||
| ## [Unreleased] | ||
|
|
||
| Work on top of `v0.4.0`. Includes a breaking change to solver selection, so the | ||
| next release is expected to be `v0.5.0`. | ||
|
|
||
| ### Added | ||
|
|
||
| - **Sh-matrix moment-separation method** for fast parameter sweeps: | ||
| `prepare_sh`, `transition_matrix(prep, λ, mᵣ)`, and `transition_matrix_spectrum`. | ||
| The geometry quadrature is computed once and reused, so wavelength / | ||
| refractive-index sweeps are cheap; for spheroids it also reproduces the | ||
| high-aspect stabilization analytically. Works for any axisymmetric shape. | ||
| - **Two-layer solver API**: fixed-discretization solvers `EBCM`, `IITM`, | ||
| `ShMatrix`, and the `Iterative` convergence wrapper (with `ConvergencePolicy`), | ||
| selected via `transition_matrix(s, λ, solver)`. | ||
| - **Stabilized high-aspect-ratio spheroids** (`stable = true`): the | ||
| cancellation-free `F⁺` formulation of Somerville, Auguié & Le Ru (2013), | ||
| available as `EBCM(nₘₐₓ, Ng; stable = true)` and, auto-converged, as | ||
| `Iterative(EBCM; stable = true)`. | ||
| - **Performance benchmark suite** and a PR benchmark CI workflow | ||
| (AirspeedVelocity). | ||
| - **`examples/` folder** with five runnable Pluto notebooks — shapes gallery, | ||
| angular scattering & polarization, orientation averaging, solver landscape, and | ||
| spectral sensitivity — rendered into the documentation site. | ||
|
|
||
| ### Changed | ||
|
|
||
| - **(Breaking)** Solver selection moves to solver objects passed to | ||
| `transition_matrix(s, λ, solver)`. The keyword-based auto-converge | ||
| `transition_matrix(s, λ; threshold, …)` is replaced by | ||
| `Iterative(EBCM; threshold, …)`. The bare `transition_matrix(s, λ)` / | ||
| `calc_T(s, λ)` is unchanged (auto-converged classic EBCM). | ||
| - Performance: factor `𝐐` once and reuse it across Jacobian slices instead of an | ||
| explicit `inv`; the IITM radial recursion solves `M \ X` instead of forming | ||
| `inv(M)`; the Sh-matrix precompute is optimized (coefficient precompute, folded | ||
| convolution, precision split, and an analytic-zeroing fast path for spheroids). | ||
| - Documentation: the API reference now filters internal (underscore-prefixed) | ||
| docstrings and uses `checkdocs = :exported`. | ||
|
|
||
| ### Fixed | ||
|
|
||
| - `prepare_sh` requires an even `Ng` only for shapes with an equatorial symmetry | ||
| plane (non-symmetric shapes accept odd `Ng`). | ||
| - `transition_matrix_spectrum` validates that `λs` and `mᵣs` have matching lengths | ||
| instead of silently truncating to the shorter one. | ||
| - `ricattibessely` handles `nₘₐₓ = 1`. | ||
| - `cbrt` on `Double64` (DoubleFloats v1.9 returns a tuple). | ||
|
|
||
| ## [0.4.0] - 2026-06-04 | ||
|
|
||
| - Performance optimizations and the analytical linearization framework | ||
| (`LinearizationProblem`, `linearize_transition_matrix`, with Mie / EBCM / IITM | ||
| backends). See [#7](https://github.com/JuliaRemoteSensing/TransitionMatrices.jl/pull/7). | ||
|
|
||
| ## [0.3.1] - 2026-01-18 | ||
|
|
||
| - Raise the `Wigxjpf` compatibility bound to v0.2; CI configuration updates. | ||
|
|
||
| ## [0.3.0] - 2025-04-03 | ||
|
|
||
| - Compatible with Julia 1.13. | ||
| - Removed `ArbNumerics` from the dependencies; its types are no longer | ||
| re-exported (use `Arblib`'s `Arb`/`Acb`). | ||
|
|
||
| ## [0.2.0] - 2023-04-02 | ||
|
|
||
| - Early development release. | ||
|
|
||
| ## [0.1.0] - 2023-03-17 | ||
|
|
||
| - Initial release. | ||
|
|
||
| [Unreleased]: https://github.com/JuliaRemoteSensing/TransitionMatrices.jl/compare/v0.4.0...HEAD | ||
| [0.4.0]: https://github.com/JuliaRemoteSensing/TransitionMatrices.jl/compare/v0.3.1...v0.4.0 | ||
| [0.3.1]: https://github.com/JuliaRemoteSensing/TransitionMatrices.jl/compare/v0.3.0...v0.3.1 | ||
| [0.3.0]: https://github.com/JuliaRemoteSensing/TransitionMatrices.jl/compare/v0.2.0...v0.3.0 | ||
| [0.2.0]: https://github.com/JuliaRemoteSensing/TransitionMatrices.jl/compare/v0.1.0...v0.2.0 | ||
| [0.1.0]: https://github.com/JuliaRemoteSensing/TransitionMatrices.jl/releases/tag/v0.1.0 |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| [deps] | ||
| BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" | ||
| TransitionMatrices = "057c4241-e127-4181-840e-6b4b92e6eef5" | ||
|
|
||
| [compat] | ||
| BenchmarkTools = "1" | ||
| julia = "1.10" |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| # Benchmarks | ||
|
|
||
| Performance benchmark suite for `TransitionMatrices.jl`, built on | ||
| [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl). The suite | ||
| follows the standard Julia convention — `benchmark/benchmarks.jl` defines a | ||
| single global `const SUITE::BenchmarkGroup` — so it works unchanged with both | ||
| [PkgBenchmark.jl](https://github.com/JuliaCI/PkgBenchmark.jl) and | ||
| [AirspeedVelocity.jl](https://github.com/MilesCranmer/AirspeedVelocity.jl). | ||
|
|
||
| ## Layout | ||
|
|
||
| | File | Purpose | | ||
| | --- | --- | | ||
| | `benchmarks.jl` | Defines `SUITE` (consumed by every tool below). | | ||
| | `runbenchmarks.jl` | Local runner: tune once, cache params, save results JSON. | | ||
| | `Project.toml` | Isolated environment; dev-depends on the parent package. | | ||
| | `params.json` | Cached `tune!` parameters (created on first run). | | ||
|
|
||
| ## Groups | ||
|
|
||
| - `special_functions` — Riccati-Bessel and Wigner-d recursions (inner kernels). | ||
| - `ebcm` — EBCM blocks, fixed-order solves, and end-to-end auto-convergence. | ||
| - `iitm` — Invariant Imbedding T-Matrix (axisymmetric and N-fold). | ||
| - `postprocessing` — far-field observables from a precomputed T-matrix. | ||
| - `linearization` — analytical EBCM Jacobian (baseline for the `inv` → `lu` work). | ||
| - `precision` — Float64 vs Double64 on the same EBCM block. | ||
|
|
||
| ## Running | ||
|
|
||
| The simplest path uses the parent `justfile`: | ||
|
|
||
| ```sh | ||
| just bench # instantiate the env and run the whole suite | ||
| ``` | ||
|
|
||
| Or directly: | ||
|
|
||
| ```sh | ||
| julia --project=benchmark -e 'using Pkg; Pkg.develop(path="."); Pkg.instantiate()' | ||
| julia --project=benchmark benchmark/runbenchmarks.jl results-baseline.json | ||
| ``` | ||
|
|
||
| Run a single group while iterating: | ||
|
|
||
| ```julia | ||
| julia --project=benchmark | ||
| julia> include("benchmark/benchmarks.jl"); | ||
| julia> run(SUITE["ebcm"]; verbose = true) | ||
| ``` | ||
|
|
||
| ## Comparing two revisions | ||
|
|
||
| Capture a baseline, make your change, capture again, then judge: | ||
|
|
||
| ```julia | ||
| using BenchmarkTools | ||
| old = BenchmarkTools.load("results-baseline.json")[1] | ||
| new = BenchmarkTools.load("results.json")[1] | ||
| judge(minimum(new), minimum(old)) # :improvement / :regression / :invariant | ||
| ``` | ||
|
|
||
| `minimum` is used because it is the most noise-robust statistic for these | ||
| deterministic numerical kernels. | ||
|
|
||
| For automated cross-revision runs (and PR comments), AirspeedVelocity.jl reads | ||
| the same `SUITE`: | ||
|
|
||
| ```sh | ||
| benchpkg TransitionMatrices --rev=main,HEAD --bench-on=HEAD | ||
| ``` |
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: JuliaRemoteSensing/TransitionMatrices.jl
Length of output: 125
🏁 Script executed:
Repository: JuliaRemoteSensing/TransitionMatrices.jl
Length of output: 189
🏁 Script executed:
Repository: JuliaRemoteSensing/TransitionMatrices.jl
Length of output: 929
Pin the AirspeedVelocity action to a commit SHA
MilesCranmer/AirspeedVelocity.jl@action-v1is a mutable tag; pin it to commit315c11b51ceee8ebd6063d70cff6ae499a040d28to prevent supply-chain mutation.Replace:
With:
🧰 Tools
🪛 zizmor (1.25.2)
[error] 45-45: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents