Metadata-Version: 2.4
Name: cusna
Version: 0.1.0
Summary: GPU-accelerated simulation and estimation of stochastic actor-oriented models (SAOM/RSiena) and ERGMs
Author-email: Artem Maltsev <MaltsevSNA@proton.me>
Maintainer-email: Artem Maltsev <MaltsevSNA@proton.me>
License-Expression: MIT
Project-URL: Homepage, https://github.com/artemmaltsev74-techcom/cusna
Project-URL: Repository, https://github.com/artemmaltsev74-techcom/cusna
Project-URL: Documentation, https://github.com/artemmaltsev74-techcom/cusna/blob/main/docs/api.md
Project-URL: Issues, https://github.com/artemmaltsev74-techcom/cusna/issues
Keywords: social network analysis,stochastic actor-oriented models,SAOM,RSiena,ERGM,exponential random graph models,network simulation,statistical inference,method of moments,CUDA,GPU
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Environment :: GPU :: NVIDIA CUDA :: 12
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.26
Requires-Dist: numba>=0.59
Provides-Extra: gpu
Requires-Dist: cupy-cuda12x[ctk]>=13.0; extra == "gpu"
Provides-Extra: npe
Requires-Dist: torch>=2.2; extra == "npe"
Requires-Dist: sbi>=0.22; extra == "npe"
Provides-Extra: bench
Requires-Dist: pandas>=2.0; extra == "bench"
Requires-Dist: pyreadr>=0.5; extra == "bench"
Dynamic: license-file

# cusna

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

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)

`cusna` moves the simulation loop of stochastic actor-oriented models
(SAOM — the model family of [RSiena](https://www.stats.ox.ac.uk/~snijders/siena/))
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](https://numba.pydata.org/) 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

```bash
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):

```python
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:

```r
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`](https://github.com/artemmaltsev74-techcom/cusna/blob/main/docs/api.md)

## License

MIT. `cusna` contains no RSiena or ergm code; it re-implements the models and
validates its outputs against those packages.
