Skip to content

feat(delphi): Clojure timing probe (Spec C)#2643

Draft
jucor wants to merge 1 commit into
spr/edge/bbb74f71from
spr/edge/96c1f19e
Draft

feat(delphi): Clojure timing probe (Spec C)#2643
jucor wants to merge 1 commit into
spr/edge/bbb74f71from
spr/edge/96c1f19e

Conversation

@jucor

@jucor jucor commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Add scripts/clj_timing_probe.py — a click CLI that runs the Clojure
Mode A replay driver (math/dev/replay.clj) at increasing vote-count
sizes, records wall-clock seconds + final-blob success per size, fits
runtime ~ a + b*N^k (log-log least squares, a estimated from the
smallest run as the fixed JVM-startup cost), and recommends the
largest N that stays within a wall-clock budget.

TDD: tests/replay_harness/test_timing_probe.py mocks the clojure
subprocess for all unit tests (CSV truncation, schedule shape, fit
recovery on synthetic power-law data, recommendation math, stdout
line budget, CLI end-to-end) plus one real-subprocess integration
test gated on clojure being on PATH and RUN_CLJ_INTEGRATION=1.

commit-id:96c1f19e


Stack:


⚠️ Part of a stack created by spr. Do not merge manually using the UI - doing so may have unexpected results.

Add scripts/clj_timing_probe.py — a click CLI that runs the Clojure
Mode A replay driver (math/dev/replay.clj) at increasing vote-count
sizes, records wall-clock seconds + final-blob success per size, fits
runtime ~ a + b*N^k (log-log least squares, a estimated from the
smallest run as the fixed JVM-startup cost), and recommends the
largest N that stays within a wall-clock budget.

TDD: tests/replay_harness/test_timing_probe.py mocks the clojure
subprocess for all unit tests (CSV truncation, schedule shape, fit
recovery on synthetic power-law data, recommendation math, stdout
line budget, CLI end-to-end) plus one real-subprocess integration
test gated on `clojure` being on PATH and RUN_CLJ_INTEGRATION=1.

commit-id:96c1f19e
This was referenced Jul 22, 2026
@jucor
jucor marked this pull request as draft July 22, 2026 00:51
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 02:01
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 02:02
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 02:10
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 02:10
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 03:54
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 03:54
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 06:16
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 06:16
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 06:50
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 06:50
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 08:11
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 08:11
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 09:58
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 09:58
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 11:20
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 11:21
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 24, 2026 06:02
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 24, 2026 06:02
@jucor
jucor requested a review from Copilot July 25, 2026 22:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Delphi-side CLI tool to empirically benchmark the Clojure Mode A replay driver (math/dev/replay.clj) across increasing vote-count sizes, fit a simple power-law runtime model, and emit a recommendation for a max vote cutoff within a wall-clock budget—along with a thorough mocked test suite and one gated real-subprocess integration test.

Changes:

  • Added delphi/scripts/clj_timing_probe.py: Click CLI to run Clojure replays on truncated vote CSVs, time them, fit t ~ a + b*N^k, and recommend an N within --budget-min.
  • Added delphi/tests/replay_harness/test_timing_probe.py: unit tests with fully mocked subprocess plus a gated integration test that runs real clojure -M:replay.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
delphi/scripts/clj_timing_probe.py Implements the timing probe CLI, subprocess invocation, runtime fitting, and report generation.
delphi/tests/replay_harness/test_timing_probe.py Adds unit + gated integration coverage for the timing probe behavior.
Comments suppressed due to low confidence (1)

delphi/scripts/clj_timing_probe.py:437

  • probe() doesn’t handle an empty votes file (n_max==0) and may write schedules / run probes at size=0. Also, recommend_max_votes() can return a value larger than the dataset size; the CLI should clamp the recommendation to n_max so the output is actionable.
    n_max = count_data_rows(votes_path)
    size_list = parse_sizes(sizes, n_max)
    if not size_list:
        raise click.UsageError("no sizes to probe")

    results = run_all(
        size_list, votes_path, dataset=dataset, math_dir=MATH_DIR, timeout=timeout_sec,
    )

    ok_sizes = [r.size for r in results if r.ok]
    ok_seconds = [r.seconds for r in results if r.ok]
    if ok_sizes:
        fit = fit_power_law(ok_sizes, ok_seconds)
    else:
        fit = FitResult(a_est=None, b=None, k=None, n_fit_points=0)

    recommended = recommend_max_votes(fit, budget_min)


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +106 to +117
def parse_sizes(spec: str, n_max: int) -> list[int]:
"""Parse a comma-separated size list, capped at ``n_max``, deduped, ascending."""
sizes: set[int] = set()
for part in spec.split(","):
part = part.strip()
if not part:
continue
n = int(part)
if n <= 0:
raise ValueError(f"size must be positive, got {n}")
sizes.add(min(n, n_max))
return sorted(sizes)
Comment on lines +339 to +343
lines.append(f"recommended_max_votes~={recommended} for budget={budget_min:g}min")
else:
lines.append(f"recommended_max_votes=NA for budget={budget_min:g}min (insufficient data)")

return lines
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