Skip to content

Commit e674617

Browse files
docs(optimizer): document atomic_costs.rs and the --atomic-costs workflow
Updates the v1 implementation plan for #549/#524: File Map, Phase 2f, 3c status, and a runbook for generating sketch-bench's table and feeding it to candidate-gen-dump/asap-optimizer-cli. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent c8e59da commit e674617

1 file changed

Lines changed: 74 additions & 7 deletions

File tree

.design_docs/optimizer-v1-implementation-plan.md

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ asap-planner-rs/src/optimizer/
8080
├── candidate_gen.rs enumerate candidate configs per AQE [Phase 2b, done]
8181
├── cost_model.rs ingest/query cost formulas [Phase 2c, done]
8282
├── greedy.rs per-AQE greedy assignment [Phase 2e, done]
83+
├── atomic_costs.rs (sketch_type, params) → AtomicCosts, from
84+
│ sketch-bench's exported table [Phase 2f, done, #549]
8385
8486
│ ── TO BE ADDED ──
8587
├── feasibility.rs Feasible(a,g) predicate — only meaningful once configs
@@ -222,6 +224,33 @@ placeholder value applied uniformly to every candidate — see open TODO below.
222224
a real `aggregation_id`, emits one `QueryConfig` per original query string, with
223225
`num_aggregates_to_retain` from `retention_count_for_assignment()`.
224226

227+
#### 2f — `atomic_costs.rs` (done, issue #549, carved out of #524)
228+
229+
`greedy.rs` no longer applies one global `AtomicCosts` to every candidate. Per candidate:
230+
231+
```rust
232+
pub fn resolve_atomic_costs(table: &AtomicCostTable, agg_type: AggregationType,
233+
params: &HashMap<String, Value>) -> Option<AtomicCosts>
234+
```
235+
236+
- `CountMinSketch` / `HLL` / `DatasketchesKLL`: translated to sketch-bench's `(algorithm, params)`
237+
key (`sketch_bench_key()` — field names are duplicated from `candidate_gen.rs`'s `param_grid()`,
238+
not derived from it, so a rename on either side without the other panics loudly instead of
239+
silently mismatching) and looked up by exact key in the table. No match for that exact param
240+
point → `None`, candidate dropped.
241+
- Every other `AggregationType` (trivial accumulators like `Sum`/`MinMax`, and sketches
242+
sketch-bench doesn't wrap yet like `CountMinSketchWithHeap`/`HydraKLL`) → `Some(AtomicCosts::default())`,
243+
the pre-#549 flat stub, with a `tracing::warn!`. **This means costs for those families are still
244+
param-invariant** (e.g. `CountMinSketchWithHeap` currently costs identically regardless of
245+
`depth`/`width`/`heapsize` — see #524 for the analytic memory bound that's supposed to replace
246+
the stub for it).
247+
- No `subtract_cpu_secs` in the table (asap_sketchlib has no `subtract` yetasap_sketchlib#69) —
248+
always comes from the stub constant regardless of family.
249+
250+
`AtomicCostEntry`/`AtomicCostTable` are a deliberate duplicate of sketch-bench's
251+
`aqpbm_core::atomic_costs` types (same reasoning as the field-name duplication above: sketch-bench's
252+
schema is still actively churning, so no shared crate dependency yetsee PR #547's discussion).
253+
225254
---
226255

227256
### 🔲 Phase 3Full MIP with Cross-AQE Sharing
@@ -236,11 +265,18 @@ Add `run_mip_pipeline()` to `pipeline.rs`.
236265
Relax `labels_compatible()` in `asap_types::capability_matching` at line 86 (TODO comment already there).
237266
Allow a config with labelsquery labels to serve that AQE. This is what enables cross-AQE sharing.
238267

239-
#### 3csketch-bench cardinality sweep
268+
#### 3creal `AtomicCosts` from sketch-bench
240269

241-
- Add cardinality to sweep grids in `sketch-bench`
242-
- Add `CountMinSketchWithHeap` wrapper in `sketch-cli/src/wrappers/`
243-
- Plug real `AtomicCosts` values into cost model
270+
-Plug real `AtomicCosts` values into cost modeldone for CMS/HLL/KLL, see 2f above and
271+
"Running with real sketch-bench costs" below.
272+
-Add `CountMinSketchWithHeap` wrapper in sketch-bench, so it stops always costing at the flat
273+
stub. Its memory is meant to be an analytic bound (`heap_size · avg_key_size`), not a
274+
sketch-bench lookup at all, per #524that formula still needs implementing in
275+
`atomic_costs.rs`/`cost_model.rs`.
276+
- ~~Add cardinality to sweep grids in `sketch-bench`~~ — decided unnecessary: CPU/mem costs for
277+
CMS/HLL/KLL are functions of structural params (depth×width, lg_k, K), not cardinality: only
278+
`CountMinSketchWithHeap` is cardinality-dependent, and that's the analytic-bound case above, not
279+
a sketch-bench sweep axis.
244280

245281
#### 3dAccuracy constraint
246282

@@ -265,14 +301,45 @@ standalone `asap-optimizer-cli` binary (`asap-planner-rs/src/bin/optimizer_cli.r
265301
```
266302
cargo run -p asap_planner --bin asap-optimizer-cli -- \
267303
--input_config <path/to/workload.yaml> \
268-
--prometheus_scrape_interval 60 \
269-
[--rho 1.0]
304+
--data-ingestion-interval-ms 60000 \
305+
[--rho 1.0] \
306+
[--atomic-costs <path/to/atomic_costs.json>]
270307
```
271308

272309
Takes the same `ControllerConfig` YAML format as `asap-planner --input_config`
273310
(with a `metrics:` hints block for label schemano live Prometheus needed).
274311
Prints deployed streaming configs and query configs to stdout. `--rho` is the
275-
placeholder arrival rate (see TODOs belownot real yet).
312+
placeholder arrival rate (see TODOs belownot real yet). `--atomic-costs` is
313+
optional; omit it and every candidate costs at the flat stub, same as before #549.
314+
315+
### Running with real sketch-bench costs
316+
317+
**1. Generate the table, in the `sketch-bench` repo:**
318+
319+
```
320+
./scripts/export_atomic_costs.sh
321+
# → out/atomic_costs.json — one row per (sketch, params) point in ASAPQuery's grid,
322+
# built by looping candidate_gen.rs's CMS_DEPTHS×CMS_WIDTHS/HLL_PRECISIONS/KLL_KS
323+
# through `approxbench sketchbench --flat` and reducing with `approxbench atomic-costs`.
324+
```
325+
326+
**2. Feed it to ASAPQuery**, either binary:
327+
328+
```
329+
# See what each candidate would cost, before selection:
330+
cargo run -p asap_planner --bin candidate-gen-dump -- \
331+
--input_config workload.yaml --data-ingestion-interval-ms 60000 \
332+
--atomic-costs path/to/atomic_costs.json
333+
334+
# Run the actual optimizer:
335+
cargo run -p asap_planner --bin asap-optimizer-cli -- \
336+
--input_config workload.yaml --data-ingestion-interval-ms 60000 \
337+
--atomic-costs path/to/atomic_costs.json
338+
```
339+
340+
`candidate-gen-dump`'s output labels each params row `[real]` (resolved from the table) or
341+
`[stub]` (fell through to `AtomicCosts::default()` — either an unbenchmarked family, or a
342+
benchmarked family's param point missing from the table).
276343
277344
Wire-in decision (deferred): once Phase 3 (MIP + feasibility + label superset
278345
matching) lands, swap `Controller::generate()` to call `run_mip_pipeline()`

0 commit comments

Comments
 (0)