Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
gam / gamfit
A generalized additive model engine. The fitting code is in Rust. The
public interfaces are a Rust CLI (gam) and a Python package
(gamfit). Both share one engine, one formula DSL, and one on-disk
model format.
Docs: https://gamfit.readthedocs.io/. PyPI: https://pypi.org/project/gamfit/.

Scope
Supported response families: Gaussian, binomial / Bernoulli (including a marginal-slope variant for calibrated risk scores), Poisson, Gamma, and parametric / semi-parametric survival.
Supported term types in formulas: parametric terms, univariate smooths
(s), tensor-product smooths (te, ti), radial smooths in arbitrary
dimension (matern, duchon, thinplate), intrinsic sphere smooths
(sphere), random effects (group), interval-bounded coefficients
(bounded), and learnable links (link(type=flexible(...)),
link(type=blended(...)), sas, beta-logistic, linkwiggle).
Smoothing parameters are selected by REML or LAML. Posterior sampling uses NUTS over the coefficient posterior conditional on the fitted smoothing parameters where the family supports it, and a Gaussian Laplace approximation otherwise.
Install
Python wheels are published for Linux (x86_64, aarch64), macOS (Intel and Apple silicon), and Windows. A Rust toolchain is not required.
# or
Optional extras: gamfit[pandas], gamfit[plot], gamfit[sklearn],
gamfit[torch], gamfit[all].
For the Rust CLI:
|
Or cargo build --release. The binary is ./target/release/gam.
Usage
Python:
=
=
CLI:
CLI subcommands: fit, predict, report, diagnose, sample,
generate. Run gam <command> --help for options.
Examples
Surface smooths in arbitrary dimension, with optional per-axis length scales:
Smooths on manifolds. The basis and penalty encode the wrap topology,
so a fit on theta ∈ [0, 2π) has no seam at 0 / 2π, and an S² fit
has no pole artefacts.

Each pair shows the noisy input (left) and the recovered smooth (right). The full gallery and reproduction script: docs/manifold-smooths.md.
Learnable link functions. A flexible(base) link adds a spline offset
on top of a base link. blended(l1, l2) learns a mixture weight. sas
and beta-logistic learn shape parameters.
Marginal-slope models for binary or survival outcomes with a calibrated risk score. The baseline and the score effect are fit in separate formulas; the score effect is a smooth function of covariate space.

Survival models. Surv(entry, exit, event) is supported in four
likelihood modes: transformation, Weibull, location-scale, and
marginal-slope. model.predict(...) returns a SurvivalPrediction
with on-demand S(t), h(t), H(t) on any time grid:
=
=
=
# streamed
Posterior sampling. model.sample(...) draws from the coefficient
posterior conditional on the fitted smoothing parameters. Predictive
bands are computed in row chunks.
=
=
Interval-bounded coefficients with an optional Beta prior:
scikit-learn wrappers:
=
Penalties
A smooth term contributes one or more penalized coefficient blocks, each with its own smoothing parameter selected by REML/LAML. For polyharmonic and Duchon radial bases, three penalty operators act on the same coefficient block: mass (L²), tension (gradient), and stiffness (Laplacian/curvature). P-spline, thin-plate, and tensor-product smooths use their standard derivative-based penalties.
GPU
The Rust engine includes optional CUDA support (cuBLAS, cuSOLVER, cuSPARSE). It loads lazily and falls back to the CPU path when no working CUDA stack is found. The same wheel runs on CPU-only and GPU hosts.
Per-op dispatch thresholds are measured at probe time from GPU FP64 throughput, CPU FP64 throughput, and PCIe bandwidth. Below the crossover where transfer cost dominates, kernels stay on the CPU. To print the calibrated thresholds:
If both a system CUDA toolkit and PyTorch's nvidia-*-cu12 wheels are
present in the same environment, the same SONAME (e.g.
libcublas.so.12) can appear twice in /proc/self/maps. This is
benign when glibc resolves dlopen(SONAME) to a single file; gamfit
warns once per conflict-set and continues. The pathological case
(cublasDestroy_v2 aborting in glibc) only occurs if calling code
dlopens both files by absolute path. Keep one CUDA toolkit
reachable.
If you use gamfit together with torch and your driver is CUDA 12.x,
install a torch build whose CUDA suffix matches the driver
(+cu12x). gamfit itself loads cuBLAS / cuSOLVER / cuSPARSE through
whichever libcudart.so.12 is reachable.
Repository layout
| Path | Contents |
|---|---|
src/ |
Rust engine: fitting, inference, smooth construction, survival, CLI. |
crates/gam-pyffi/ |
PyO3 bindings (gamfit._rust). |
gamfit/ |
Python public API on top of the bindings. |
docs/ |
MkDocs/Material documentation sources. |
tests/ |
Rust and Python integration tests. |
bench/ |
Benchmark harness, configs, datasets, plots. |
scripts/ |
Demo and diagnostic scripts, including the manifold smooths gallery. |
Development
Benchmarks: python3 bench/run_suite.py --help.
Documentation
- Full Python documentation: https://gamfit.readthedocs.io/.
- Cookbook: docs/cookbook.md.
- Manifold smooths gallery: docs/manifold-smooths.md.
Issues
Open a GitHub issue for bug reports, feature requests, or questions.
License
AGPL-3.0-or-later. See LICENSE.