Skip to content

chore: use pharmsol from main - #333

Draft
mhovd wants to merge 2 commits into
mainfrom
chore/pharmsol-main
Draft

mhovd wants to merge 2 commits into
mainfrom
chore/pharmsol-main

Conversation

@mhovd

@mhovd mhovd commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

Points PMcore at pharmsol main (e684464, ahead of 0.29.4) to measure the migration cost and the performance impact. Because this is a git dependency it can't be published as-is; it's meant to be merged once pharmsol cuts a release.

Size of the change

24 files, +133 / −147. Most of it is mechanical.

Library (src/, ~9 files)

  • simulate_subject_dense → simulate; bind_error_models → validate_error_models; EquationTypes no longer re-exported.
  • AssayErrorModels is now a BTreeMap<OutputLabel, _> (pharmsol#392):
    • error_optim: gamma_delta is indexed by enumeration position instead of the output index.
    • cycles.csv: closures take &OutputLabel.
    • validate_nonparametric_error_models: finds the error model for each observed output by resolving its label, instead of going through the removed bound/dense models. The outeq_<N> fallback (resolve_output_index) is deleted to match pharmsol.
  • Prediction::outeq() returns &OutputLabel:
    • NPPredictionRow::outeq() now returns &OutputLabel (public API change).
    • BestDose turns the label back into an index, the same way it already handles observations.

Examples / benches / tests (~15 files)
pharmsol#383 removed the 1 ↔ outeq_1 / input_1 aliasing; labels now have to match exactly. Every model changes outeq_N/input_N → N, e.g. outputs: [1], infusion[1], y[1], "1" in AssayErrorModels::add. Downstream users with prefixed names will hit this at runtime, not at compile time.

Behaviour changes worth noting

  1. Error-model factor optimisation now runs for label-added models. Before, AssayErrorModels::add("outeq_1", …) stored the model where iter() couldn't see it, so NPAG/NPOD skipped gamma/lambda optimisation and cycles.csv had no gamlam.* column. Both now work. (The pharmsol#392 commit message describes this bug.)
  2. pred.csv outeq column now holds the data label (1) instead of the dense 0-based slot (0).
  3. cycles.csv header is gamlam.<label> (e.g. gamlam.1).

Numerical check (bimodal_ke example, NPAG)

main this PR
Cycles to convergence 287 320
Final −2LL −429.20383 −429.20387
Trajectory — identical to ~1e-12 through cycle 49
Final support points / weights — identical (weights agree to ~1e-13)

The extra cycles come from the error-model optimisation that now runs. It does two extra Ψ evaluations per cycle, and with lambda = 0 those are no-ops.

Performance (cargo bench --bench bimodal_ke, Criterion, same machine, baseline = main)

Bench main this PR change
bimodal_ke_npag 3.093 s 2.919 s −5.6 %
bimodal_ke_npod 1.376 s 0.993 s −27.8 %
bimodal_ke_postprob 621 ms 456 ms −26.6 %

NPAG improves less because it now does more work: ~11 % more cycles plus the extra Ψ evaluations. NPOD and postprob are closer to the raw simulator gain, about 27 %.

Testing

  • cargo test --all-features: 84 passed, 0 failed.
  • cargo clippy --all-targets --all-features: no new warnings (the 2 that remain are on main too).
  • Smoke-ran every example. meta, drusano (solver stiffness) and vanco (label mismatch) fail identically on main, so they aren't regressions. iov/vanco_sde were capped at 90 s with no errors.

Track pharmsol main (e684464) and adapt to its breaking changes:

- simulate_subject_dense -> simulate; bind_error_models -> validate_error_models
- EquationTypes removed from the prelude re-exports
- AssayErrorModels is keyed by OutputLabel; error optimisation, cycle CSV
  output and nonparametric validation now work with labels
- Prediction::outeq() returns &OutputLabel; NPPredictionRow::outeq follows
- Output/route labels match exactly (no outeq_N/input_N alias), so examples,
  benches and tests use numeric labels that match the data
Copilot AI balanced review requested due to automatic review settings October 28, 2026 08:47
@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

ProjectPMcore
Branchchore/pharmsol-main
Testbedmhovd-pgx
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
bimodal_ke_npag📈 view plot
🚷 view threshold
3,539.70 ms
(-18.54%)Baseline: 4,345.58 ms
6,448.85 ms
(54.89%)
bimodal_ke_npod📈 view plot
🚷 view threshold
802.24 ms
(-38.79%)Baseline: 1,310.54 ms
2,051.75 ms
(39.10%)
bimodal_ke_postprob📈 view plot
🚷 view threshold
343.06 ms
(-12.01%)Baseline: 389.89 ms
836.87 ms
(40.99%)
🐰 View full continuous benchmarking report in Bencher

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.

🟡 Changes recommended

The upgrade makes residual error models label-keyed, but ParametricBuilder still stores them under dense indices, leaving constructed problems without models under their actual output labels.

1 open issue
What changed in this PR

Migrates PMcore to pharmsol main to assess API migration costs and performance ahead of a published release.

Changes:

  • Updates simulation calls and error-model validation for the new APIs.
  • Adapts error-factor optimization, prediction output, and cycle logs to label-keyed models.
  • Replaces prefixed input/output aliases with exact numeric labels in examples, benchmarks, and tests.
File Description
tests/​bestdose_tests.rs Migrates test models to exact numeric labels.
src/​lib.rs Removes the EquationTypes re-export.
src/​iov/​optimizer.rs Uses the renamed simulation API.
src/​estimation/​problem.rs Validates assay models using exact output labels.
src/​estimation/​nonparametric/​predictions.rs Preserves output labels in prediction rows.
src/​estimation/​nonparametric/​cycles.rs Adapts cycle logging to label-keyed models.
src/​bestdose/​cost.rs Updates simulation calls and converts prediction labels to numeric keys.
src/​algorithms/​nonparametric/​error_optim.rs Indexes optimization steps by model enumeration position.
src/​algorithms/​mod.rs Updates simulation calls and label debug output.
examples/​vanco.rs Uses the renamed simulation API.
examples/​vanco_sde/​main.rs Migrates routes, outputs, and assay labels.
examples/​two_eq_lag/​main.rs Migrates input, lag, output, and assay labels.
examples/​theophylline/​main.rs Migrates route, output, and assay labels.
examples/​new_iov/​main.rs Migrates route, output, and assay labels.
examples/​neely/​main.rs Migrates multiple outputs and assay labels.
examples/​meta/​main.rs Migrates infusion, output, and assay labels.
examples/​iov/​main.rs Migrates route, output, and assay labels.
examples/​drusano/​main.rs Migrates multiple inputs, outputs, and assay labels.
examples/​chain_algorithms.rs Migrates the chained-estimation example’s labels.
examples/​bimodal_ke/​main.rs Migrates the benchmark example’s labels.
examples/​bimodal_ke_backend_compare.rs Aligns labels across DSL, legacy, and macro models.
examples/​bestdose/​main.rs Updates DSL labels and their explanatory comment.
Cargo.toml Points pharmsol at its Git main branch.
benches/​bimodal_ke.rs Migrates model and assay labels for all benchmark cases.

Review effort: Balanced

Comment thread Cargo.toml Outdated
] }
faer = "0.24.0"
pharmsol = "0.29.2"
pharmsol = { git = "https://github.com/LAPKB/pharmsol.git", branch = "main" }
@mhovd
mhovd marked this pull request as draft October 29, 2026 08:20

This branch has not been deployed

No deployments
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