Skip to content

rqe-optimizer: MILP on cost by use, with batch latency (reported, or as an SLA) - #188

Merged
zzylol merged 18 commits into
mainfrom
batch-sla
Oct 9, 2026
Merged

zzylol merged 18 commits into
mainfrom
batch-sla

Conversation

@zzylol

@zzylol zzylol commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

What

The MILP that plans RQE deployments now prices a plan's cost billed by use, and computes the plan's batch latency. Latency is used in two versions:

  1. No SLA: the cheapest plan, with its latency reported. A latency bound can be swept to trace the cost–latency Pareto frontier.
  2. Batch latency SLA: the cheapest plan whose batch latency is at most L.

This is for the AutoSketch vs. planner evaluation (ProjectASAP/ASAPQuery#777). The evaluation itself is #138, stacked on this PR.

The design is in docs/rqe_sketch_deployment_v1.md, section "Cost by use and batch latency". Every formula and the algorithm come with a plain-English explanation. The sections are:

  1. Definitions.
  2. Cost model, and how it maps to cloud billing.
  3. CPU parts and how each is computed.
  4. Memory parts and how each is computed.
  5. Batch latency and the SLA.
  6. The job placement algorithm.
  7. MILP formulation.
  8. Solution method.
  9. Outputs.

Model

  • Cost: w1 · AUC(CPU) + w2 · AUC(memory), CPU elastic, as on fine-grained autoscaling platforms. Provisioned (peak) billing is not modeled.
  • CPU:
    • Ingest (the precompute) runs on ⌈ρ⌉ workers split by sample.
    • A compaction job merges the workers' partial copies at each window close.
    • Each RQE firing issues one query job, which merges the query window's instances and then estimates.
    • Every job uses at most one core, because sketch-bench's operations are single-threaded (CPU time = wall time).
  • Memory, each part counted once:
    • ingest (open windows × workers);
    • storage (compacted closed windows);
    • compaction (partial copies, while it runs);
    • query (merge accumulators and output, while it runs).
  • Batch latency: the job placement (issue order, compaction before queries, longest first, up to one core per job) gives it. With elastic CPU it has a closed form: the longest chain, compaction then query.
  • MILP: linear and exact in both versions. A latency bound or SLA is a filter that rules out pairs whose chain is longer than L.

Code

  • rqe-optimizer/src/usage.rs: a plan's resource use, cost by use, and latency.
  • milp::minimize_usage_cost:
    • optional latency_bound_ms, for the frontier or the SLA;
    • optional allowed candidates per RQE, so PerQuery can rule out sharing: identical deployments become separate copies, each paying its own ingest.
  • analytical_cost_model: ingest_workers, compaction_secs, compaction_bytes, chain_ms.
  • The existing minimize is unchanged, so ASAPQuery's planner is unaffected.

Tests

  • Cost by use and latency of a small plan.
  • minimize_usage_cost matches brute force under three weight settings, and under four latency bounds; looser bounds never cost more.
  • allowed keeps identical deployments apart.
  • All 92 rqe-optimizer tests pass; clippy is clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

zzylol and others added 2 commits October 8, 2026 16:22
minimize_batch_sla bounds when an aligned batch of every RAQE finishes:
the plan provisions V vCPUs shared by ingest (rho_ing) and the batch's
merge and query work W, a fluid queue, so V >= rho_ing + W / SLA, and
V >= the mean CPU. CPU is priced at V. A pair whose per-group work
exceeds the SLA is forbidden. With a loose SLA the plan is minimize's.
analytical_cost_model gains provisioned_vcpus and batch_makespan_ms to
price any plan at an SLA. The model is in docs/rqe_sketch_deployment_v1.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
…for review)

Replaces the provisioned-V batch SLA write-up with the design under review:
precompute and query jobs per RAQE firing, each on at most one core; an
event-driven placement at a (CPU, memory) resource point gives batch
latency; cost model 1 bills AUC, cost model 2 the peak; the MILP uses a
linear surrogate and is verified by the placement. Four open questions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
@zzylol zzylol changed the title rqe-optimizer: batch latency SLA with provisioned vCPUs rqe-optimizer: cost models 1 and 2, batch latency via query placement (design for review) Oct 8, 2026
zzylol and others added 5 commits October 8, 2026 18:43
…apacity

Precompute is inserting samples into window instances (ingest), a steady
background load; each firing's query job merges the query window's
instances and estimates, at most one core. Capacity is fractional and
shared as rates. States sketch-bench's measurement assumption (single
threaded, CPU time = wall time). Two open questions remain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
…mory in three parts

Ingest runs on ceil(rho_D) workers split by sample, each with its own open
windows; a compaction job merges the partials at window close, on the
query's critical path. Memory is ingest, storage and query, each counted
once. Cost model 1 bills CPU and memory by use (elastic CPU, latency is the
longest chain); cost model 2 provisions (C, M), billed at the peak, with the
placement giving latency. The resource-point question is resolved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
Cost model 1 is exact and linear (elastic CPU: latency is the longest
chain). Cost model 2's batch row is a surrogate that chooses the mapping;
the placement then sizes C (smallest meeting the SLA) and M (its peak) for
every method alike, replacing the re-solve loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
placement: a plan's load over time (ingest on ceil(rho) workers split by
sample, compaction at window close, one query job per firing, each at
most one core), cost model 1 (by use, elastic CPU, latency = longest
chain) and cost model 2 (a provisioned (C, M) billed at the peak, sized
by an event-driven placement: the smallest C meeting the SLA, M its peak).

milp::minimize_cost_model: cost model 1 is exact and linear; cost model 2
uses a linear surrogate (batch work over the capacity ingest leaves,
every query's memory at once), then corrects it with the placement's
error on the chosen mapping and solves again, keeping the cheapest placed
mapping. The earlier provisioned-V minimize_batch_sla is removed;
minimize is unchanged.

Tests: placement (one core per job, fractional capacity, shared batches,
compaction before queries, backlog, both cost models); cost model 1
matches brute force with and without an SLA; cost model 2 meets the SLA
and matches the brute-force placed optimum.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
Title 'MILP with latency SLA constraints: cost models, query placement and
batch latency'; in order: definitions, the two cost models, CPU and memory
parts and how each is computed, batch latency vs. the SLA, the job
placement algorithm, the MILP formulation, and the solution method
(cost model 1 exact; cost model 2 surrogate, placement sizing and
correction passes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
@zzylol zzylol changed the title rqe-optimizer: cost models 1 and 2, batch latency via query placement (design for review) rqe-optimizer: MILP with latency SLA constraints — cost models 1 and 2, query placement and batch latency Oct 8, 2026
zzylol and others added 6 commits October 8, 2026 19:13
Cost model 1 is the placement with unlimited capacity (elastic CPU): every
job starts when ready on its own core, so the latency is the longest chain
and the closed form the MILP uses is exact; cost model 2 runs it with the
provisioned C. A test checks the closed form against the placement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
Queries are issued at their firing time; compaction is triggered at a
window close. The doc section and placement.rs use these terms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
…lacement

Cost model 2 matches containers billed by allocation and VMs (queueing for
a core or for memory lowers the peaks); cost model 1 matches idealized
fine-grained autoscaling, where queueing saves nothing and the cost-latency
trade-off comes from the plan (precompute vs. query-time merging). The
placement makes a job wait when its memory does not fit in M, and cost
model 2's sizing searches (C, M) for the cheapest pair meeting L.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
Billing charges the memory allocated; whether an application queues jobs
to fit a smaller allocation is its own policy, not billing. So the
placement has no memory limit and M is the peak it reaches at C*.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
- minimize_cost_model takes `allowed` candidates per RAQE, so PerQuery
  can rule out sharing: identical deployments as separate candidate copies
  each pay their own ingest (test).
- One chain function (analytical_cost_model::chain_ms) and one SLA slack
  (meets_sla, 1e-9 relative) for the MILP's chain filter and the
  placement, so a chain equal to L is never feasible in one and not the
  other.
- cost_model_2's doubling search stops after 64 steps.
- The placement keeps a pending list of issued, unfinished jobs instead of
  scanning every job at each event.
- A compaction holds the closed window's k partial copies while it runs:
  in AUC(memory), the placement's memory over time, and both MILPs'
  memory terms (test).
- Docs: instances vs. groups in the formulas; the compaction memory row;
  per-RAQE latency bounds are not used; the search bounds; PerQuery via
  `allowed`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
zzylol and others added 2 commits October 8, 2026 19:45
Without an SLA, cost model 2's capacity is not pinned down (at the mean
load, a placement that can't use every core keeps a growing backlog, so
its latency depends on how long it is simulated). cost_model_2 takes the
SLA, and minimize_cost_model asserts one for cost model 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
The paper's message is lower cost and lower latency, so the MILP drops
the peak-billed cost model and every latency constraint:

- usage.rs (replacing placement.rs): a plan's resource use (ingest on
  ceil(rho) workers split by sample, compaction at window close, one
  query job per firing), its cost w_cpu * AUC(CPU) + w_mem * AUC(memory),
  and its latency, the longest chain (CPU is elastic).
- milp::minimize_usage_cost (replacing minimize_cost_model): exact and
  linear, with `allowed` candidates per RAQE for PerQuery. Cost model 2,
  the placement, the SLA rows, the correction passes and meets_sla are
  removed; minimize is unchanged.
- Docs: "Cost by use and batch latency": definitions, the cost model,
  CPU and memory parts, batch latency (reported), the MILP, and how it
  is solved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
@zzylol zzylol changed the title rqe-optimizer: MILP with latency SLA constraints — cost models 1 and 2, query placement and batch latency rqe-optimizer: minimize cost billed by use; batch latency reported Oct 8, 2026
zzylol and others added 2 commits October 8, 2026 20:06
…ncy frontier

minimize_usage_cost takes latency_bound_ms: pairs whose chain exceeds it
are ruled out, so the plan is the cheapest at least that fast (exact,
since CPU is elastic). Sweeping it traces each method's Pareto frontier;
it is not an SLA. Test: matches brute force under four bounds, and looser
bounds never cost more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
…algorithm

Version 1 minimizes cost by use and reports latency, with an optional bound
that traces the frontier; version 2 requires the batch latency, from the
job placement, to be at most an SLA. The placement algorithm is back: with
elastic CPU it has the closed form (longest chain) the code uses, which
keeps both versions exact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
zzylol added a commit that referenced this pull request Oct 8, 2026
…et by default

- The runner prices every plan by use (usage::usage_cost): w_cpu * AUC(CPU)
  + w_mem * AUC(memory), CPU elastic, latency the longest chain, reported.
- ASAP is milp::minimize_usage_cost over every RQE; PerQuery the same over
  each RQE's own candidates (separate copies via `allowed`, no sharing);
  AutoSketch's plan is priced the same way.
- No SLA grid. Each method's cost-latency frontier: ASAP and PerQuery are
  solved unbounded and for 12 bounds log-spaced from the tightest feasible
  one to the unbounded latency, plus AutoSketch's latency.
- The synthetic grid is the mixed template set: shared r in {1, 8} and
  metrics m in {1, 8, 16} (50, 92, 400, 800 RQEs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
zzylol added a commit that referenced this pull request Oct 8, 2026
…measured benchmark

- Four workloads of the mixed template set (50, 92 with r = 8, 400 with
  m = 8, 800 with m = 16 RQEs), cost by use (#188), each method's cheapest
  plan and ASAP's and PerQuery's cost-latency frontiers (12 bounds plus
  AutoSketch's latency), CPU-only and Fargate weights, --runs 3, one node
  per workload. No RQE dropped, no sanity violation.
- AutoSketch's benchmark time is measured: approxbench's accuracy run (1e8
  items, exact baseline, scoring) once per distinct probed config and
  shape, serially on idle clnode155 (21-37 s each), charged once per
  probed (metric, config): 212, 1697 and 3394 s for m = 1, 8, 16.
- plot_autosketch_vs_asap_synthetic.py: fig_frontier.png (cost vs. query
  latency, every point labeled), fig_planning_time.png (AutoSketch as
  search + measured benchmark; 60 s per probe only as a labeled
  reference), summary_synthetic.md. The SLA-era figures, the dashboard
  results and plot_autosketch_vs_asap_workloads.py are removed.
- README: the cost model, version 1, how to reproduce, and the headline
  numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
zzylol added a commit that referenced this pull request Oct 8, 2026
…et by default

- The runner prices every plan by use (usage::usage_cost): w_cpu * AUC(CPU)
  + w_mem * AUC(memory), CPU elastic, latency the longest chain, reported.
- ASAP is milp::minimize_usage_cost over every RQE; PerQuery the same over
  each RQE's own candidates (separate copies via `allowed`, no sharing);
  AutoSketch's plan is priced the same way.
- No SLA grid. Each method's cost-latency frontier: ASAP and PerQuery are
  solved unbounded and for 12 bounds log-spaced from the tightest feasible
  one to the unbounded latency, plus AutoSketch's latency.
- The synthetic grid is the mixed template set: shared r in {1, 8} and
  metrics m in {1, 8, 16} (50, 92, 400, 800 RQEs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
zzylol added a commit that referenced this pull request Oct 8, 2026
…measured benchmark

- Four workloads of the mixed template set (50, 92 with r = 8, 400 with
  m = 8, 800 with m = 16 RQEs), cost by use (#188), each method's cheapest
  plan and ASAP's and PerQuery's cost-latency frontiers (12 bounds plus
  AutoSketch's latency), CPU-only and Fargate weights, --runs 3, one node
  per workload. No RQE dropped, no sanity violation.
- AutoSketch's benchmark time is measured: approxbench's accuracy run (1e8
  items, exact baseline, scoring) once per distinct probed config and
  shape, serially on idle clnode155 (21-37 s each), charged once per
  probed (metric, config): 212, 1697 and 3394 s for m = 1, 8, 16.
- plot_autosketch_vs_asap_synthetic.py: fig_frontier.png (cost vs. query
  latency, every point labeled), fig_planning_time.png (AutoSketch as
  search + measured benchmark; 60 s per probe only as a labeled
  reference), summary_synthetic.md. The SLA-era figures, the dashboard
  results and plot_autosketch_vs_asap_workloads.py are removed.
- README: the cost model, version 1, how to reproduce, and the headline
  numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
@zzylol zzylol changed the title rqe-optimizer: minimize cost billed by use; batch latency reported rqe-optimizer: MILP on cost by use, with batch latency (reported, or as an SLA) Oct 9, 2026
Comment thread docs/rqe_sketch_deployment_v1.md
Comment thread docs/rqe_sketch_deployment_v1.md Outdated

| Part | When | CPU-seconds | Mean vCPUs |
|---|---|---|---|
| Ingest (the precompute) | continuously, as samples arrive | — | `ρ_D = λ_D · (x_D / y_D) · c_ins` |

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.

should rho_D be divided by scrape interval for "mean vCPUs"?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

No: the scrape interval is already inside λ_D = card(series) / scrape interval (samples per second). ρ_D = λ_D (samples/s) × x/y (windows per sample) × c_ins (CPU-seconds per insert) is already CPU-seconds per second. The definitions table now states λ_D's definition, and the explanation spells out the units (5aa3932).

Every mean vCPU is an average rate over the same period (whole
hyperperiods), so the parts add; ingest is already a rate (lambda_D =
series / scrape interval), and only compaction and queries are divided by
their period. AUC(CPU) is written as three sums to make that plain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
@zzylol
zzylol merged commit 1270b3c into main Oct 9, 2026
2 checks passed
@zzylol
zzylol deleted the batch-sla branch October 9, 2026 18:05
zzylol added a commit that referenced this pull request Oct 9, 2026
…et by default

- The runner prices every plan by use (usage::usage_cost): w_cpu * AUC(CPU)
  + w_mem * AUC(memory), CPU elastic, latency the longest chain, reported.
- ASAP is milp::minimize_usage_cost over every RQE; PerQuery the same over
  each RQE's own candidates (separate copies via `allowed`, no sharing);
  AutoSketch's plan is priced the same way.
- No SLA grid. Each method's cost-latency frontier: ASAP and PerQuery are
  solved unbounded and for 12 bounds log-spaced from the tightest feasible
  one to the unbounded latency, plus AutoSketch's latency.
- The synthetic grid is the mixed template set: shared r in {1, 8} and
  metrics m in {1, 8, 16} (50, 92, 400, 800 RQEs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
zzylol added a commit that referenced this pull request Oct 9, 2026
…measured benchmark

- Four workloads of the mixed template set (50, 92 with r = 8, 400 with
  m = 8, 800 with m = 16 RQEs), cost by use (#188), each method's cheapest
  plan and ASAP's and PerQuery's cost-latency frontiers (12 bounds plus
  AutoSketch's latency), CPU-only and Fargate weights, --runs 3, one node
  per workload. No RQE dropped, no sanity violation.
- AutoSketch's benchmark time is measured: approxbench's accuracy run (1e8
  items, exact baseline, scoring) once per distinct probed config and
  shape, serially on idle clnode155 (21-37 s each), charged once per
  probed (metric, config): 212, 1697 and 3394 s for m = 1, 8, 16.
- plot_autosketch_vs_asap_synthetic.py: fig_frontier.png (cost vs. query
  latency, every point labeled), fig_planning_time.png (AutoSketch as
  search + measured benchmark; 60 s per probe only as a labeled
  reference), summary_synthetic.md. The SLA-era figures, the dashboard
  results and plot_autosketch_vs_asap_workloads.py are removed.
- README: the cost model, version 1, how to reproduce, and the headline
  numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis
zzylol added a commit that referenced this pull request Oct 9, 2026
…ontier and SLA versions) (#138)

* rqe-optimizer: evaluate AutoSketch vs ASAP on the synthetic and trace workloads

ProjectASAP/ASAPQuery#777 (paper §6.3), consolidating #138, #139 and #141.

- rqe-optimizer/examples/autosketch_vs_asap.rs (traces and synthetic): ASAP
  (milp::minimize), PerQuery-CostAware and AutoSketch-Adapted. Costs and
  accuracy come from --saturation-dir, as the planner reads them:
  SaturationCurves::accuracy for ASAP (merge curves for KLL and top-k,
  #179), autosketch_accuracy for AutoSketch, and the one-study cost table
  (#178). Each run is scored by analytical_cost_model::score at #777's two
  weight settings and the SLA grid.
- scripts/run_autosketch_vs_asap.sh and plot_autosketch_vs_asap.py: the
  trace workloads alibaba_v2022 and google_2011. boom is left out for now.
- scripts/export_autosketch_eval_table.py --synthetic: one workload-only
  table per grid point, plus plan.tsv. The data constants come from
  study_saturation's COST_*. The traces path is unchanged from main.
- scripts/run_autosketch_vs_asap_synthetic.sh and
  plot_autosketch_vs_asap_synthetic.py: run the synthetic grid, then plot.
- scripts/profiling_time.py and the results README: ASAP's one-time
  profiling time, and how to reproduce.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* rqe-optimizer: trace key queries keep one accumulator per key; report the accuracy source

From review on #138:
- A traces key query (sum by key) keeps one exact accumulator per key: its
  groups are the window's keys, not the table's one sketch. A stream's
  card(g) is the largest over its RQEs.
- AutoSketch's benchmark lower bound uses one query of one instance, not
  the stream's q_r of them.
- --weights that names none of the weight settings is an error.
- The chosen report lists each RQE's accuracy source (#180's
  accuracy_with_source).
- Drop a duplicated BoomTest; capability_of's comment matches the code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: one accuracy level, p95; plots join one RQE set and charge AutoSketch's benchmark

- One accuracy level for every workload, synthetic and traces: 95% in
  each family's metric (rank, relative value and relative error at most
  0.05; top-k precision at least 0.95). The strictness dimension is gone.
- fig_objective_vs_latency joins only points over one RQE set (solid for
  the full set, dashed for the subset tight SLAs keep).
- fig_planning_time adds AutoSketch's charged benchmark time (lower bound
  and 60 s per probe), as #777 section 7 counts it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: summaries show Σ window/slide; synthetic summary to its own file

AutoSketch-Adapted's ingest cost is window / slide overlapping sketches per
deployment (window = the query's lookback), so the column explains its gap
to ASAP. The synthetic and trace scripts both wrote summary.md into one
results directory; the synthetic one is now summary_synthetic.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: RQEs carry their top-k k (#185)

Raqe now has topk_k. The tables name it only in the query id (topk32_...),
so the runner reads it there and stops on a top-k query that names none.
On the p95 synthetic and trace tables every top-k query is k = 32, and the
plans are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: p95 results for the synthetic grid and the traces

Runs on clnode155 over the asap_sketchlib 0.3.0 study (#174, #178–#186):
four synthetic workloads and alibaba_v2022 / google_2011, raw JSON,
summaries and figures. The README gives the no-SLA headline, including
Σ window/slide behind AutoSketch-Adapted's gap. profiling-time.json is
refilled from the study's raw records (0.77 h; the K = 1e4 column refill
of #186 is its own run).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: figures and tables give each method's absolute cost

Cost figures label every bar and point with its value; the summaries and
the results README list each method's objective instead of its ratio to
ASAP. The by-dimension figure's legend moves above the panels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: metrics dimension, one dashboard per metric (21 · m RQEs)

Shared replicas on one metric stop adding RQEs past r = 8 (52 at r = 8,
57 at r = 64), so the grid keeps shared r ∈ {1, 8} and adds metrics
m ∈ {1, 8, 16}: copy i of the template set reads its own metric data_i,
so nothing is shared across copies and RQEs grow as 21 · m (168, 336).
The planning-time figure plots this dimension. The m = 8 and 16 runs are
added; the r = 64 result is removed. Existing tables are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: AutoSketch benchmarks each config once per metric

Synthetic tables name the metric each RQE reads (data, or data_i in the
metrics dimension), and AutoSketch-Adapted's benchmark time counts a
probed config once per metric, on that metric's data: 540, 4320 and
8640 s (60 s per probe) for m = 1, 8, 16. Trace tables name none and
read one metric per dataset, as before. All five synthetic workloads are
rerun with the current runner on four nodes; objectives are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: cost vs. total estimated latency for every workload

One column per workload (five synthetic, two traces), one row per weight
setting, one line per method across the SLA grid, each point labeled with
its cost. Total latency is the sum of the RQEs' estimated latencies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: finer SLA grid, {0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10} ms and none

Checks whether AutoSketch-Adapted's memory objective makes it miss an
SLA: it never does. Its plans never merge, so each RQE's latency is within
1.4% of the lowest any deployment reaches (equal for quantile, exact and
trace RQEs), and RQEs no method can meet are excluded for all methods.
All workloads rerun on four nodes; figures and summaries regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: AutoSketch probe list and measured benchmark time; traces with 6h/24h windows

- The runner lists AutoSketch-Adapted's distinct probed (metric, config)
  pairs with the data shape each is benchmarked on, and drops the
  benchmark-time lower bound. scripts/autosketch_benchmark_time.py runs
  each probe's approxbench accuracy benchmark (1e8 items, exact baseline
  and scoring) and times it, as AutoSketch benchmarks probed configs.
- Trace streams with more keys than samples per second are left out and
  listed (rounding their rate up to their key count inflated every
  method's cost).
- The trace table is regenerated from ASAPQuery #812's skew summary
  (6h and 24h windows, a day of Alibaba).
- Plots: one line per method over the full RQE set; AutoSketch's planning
  time with its measured benchmark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: cost by use (sketch-bench #188); Pareto frontier sweep; mixed set by default

- The runner prices every plan by use (usage::usage_cost): w_cpu * AUC(CPU)
  + w_mem * AUC(memory), CPU elastic, latency the longest chain, reported.
- ASAP is milp::minimize_usage_cost over every RQE; PerQuery the same over
  each RQE's own candidates (separate copies via `allowed`, no sharing);
  AutoSketch's plan is priced the same way.
- No SLA grid. Each method's cost-latency frontier: ASAP and PerQuery are
  solved unbounded and for 12 bounds log-spaced from the tightest feasible
  one to the unbounded latency, plus AutoSketch's latency.
- The synthetic grid is the mixed template set: shared r in {1, 8} and
  metrics m in {1, 8, 16} (50, 92, 400, 800 RQEs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: version 1 (no SLA) results on the mixed set, with AutoSketch's measured benchmark

- Four workloads of the mixed template set (50, 92 with r = 8, 400 with
  m = 8, 800 with m = 16 RQEs), cost by use (#188), each method's cheapest
  plan and ASAP's and PerQuery's cost-latency frontiers (12 bounds plus
  AutoSketch's latency), CPU-only and Fargate weights, --runs 3, one node
  per workload. No RQE dropped, no sanity violation.
- AutoSketch's benchmark time is measured: approxbench's accuracy run (1e8
  items, exact baseline, scoring) once per distinct probed config and
  shape, serially on idle clnode155 (21-37 s each), charged once per
  probed (metric, config): 212, 1697 and 3394 s for m = 1, 8, 16.
- plot_autosketch_vs_asap_synthetic.py: fig_frontier.png (cost vs. query
  latency, every point labeled), fig_planning_time.png (AutoSketch as
  search + measured benchmark; 60 s per probe only as a labeled
  reference), summary_synthetic.md. The SLA-era figures, the dashboard
  results and plot_autosketch_vs_asap_workloads.py are removed.
- README: the cost model, version 1, how to reproduce, and the headline
  numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: version 2, a batch latency SLA, on the synthetic mixed set

The runner adds version 2 of the evaluation beside version 1 (no latency
constraint and the frontiers, unchanged in `results`): at each SLA of a
grid (default 100, 300, 1000, 3000, 10000 ms; --slas-ms overrides), ASAP
and PerQuery plan the cheapest plan whose batch latency (the longest
chain) is at most the SLA, via minimize_usage_cost's latency bound, which
is exact with elastic CPU. An SLA below a method's tightest feasible
bound gives an infeasible record. AutoSketch's one plan is recorded at
each SLA with meets_sla. Records go to `sla_results`, with sanity checks
that every plan meets its SLA and that ASAP costs no more than PerQuery.

Results on clnode109 (--runs 3) for the mixed set, r = 8 and m = 8, 16:
no drops, no sanity violations; the tightest feasible SLA is 92 ms, and
AutoSketch (latency 1011 ms) meets only 3000 and 10000 ms. AutoSketch's
planning time is search plus its measured benchmark
(scripts/autosketch_benchmark_time.py: approxbench accuracy runs at 1e8
items, 20-33 s each, serial and alone on the node): 197 s at m = 1,
3159 s at m = 16. scripts/plot_autosketch_vs_asap_sla.py draws
fig_cost_vs_sla.png and summary_sla.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: remove the old trace results and figures

They came from the earlier model (per-RQE SLA over a µs grid, mean-CPU
cost); the traces are to be rerun on cost by use with both latency
versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: trim the PR to what it needs

- Result JSONs without per-RQE choices (`chosen`): the figures and
  summaries don't read them, and they were nearly all of the 2.9M lines;
  rerun the runner for them.
- Machine files folded into the READMEs (all Intel Xeon E5-2683 v3,
  56 cores); the synthetic run script no longer writes them.
- The SLA-era trace scripts (plot_autosketch_vs_asap.py,
  run_autosketch_vs_asap.sh) are removed; the traces are to be rerun on
  cost by use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: keep only what the three figures need

The PR's results are the frontier (version 1), cost vs. SLA (version 2)
and planning time on the synthetic mixed set. The trace table goes back
to the base version (the traces are to be rerun on cost by use, with
their new table), and the ASAP profiling-time script and data, which no
figure uses, are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: commit the inputs of the three figures

rqe-optimizer/results/autosketch-vs-asap-inputs/ holds what the figures
were computed from: the sketch-bench study on asap_sketchlib 0.3.0 (the
cost table, sketches and exact aggregations, and the accuracy curves the
runner reads as --saturation-dir) and the synthetic mixed-set tables with
plan.tsv. The READMEs point the reproduce steps at them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

* eval: the raw approxbench records behind the figures' study

rqe-optimizer/results/autosketch-vs-asap-inputs/raw/ holds the gzipped
approxbench records (920 KB) that ../saturation/ was reduced from, with a
README mapping each file to its machine, arguments, record count, run time
and output. Rerunning them is 0.77 h of machine time over 5 machines in
parallel (about 20-30 minutes of wall time).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhcWJExZcmVqS6r6rEtjis

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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