Skip to main content

cusna

GPU-accelerated simulation and estimation of stochastic actor-oriented models (SAOM / RSiena) and ERGMs.

License: MIT Python

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 its FRAN hook, 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

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)

Source distribution for cusna 0.1.0
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)

Table of built distributions (wheels) for cusna 0.1.0
File Interpreter ABI Platform Actions
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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page