cusna
GPU-accelerated simulation and estimation of stochastic actor-oriented models (SAOM / RSiena) and ERGMs.
cusna moves the simulation loop of stochastic actor-oriented models
(SAOM — the model family of RSiena)
and exponential random graph models (ERGM) onto the GPU. One CUDA thread
block simulates one chain; adjacency lives in bitmasks, so triadic change
statistics reduce to a bitwise AND and a population count, and the
counter-based Philox4x32-10 RNG makes every run bit-reproducible. A
multithreaded numba backend mirrors the CUDA
kernel exactly and runs everywhere, so the package is fully functional on
CPU-only machines (the GPU is an accelerator, not a requirement).
The library offers two complementary paths:
- an acceleration backend for RSiena — a fast, bit-exact simulator that
drives the trusted
siena07()estimator through itsFRANhook, so RSiena's convergence machinery is inherited unchanged; and - a compatible standalone estimator — a batched method-of-moments (Robbins–Monro) estimator, the fast path for well-conditioned models.
Installation
pip install cusna # CPU backend (numpy + numba), works everywhere
pip install "cusna[gpu]" # + CuPy with the bundled CUDA 12 runtime
The [gpu] extra pulls cupy-cuda12x[ctk], which JIT-compiles the kernels
with NVRTC — no separate CUDA toolkit installation is required, only an
NVIDIA driver. On a machine without an NVIDIA GPU, install the base package
and use backend="cpu".
Quickstart
This runs on any machine (CPU backend, no GPU needed):
import numpy as np
from cusna.saom.data import SaomData
from cusna.saom.stats import EffectSpec
from cusna.saom.mom import MomEstimator
rng = np.random.default_rng(0)
# A tiny two-wave directed network panel (n = 20 actors).
w1 = (rng.random((20, 20)) < 0.15).astype(np.uint8)
w2 = w1.copy()
flip = rng.random((20, 20)) < 0.10 # some ties change between waves
w2[flip] = 1 - w2[flip]
np.fill_diagonal(w1, 0); np.fill_diagonal(w2, 0)
data = SaomData([w1, w2])
effects = [EffectSpec("density"), EffectSpec("recip"), EffectSpec("transTrip")]
est = MomEstimator(data, effects=effects, conditional=True, backend="cpu")
res = est.estimate()
print(res.summary()) # estimated parameters, standard errors, t-conv
Switch to the GPU by passing backend="gpu" (requires cusna[gpu] and an
NVIDIA GPU). To force the CPU path on a GPU machine, set the environment
variable CUSNA_NO_GPU=1.
Driving RSiena from R
cusna can back the unmodified siena07() estimator via reticulate, so R
users get GPU-accelerated simulation without forking RSiena:
source("r/cusnaFRAN.R")
alg$FRAN <- make_cusna_fran(waves, effect_names, cov, conditional, proto_dir, python)
siena07(alg, data = dat, effects = eff, useCluster = FALSE)
A dedicated R package (wrapping this engine through reticulate, in the
spirit of tensorflow/keras/greta) is in preparation; see the
repository for the current bridge.
What works
SAOM method-of-moments estimation (conditional, unconditional and
coevolution), a broad catalog of network and behavior effects (including the
gwesp/gwdsp families, user-defined interactions and cross-network effects),
creation/endowment effects, network–behavior and multi-network coevolution,
missing data, structural zeros/ones, MaxDegree, multiple actor and dyadic
covariates, composition change, symmetric networks, sienaGOF-style goodness
of fit, and a drop-in siena07() backend. On the ERGM side: a TNT sampler
(batch of independent chains, exact ergm proposal protocol) and an MPLE
change-statistic kernel. Full MCMC-MLE for ERGMs remains the domain of
ergm.
Every capability is validated against RSiena 1.6.6 and ergm 4.12: 23 automated comparisons across five public longitudinal datasets (s50, van de Bunt, Glasgow, Knecht, COW alliances), synthetic panels and three classic ERGM benchmarks. Targets match to machine precision; simulated statistic distributions are equivalent; estimates agree within a fraction of a standard error.
Throughput on an RTX 3060 Ti reaches ~34k full-period simulations per second on the classic s50 dataset (n = 50) — one to two orders of magnitude over single-core RSiena, with the kernel becoming memory-bound around n ≈ 1000.
Documentation & source
- Source, examples and validation harness: https://github.com/artemmaltsev74-techcom/cusna
- API reference:
docs/api.md
License
MIT. cusna contains no RSiena or ergm code; it re-implements the models and
validates its outputs against those packages.
Metadata
Release files for cusna 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cusna-0.1.0.tar.gz | 96.1 kB | Without provenance | Details for cusna-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cusna-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for cusna-0.1.0-py3-none-any.whl |
Total release size: 169.6 kB
Release files / cusna-0.1.0.tar.gz
| Download URL | cusna-0.1.0.tar.gz |
|---|---|
| Size | 96.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
440b32d1eabf4b6a6532f0fecfae0108702f312593390feab6e1194236aec706
|
|
BLAKE2b-256 checksum How to use checksums |
736ac1575b94ab9e821f364cbf55d3eac1dbe657f51c2975c66c6769e3cd2617
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / cusna-0.1.0-py3-none-any.whl
| Download URL | cusna-0.1.0-py3-none-any.whl |
|---|---|
| Size | 73.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4aea3b05174ae52140d1ef08fa1bf5b61f0b41c5bdb810aa7979aaf314d466a7
|
|
BLAKE2b-256 checksum How to use checksums |
438462165e0821ead3119add3afe69de360cee827be36e99840a695b56695535
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for cusna 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.