Skip to content

Releases: seantalts/stanli

stanli 0.25.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 02:36
Immutable release. Only release title and notes can be modified.
bc66380

What's Changed

  • Preserve Windows exception tables in embedded compiler builds by @seantalts in #503
  • Make triangular-solve adjoint ownership explicit by @seantalts in #504
  • Align macOS host dependencies and remove dependency warning patches by @seantalts in #505
  • PR gate waits for the Windows compiler jobs; changelog written at release by @seantalts in #500
  • Benchmarks page: one TL;DR, every number once by @seantalts in #506
  • Memoize data-controlled loops during frame recording by @seantalts in #507
  • Stop in-place writes from changing values a retained loop has already read by @seantalts in #508
  • Fix the live CI flakes: timeouts, fetch retries, decode gate, baseline fetch by @seantalts in #510
  • Make write_array and expression-effect checks linear in model size by @seantalts in #512
  • Check the embedded stanc object at configure time and key it by its inputs by @seantalts in #511
  • Lower deeply nested expressions on a large stack instead of crashing by @seantalts in #514
  • Make generated-quantities loops and branches linear in prep time by @seantalts in #513
  • Skip the deep-expression test under sanitizers by @seantalts in #515
  • R: report compiled code from another install instead of a missing routine by @seantalts in #517
  • Name every missing data variable in one error by @seantalts in #518
  • Validate sampling and optimize arguments with clear messages by @seantalts in #519
  • Show why proposals are rejected and print the same sampling warnings everywhere by @seantalts in #520
  • Plain user-facing compile and data errors, with stanc3 warnings and the model file name by @seantalts in #521
  • Lower csr_matrix_times_vector in linear time by @seantalts in #509
  • Accept omitted zero-size data and send runtime output through R and Python stdout by @seantalts in #522
  • Build repeated structured-loop frames from templates and lower write_array alongside log_prob by @seantalts in #524
  • Fix main build: pass omitted data to the write_array lowering after log_prob by @seantalts in #525
  • Fix int reads of 2-D int arrays written by rows (#523); container grid, OncoBayes2 corpus, compiled GQ by @seantalts in #527
  • Trim the container write/read grid to 66 models by @seantalts in #528
  • Fix Windows stack overflows and x87 precision on helper threads by @seantalts in #529
  • Release 0.25.0 by @seantalts in #530

Full Changelog: v0.24.0...v0.25.0

stanli 0.24.0

Choose a tag to compare

@seantalts seantalts released this 25 Oct 23:01
Immutable release. Only release title and notes can be modified.
0e32ea3

Stanli 0.24.0 adds RStan-style sampling and variational inference, improves R and webR integration, and fixes Stan compatibility issues found in rbmi and OncoBayes2 models. The macOS arm64 packages also prepare large ctsem models faster.

R and webR

  • Run RStan-style code on Stanli. as_stanmodel() wraps Stan code, a .stan file, or an RStan stanmodel. Pass it to rstan::sampling() or rstan::vb() to use Stanli and receive a stanli_stanfit. Sampling supports RStan's initialization forms, parameter selection, chain IDs, sampler controls, and algorithm = "Fixed_param". Unsupported arguments produce explicit errors. rstan::optimizing() remains unsupported because its Jacobian convention differs; use optimize_model() with its documented semantics. Packages with their own precompiled models, such as rstanarm, are outside this interface. (#499)
  • Choose chain IDs. sample_model(chain_id = ...) assigns consecutive IDs and their random streams. With the same seed, four chains sampled together reproduce four separate one-chain runs with IDs 1 through 4. With Pathfinder initialization, all chains instead share one Pathfinder run seeded by the first chain's ID. (#497)
  • Pass higher-dimensional data. stanli_model() accepts R arrays of any rank, including zero-length dimensions, and unnamed lists become arrays. Lists of matrices and vectors now map to their Stan array types. (#497)
  • Use simpler interoperability helpers. parameter_names() lists declared parameters, with scalars = TRUE for individual elements. unconstrain(ignore_unknown = TRUE) ignores extra entries in initialization lists. as_stanfit(plain = TRUE) returns an exact stanfit class for clients that require it; it retains draws but drops the live model. (#497, #499)
  • Fit conversion and permuted extraction no longer change or depend on the caller's R random stream. Converted fits also tell brms that they hold a compiled model, avoiding unnecessary RStan recompilation for density evaluation. brms operations that refresh a fit still need a backend that samples with Stanli. (#497)

Stan compatibility and correctness

  • Added sort_asc, sort_desc, sort_indices_asc, sort_indices_desc, and rank for integer and real arrays, vectors, and row vectors. Value sorting carries gradients and rejects NaN as Stan Math does. (#497)
  • Supported model sizes and slices computed by counter-based while loops, including forms used in rbmi's MMRM model. (#498)
  • Allowed data-size functions that call print() or reject(), including OncoBayes2's array[M] vector[max_int(Nc)] w. They run once during data loading; random-number-generating size functions remain unsupported. (#498)
  • Fixed integer division promoted to real. Expressions such as lower = -1 / (n - 1) now preserve Stan's integer division before conversion to a real value. Previously they could produce incorrect log densities. (#498)

Performance and evidence

  • The macOS arm64 wheel and R runtime use a newer Apple Clang toolchain. On the measured 4,000-row, 580-parameter ctsem model, time to the first gradient fell from about 22 s to 13 s; warm gradients remained about 0.35 s. Three ordinary brms, rethinking, and cognitive models were unchanged or slightly faster in the measured phases. The deployment target remains macOS 11.0. (#501)
  • The brms comparison now reports eight-seed reruns of the twelve models with one-sided convergence failures in the original run: 29 of 96 Stanli fits and 32 of 96 CmdStanR fits exceeded R-hat 1.01. No model consistently failed with one backend while converging with the other. Raw runs and the reproducible seed setting are included in the report. (#496)

Python, npm, and the R package/runtime are versioned together at 0.24.0. After upgrading the R package, run stanli::stanli_install() to fetch its matching runtime.

Known integration issues

  • Windows x86_64 development builds with MSYS2 Clang have failures in three sort/rank rejection tests. The prebuilt Windows packages use GCC and pass those tests. (Development-build failure)
  • The separately maintained stanr package's pinned vendoring script has not caught up with the current runtime sources. Its compatibility job is nonblocking and fails with emit_message body not found, as it did in 0.23.2; this release does not claim downstream stanr compatibility. (Compatibility checks)

Changelog · All changes since 0.23.2

stanli 0.23.2

Choose a tag to compare

@github-actions github-actions released this 22 Oct 22:37
Immutable release. Only release title and notes can be modified.
2400722

What's Changed

  • TESTING.md: match what CI and the tools check today by @seantalts in #492
  • Build CmdStan's SUNDIALS with -fPIC so BridgeStan can link it by @seantalts in #493
  • Fix generated values that start a markdown line by @seantalts in #491
  • Open the README with what Stanli is and its median speedups by @seantalts in #494
  • Windows arm64 R binary: exact CSV fixture, release 0.23.2 by @seantalts in #495

Full Changelog: v0.23.1...v0.23.2

stanli 0.23.1

Choose a tag to compare

@github-actions github-actions released this 22 Oct 13:01
Immutable release. Only release title and notes can be modified.
4fb3009

What's Changed

Full Changelog: v0.23.0...v0.23.1

stanli 0.22.2

Choose a tag to compare

@seantalts seantalts released this 20 Oct 02:59
Immutable release. Only release title and notes can be modified.
38f2d74

Faster inverse Gaussian cognitive models and refreshed benchmark tables.

Performance

  • The inverse Gaussian cognitive model (cm_invgaussian) gets gradients
    about 1.9x faster. Loops with a very large body now run only the branch
    each iteration takes, instead of every branch.
  • Large ctsem models get gradients about 1.03x faster.

Docs

  • The benchmark tables are rerun for this release, so they include the
    0.22.1 speedups for small ctsem models and s2_logistic_normal.

stanli 0.22.1

Choose a tag to compare

@github-actions github-actions released this 19 Oct 14:00
Immutable release. Only release title and notes can be modified.
582a089

Fixes the 0.22.0 memory regression on large ctsem models and makes small
ctsem models faster.

Performance

  • ctsem models with two observed variables get gradients about 2.8x faster,
    and s2_logistic_normal about 3.7x faster: 2x2 matrix products, solves,
    Cholesky factors and multi_normal_cholesky no longer allocate on the
    heap. Larger ctsem models are unchanged. Results are bitwise identical.

Fixes

  • Large ctsem models use far less memory again. 0.22.0 raised peak memory on
    the 4,000-row ctsem model from issue #248 from 1.5 GB to 10.3 GB per chain.
    Gradients on that model are back to their speed before 0.22.0, about 1.15x
    slower than in 0.22.0.
  • A return inside some user-defined functions no longer aborts the
    process.

stanli 0.22.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 17:57
Immutable release. Only release title and notes can be modified.
a9ff644

Faster brms and cognitive models through R and Python on Linux, faster
ctsem on large data, and a smaller C API.

Performance

  • On Linux x86-64, the runtime library that R and Python load reaches Stan
    Math's thread-local autodiff stack without a function call per access.
    Models whose functions run Stan Math autodiff inside, such as
    wiener_lpdf, get faster: on an i9-13900K the brms DDM-4 program from
    issue #455 is 1.25-1.37x faster per gradient than in 0.21.0, and about 1.1x
    faster than CmdStan. Results are bitwise identical. On other platforms the
    reverse pass now looks up the autodiff stack once instead of once per
    node.
  • ctsem models with large datasets: gradients are about 1.09x faster, and
    peak memory is about 2x higher (0.74 GB to 1.6 GB at 64,000 rows).

Fixes

  • Optimization now reports an error when generated quantities reject the
    mode. It used to return success and leave that output row unwritten.
  • The batched sqrt gradient keeps the sign of a zero adjoint, matching the
    scalar form bit for bit.
  • The web page runs every posteriordb model with 1000 warmup iterations and
    1000 draws, the same as the built-in presets. It used 100 of each, too
    short for many models to converge.

API changes

  • The C API now has one entry point per operation, and its ABI version is 2.
    Packages built against ABI version 1 (R packages before this release) refuse
    the new runtime. The removed functions and their replacements:
    • stanli_model_new, stanli_model_new_seeded and
      stanli_model_new_threaded: use stanli_model_new_with_opts.
    • stanli_model_new_from_stan, stanli_model_new_from_stan_seeded and
      stanli_model_new_from_stan_threaded: use
      stanli_model_new_from_stan_with_opts.
    • stanli_stan_to_mir and stanli_stan_to_mir_with_includes: use
      stanli_stan_to_mir_with_opts.
    • stanli_sample, stanli_sample_stream and stanli_sample_stream_stats:
      use stanli_sample_stream_stats_init.
    • stanli_sample_multi, stanli_sample_multi_progress,
      stanli_sample_multi_interruptible and stanli_sample_multi_write_array:
      use stanli_sample_multi_metric.

Docs

  • The user docs are reorganized and shorter, one page per topic.

Pull requests

#468 user docs · #469 web page draw counts · #470 Linux TLS descriptors and grad() stack lookup · #471 simplification and C ABI 2 · #472 retained-loop engine · #473 release

Full changelog: v0.21.0...v0.22.0

stanli 0.21.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 01:41
Immutable release. Only release title and notes can be modified.
ebf68a4

Faster multilevel brms and cognitive models, multi-core brms threading(),
and CmdStan-style metric controls for sampling.

Performance

  • Across the 343-model test corpus, gradients are 2.17x faster than
    CmdStan in geometric mean, up from 1.95x in 0.20.0, and 1.10x faster than
    0.20.0 on the models both releases measure.
  • brms random-effect loops are vectorized. Loops that update an element in
    place (mu[n] += r[J[n]] * Z[n]) and loops that store to the same element
    twice used to run one operation per observation. In the corpus,
    ch13_m13_5 goes from 3031 operations to 18 and ch14_m14_2 from 4053 to
    36. On the multilevel models of issue #455 this also removes the slowdown
    from running several chains at once and the growth of cost per observation
    with N. Gradients of 45 corpus models move at rounding level.
  • brms threading() programs use several cores when threads_per_chain is
    above 1. Before, they ran on one core, and in 0.20.0 they were many times
    slower than the plain program. On a 10,000-observation log-normal race model
    a gradient is 2.8x faster at 4 threads and 3.5x faster at 8, and four chains
    with 4 threads each sample in 10 s instead of 30 s. Data is shared between
    threads and chains instead of copied. A reduce_sum is split only when each
    chunk has about 30 microseconds of work, so small models stay on one thread
    and are never slower. Threaded results depend on threads_per_chain, which
    sets the summation order, and can change between stanli versions; they do
    not depend on thread scheduling. stanli_run prints a note when a model
    with a large reduce_sum runs on one thread.
  • Cognitive race and diffusion models (the cogmod family):
    • cm_invgaussian samples 4.0x faster with one chain and 4.6x faster with
      four. Loops that use log_sum_exp over a range or inv_logit now run 64
      observations at a time. This uses more memory: peak memory with four
      chains rises from 59 MB to 114 MB.
    • cm_lnr and cm_rdm gradients are about 1.5x faster: the reverse pass
      of loops with branches no longer zeroes its scratch buffer.
    • wiener_lpdf evaluates the density once per gradient instead of twice,
      also when its log density is weighted as in a mixture, and data
      arguments are no longer differentiated. About 1.5x faster on a model
      that is one y ~ wiener(...) statement. Gradients move by at most 7 ULP
      on the DDM models tried.
    • In loops with many branches that run one observation at a time, the
      reverse pass visits only the blocks that ran. The gradient is up to 9x
      faster at points where most observations return early.
  • Preparing a model allocates less in the function registry; median
    preparation time is about 1.6% shorter.

Features

  • sample_model() and sample_cstan() in R, and Model.sample() in Python,
    take metric ("diag_e", "dense_e" or "unit_e"), a starting
    inv_metric, step_size and adapt_engaged, as CmdStanR and CmdStanPy
    do. The fit reports the step size and inverse metric each chain holds after
    warmup (fit$step_size, fit$inv_metric, and $inv_metric() on
    as_cstanfit() objects in R; fit.step_size, fit.inv_metric and
    fit.metric in Python), so a pilot fit's metric can start the next one.
    The C API gains stanli_sample_multi_metric with the same controls;
    stanli_sample_opts and the ABI version are unchanged.

Fixes

  • ctsem models were lowered as one operation per data row since 0.19.0, so
    preparation time and memory grew with the data. The Kalman loop is one loop
    again: at 2000 subjects, preparation goes from 18 s to under 1 s and peak
    memory from 1.5 GB to 156 MB. A 400-subject ctsem model is now in the test
    corpus.
  • The runtime builds inside stanr again. The execution report no longer
    needs rapidjson's writer headers, which stanr's vendored Stan does not ship.

API changes

  • C++ callers that set CompileOptions::reduce_sum_min_elements should set
    reduce_sum_min_chunk_ns instead (default 30000, 0 to always split).

Testing

  • Eight brms test fixtures (s2_car, s2_car_esicar, s2_gr_by, s2_mm,
    s2_mm_weights, s2_mmc, sw_re_bern, sw_skewnormal) are gated on
    gradient error in ULP of the largest gradient entry (limit 10, measured at
    most 2) instead of per element. Against a 60-digit reference, s2_mm and
    s2_gr_by are slightly farther on one small entry (by 2e-16 and 6e-16);
    the other six are closer.

Pull requests

#456 in-place loop vectorization (#455) · #457 wiener_lpdf partials · #458 sampler metric controls · #459 benchmark gate, stanr build fix · #461 region map lanes and branch trail · #462 preparation overhead · #463 lane memory · #464 multi-core threading() · #467 release

Full changelog: v0.20.0...v0.21.0

stanli 0.20.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 12:58
Immutable release. Only release title and notes can be modified.
b92871e

What's Changed

  • Check the Linux x86-64 runtime stays on the baseline ISA by @seantalts in #431
  • Run chains in parallel with inits; keep data early returns and shared mixture probabilities on the fast path by @seantalts in #432
  • Fix flaky explicit-inits parallel sampling test by @seantalts in #433
  • Require Windows wheel checks before merging source PRs by @seantalts in #435
  • Require clean compiler builds, corpus performance checks, and post-merge CI follow-up by @seantalts in #436
  • Fix runtime and test compiler warnings by @seantalts in #434
  • Run duplicate operations' backward steps as in-place updates by @seantalts in #437
  • Fuse four densities, read rvar vectors in place, and drop the dead Stan Math kernels from release builds by @seantalts in #439
  • Fast-mode groundwork (research notes, ISA benchmark workflow) plus opt-in AVX2 matrix kernels, off by default by @seantalts in #441
  • Fuse lognormal, beta and gamma by @seantalts in #442
  • Publish the 2026-10-07 corpus benchmark by @seantalts in #445
  • Add a per-model fast_math option by @seantalts in #446
  • Check fused density arguments with one vectorized pass by @seantalts in #444
  • Record the fast-mode density candidates and the sw_skewnormal page-boundary effect by @seantalts in #448
  • Retry the signature replay seed rename on Windows by @seantalts in #447
  • Collapse repeated observations in fast mode: rows, per-group statistics, and a quadratic form by @seantalts in #443
  • Fix the no-stdio build and collapse preparation cost; fast-mode gate in CI; beta_binomial tests by @seantalts in #449
  • Fast mode: browser option, register fill alignment, sampling and accuracy checks by @seantalts in #450
  • Support a brms backend: R additions, partial inits, counting loops; brm() end to end against rstan by @seantalts in #452
  • Stan's other inference algorithms: fixed_param, Laplace, single-path Pathfinder, ADVI by @seantalts in #453
  • R: declare rstantools in Suggests by @seantalts in #454
  • Release 0.20.0 by @seantalts in #451

Full Changelog: v0.19.1...v0.20.0

stanli 0.19.1

Choose a tag to compare

@seantalts seantalts released this 04 Oct 01:33
Immutable release. Only release title and notes can be modified.
d9d0081
  • Reduce math overhead in eligible independent loops with native operations
    for erfc, log1p, log1m_exp, and inv_square.
  • Batch eligible scalar density and unary function calls across loop lanes,
    preserving their scalar values, gradients, and exception messages. Keep
    per-lane calls for functions whose vector implementations round differently.

The pinned stanr integration still fails while vendoring the runtime. The fix is in stanr PR #5, which remains open. The standalone stanli R package is covered separately by required integration checks.

Install with pip install --upgrade stanli, npm install @seantalts/stanli, or the R installation instructions.

Full changelog