Skip to content

feat: alloc profile analyzer (top_alloc_types/leaves/frames + report)#8

Merged
jack-champagne merged 1 commit into
chore/github-alignmentfrom
feat/alloc-analyzer
May 20, 2026
Merged

feat: alloc profile analyzer (top_alloc_types/leaves/frames + report)#8
jack-champagne merged 1 commit into
chore/github-alignmentfrom
feat/alloc-analyzer

Conversation

@jack-champagne
Copy link
Copy Markdown
Member

@jack-champagne jack-champagne commented May 20, 2026

Summary

Adds src/analyze.jl — aggregation helpers for AllocProfileResult that
previously lived as a DTO-local script in
harmoniqs/DirectTrajOpt.jl#71
(benchmark/analyze_allocs.jl) but are general-purpose and belong next to
benchmark_memory! here in HBJ.

PR #71 in DTO is stale and most of its value is now covered by HBJ v0.2.0's
benchmark_memory!. The one piece worth keeping is the analyzer — porting it
here so any HBJ consumer (DTO, Piccolissimo, Piccolo, …) can call it on the
profiles benchmark_memory! produces, without each downstream having its own
copy.

What's in the PR

Three query functions return Vector{AllocFrameSummary} sorted by allocated
bytes, with optional 1 / \texttt{sample\_rate} extrapolation:

  • top_alloc_types(profile; k=15) — by allocated type
  • top_alloc_leaves(profile; k=25) — by first non-noise/non-wrapper frame (the
    user-code call site that actually allocated)
  • top_alloc_frames(profile; k=25) — by every frame in every sample's stack

Built-in noise patterns drop Julia runtime / GC / Profile.Allocs / loader
frames; built-in HBJ-wrapper patterns drop benchmark_memory! and
package-internal frames so leaf views show actual user code. Both sets are
extensible via extra_noise / extra_wrappers kwargs.

report_alloc_profile is a pretty-printer that calls all three.

Also adds Printf to [deps] / [compat] (was implicitly loaded by other
deps but not declared).

Test plan

  • Pkg.test() passes locally — 295 passing, including a new
    analyze: top_alloc_types / leaves / frames testset that builds a synthetic
    AllocProfileResult, verifies noise filtering, sample-rate scaling, and
    extra_noise / extra_wrappers threading.
  • CI green
  • Once merged, DTO PR #71 can be closed and any downstream that wants
    alloc analysis (DTO, Piccolissimo) can pull this in via using HarmoniqsBenchmarks: report_alloc_profile

Follow-up

The DTO-local benchmark/analyze_allocs.jl CLI driver (reads from
results/allocs/, prints reports) can become a 10-line wrapper around
report_alloc_profile in DTO once HBJ ships these helpers.

@jack-champagne jack-champagne changed the base branch from main to chore/github-alignment May 20, 2026 06:34
jack-champagne added a commit that referenced this pull request May 20, 2026
Bring HBJ's `.github/` up to parity with the Piccolo.jl-shaped layout
that the rest of the org uses. Files are copied verbatim from Piccolo
unless noted.

Workflows
---------

- **CI.yml**: replace the precompile-only smoke check with the
  canonical matrix test workflow — runs `julia-runtest`, processes
  coverage, and uploads to codecov on Julia 1.10/1.11/1.12 + Linux
  x64. Adds `paths-ignore: ['docs/**', '*.md']` so doc-only PRs don't
  burn CI minutes once docs/ exists.
- **Formatter.yml** *(new)*: JuliaFormatter check on PR/push, with
  workflow_dispatch escape hatch to autoformat + commit.
- **nightly.yml** *(new)*: daily Julia 'pre' install check (matches
  Piccolo — install-only, not test run; intentionally lighter than
  DTO's nightly).
- **TagBot.yml**: cosmetic — unquote `lookback: 3` to match Piccolo
  exactly (functionally identical, both parse as string).

(Piccolo's `tasksmd-sync.yml` is intentionally omitted — HBJ doesn't
use the TASKS.md convention and adding the workflow speculatively is
clutter.)

dependabot.yml
--------------

Add the `julia` ecosystem alongside `github-actions` so dependabot
opens compat-bump PRs against Project.toml weekly. Comments restored
to Piccolo's verbose form.

CI.yml previously only checked that the package precompiles and loads —
so the test suite was never actually run on CI. This commit fixes that
gap; downstream branches (e.g. the alloc-analyzer PR #8) will rebase
on top of this to pick up the real test runs.
@jack-champagne jack-champagne force-pushed the chore/github-alignment branch from 98fc9d6 to f5c08c4 Compare May 20, 2026 06:40
jack-champagne added a commit that referenced this pull request May 20, 2026
Bring HBJ's `.github/` up to parity with the Piccolo.jl-shaped layout
that the rest of the org uses. Files are copied verbatim from Piccolo
unless noted.

Workflows
---------

- **CI.yml**: replace the precompile-only smoke check with the
  canonical matrix test workflow — runs `julia-runtest`, processes
  coverage, and uploads to codecov on Julia 1.10/1.11/1.12 + Linux
  x64. Adds `paths-ignore: ['docs/**', '*.md']` so doc-only PRs don't
  burn CI minutes once docs/ exists.
- **Formatter.yml** *(new)*: JuliaFormatter check on PR/push, with
  workflow_dispatch escape hatch to autoformat + commit.
- **nightly.yml** *(new)*: daily Julia 'pre' install check (matches
  Piccolo — install-only, not test run; intentionally lighter than
  DTO's nightly).
- **tasksmd-sync.yml** *(new)*: TASKS.md ↔ org GitHub Project sync.
  Filtered on `paths: ['TASKS.md']` so it's a no-op until/unless HBJ
  adopts the TASKS.md convention.
- **TagBot.yml**: cosmetic — unquote `lookback: 3` to match Piccolo
  exactly (functionally identical, both parse as string).

dependabot.yml
--------------

Add the `julia` ecosystem alongside `github-actions` so dependabot
opens compat-bump PRs against Project.toml weekly. Comments restored
to Piccolo's verbose form.

CI.yml previously only checked that the package precompiles and loads —
so the test suite was never actually run on CI. This commit fixes that
gap; downstream branches (e.g. the alloc-analyzer PR #8) will rebase
on top of this to pick up the real test runs.
@jack-champagne jack-champagne force-pushed the feat/alloc-analyzer branch 2 times, most recently from e21d665 to 60463a7 Compare May 20, 2026 06:40
Adds `src/analyze.jl` — aggregation helpers for `AllocProfileResult`
that previously lived as a DTO-local script
(`DirectTrajOpt.jl/benchmark/analyze_allocs.jl`) but are general-purpose
and belong next to `benchmark_memory!` here in HBJ.

Three core query functions return `Vector{AllocFrameSummary}` sorted by
allocated bytes, with optional `1/sample_rate` extrapolation:

  - `top_alloc_types(profile; k=15)`     — by allocated type
  - `top_alloc_leaves(profile; k=25)`    — by first non-noise/non-wrapper
                                           frame (the user-code call site)
  - `top_alloc_frames(profile; k=25)`    — by every frame in every sample's
                                           stacktrace

Built-in noise patterns drop Julia runtime / GC / `Profile.Allocs` /
loader frames; built-in HBJ-wrapper patterns drop `benchmark_memory!` and
package-internal frames so the leaf view shows actual user code. Both
sets are extensible via `extra_noise` / `extra_wrappers` kwargs for
caller-specific patterns (e.g. an integration that wants to drop its
own dispatch shims).

`report_alloc_profile` is a pretty-printer that calls all three.

Also adds Printf to `[deps]` / `[compat]` (was implicitly available
through the runtime but not declared) and a unit test that builds a
synthetic `AllocProfileResult`, verifies noise filtering, scaling, and
extra-pattern threading.
jack-champagne added a commit that referenced this pull request May 20, 2026
* chore: align .github structure with Piccolo conventions

Bring HBJ's `.github/` up to parity with the Piccolo.jl-shaped layout
that the rest of the org uses. Files are copied verbatim from Piccolo
unless noted.

Workflows
---------

- **CI.yml**: replace the precompile-only smoke check with the
  canonical matrix test workflow — runs `julia-runtest`, processes
  coverage, and uploads to codecov on Julia 1.10/1.11/1.12 + Linux
  x64. Adds `paths-ignore: ['docs/**', '*.md']` so doc-only PRs don't
  burn CI minutes once docs/ exists.
- **Formatter.yml** *(new)*: JuliaFormatter check on PR/push, with
  workflow_dispatch escape hatch to autoformat + commit.
- **nightly.yml** *(new)*: daily Julia 'pre' install check (matches
  Piccolo — install-only, not test run; intentionally lighter than
  DTO's nightly).
- **TagBot.yml**: cosmetic — unquote `lookback: 3` to match Piccolo
  exactly (functionally identical, both parse as string).

(Piccolo's `tasksmd-sync.yml` is intentionally omitted — HBJ doesn't
use the TASKS.md convention and adding the workflow speculatively is
clutter.)

dependabot.yml
--------------

Add the `julia` ecosystem alongside `github-actions` so dependabot
opens compat-bump PRs against Project.toml weekly. Comments restored
to Piccolo's verbose form.

CI.yml previously only checked that the package precompiles and loads —
so the test suite was never actually run on CI. This commit fixes that
gap; downstream branches (e.g. the alloc-analyzer PR #8) will rebase
on top of this to pick up the real test runs.

* chore: apply JuliaFormatter to existing tree

The Formatter workflow added in the previous commit will reject any
source file that isn't JuliaFormatter-clean. HBJ has never had a
formatter check, so the existing tree had accumulated formatter debt
(multi-line arg lists kept on one line, short conjunctions split
across multiple lines, etc).

Apply `JuliaFormatter.format(".")` over the whole repo so the Formatter
CI check on this PR (and every PR thereafter) starts from a clean
baseline. No semantic changes.

Touched: examples/convergence_template.jl, src/extractors.jl,
src/harness.jl, src/report.jl, src/schema.jl, src/storage.jl,
test/runtests.jl.
@jack-champagne jack-champagne merged commit afca64c into chore/github-alignment May 20, 2026
4 checks passed
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.

1 participant