Skip to main content

relann

RelaNN — A declarative query language for neural networks over relational databases.

RelaNN lets you express deep neural networks directly over relational data using a Datalog-style query language with embedding semantics. Each tuple carries a learnable vector embedding; joins compose embeddings; group-by projections aggregate them. Programs are compiled to PyTorch + cuDF + SQL physical plans.

This codebase is the open-source proof-of-concept implementation accompanying the paper "Incorporating Deep Learning Design in Database Queries" (VLDB TaDA 2026).

Why RelaNN

  • 40 % of the world's data lives in relational databases — RelaNN keeps the model definition inside the relational paradigm rather than round-tripping through external graph libraries.
  • Declarative syntax similar to SQL/Datalog — define the architecture, not the tensor plumbing.
  • No graph-conversion boilerplate — joins, aggregations and transformations have well-defined embedding semantics built into the language.
  • GPU acceleration via cuDF, with pandas fallback on CPU.
  • Mirrors the math of the original papers — implementations of GCN, R-GCN, HGT, HyGNN and DHN are 3–10× shorter than their PyTorch/PyG references.

Example

The two rules below implement query-key-value attention as used by Heterogeneous Graph Transformers over a Patients × Treatments schema:

Score(p, t; q*k)         :- Treat(p, t), Queries(p; q), Keys(t; k) .
Attention(p; sum(a*v))   :- Score(p, t; a), Values(t; v) .

The first rule joins Treat, Queries, Keys on p and t, composing the embeddings as q*k. The second joins Score with Values, weights each value by its attention score, and aggregates with sum after projecting away t.

Install

relann is GPU-first (PyTorch + optional cuDF/RAPIDS). The steps below install the CUDA build; a CPU-only fallback is noted underneath.

# 1. Install the CUDA build of PyTorch FIRST. On Windows the default PyPI torch is
#    CPU-only, so pull it from PyTorch's CUDA index. Swap cu124 for the tag matching
#    your NVIDIA driver (cu118 / cu121 / cu124 / cu126 / ...).
pip install torch --index-url https://download.pytorch.org/whl/cu124

# 2. Install relann (torch is already satisfied, so pip won't pull a CPU wheel).
pip install relann                       # core library
pip install "relann[examples]"           # + relbench, scikit-learn, matplotlib (to run the examples)
#   extras: [examples] [viz] [benchmarks] [sql] — combine like "relann[examples,viz]"

# 3. Install the PyG sparse stack (torch-scatter & friends) used by relann's
#    scatter/aggregation operators. These are prebuilt wheels matched to your torch
#    version + CUDA tag, so they are NOT installed by `pip install relann`.
pip install --no-build-isolation torch-scatter torch-sparse torch-cluster torch-geometric \
    -f https://data.pyg.org/whl/torch-2.6.0+cu124.html

import relann works without step 3 — only the scatter aggregation operators require the PyG stack, and they raise a clear install hint if it's missing.

CPU-only fallback: use --index-url https://download.pytorch.org/whl/cpu in step 1 and +cpu in step 3.

Why is step 3 separate? torch-scatter / torch-sparse / torch-cluster are compiled C++/CUDA extensions that must match your exact torch + CUDA build, so pip can't resolve them from PyPI — they ship as prebuilt wheels on the PyG index. For full GPU / cuDF / RAPIDS setup, see docs/install-gpu.md.

Develop from source

Working on relann itself uses uv and the juplit notebook workflow:

pip install uv      # or: brew install uv (macOS) · curl -LsSf https://astral.sh/uv/install.sh | sh (Linux)

git clone https://github.com/yuvallu/relann.git && cd relann
uv run poe full-setup    # uv sync + PyG sparse stack (CPU by default) + generate notebooks
uv run poe init          # install git hooks

For a CUDA dev box, set TORCH_PYG_URL before full-setup (see docs/install-gpu.md).

Workflow

This project uses juplit for literate programming: every .py file in relann/ and examples/ is paired with a .ipynb notebook via jupytext. The .py is the source of truth; .ipynb is generated on demand and gitignored.

uv run poe sync         # sync .py ↔ .ipynb after edits
uv run poe nb           # generate .ipynb from .py (run after cloning)
uv run poe clean        # sync then delete all .ipynb files (clean for AI agents)
uv run poe smoke        # fastest sanity check (~5s)
uv run poe quick        # smoke + feature (~15s)
uv run poe test         # full pytest sweep

Repository layout

relann/                # Python package — paired juplit .py notebooks (jupytext header + if test():)
├── parser.py, engine.py, session.py, term_graph.py, era_operations.py, …
├── utils/
└── relnn_grammar.lark # Lark DSL grammar

tests/                 # standalone pytest files
├── smoke/  feature/  dhn/  slow/  repro/  scaffold/

examples/              # user-facing demos (juplit .py)
research/
├── paper_experiments/ # reproducibility artefacts for the paper
└── _drafts/           # in-progress research notebooks

docs/                  # design notes, architecture, historical reference
.claude/skills/        # Claude-Code skills (juplit-programming, write-relnn-program)
scripts/run_tests.py   # convenience wrapper around pytest profiles

Tests

After the install steps above, all of these should pass on a CPU-only host:

uv run poe smoke                                   # ~5s   — 34 tests
uv run poe quick                                   # ~15s  — smoke + 274 feature tests
uv run pytest tests/repro                          # ~5s
uv run pytest tests/dhn -v                         # ~25s  — 51 tests
uv run pytest tests/                               # full sweep

Or via the runner script:

uv run python scripts/run_tests.py smoke           # ~5s
uv run python scripts/run_tests.py quick           # ~15s
uv run python scripts/run_tests.py hgt             # HGT slow scripts
uv run python scripts/run_tests.py dhn             # ~60s
uv run python scripts/run_tests.py full            # ~6min

Test collection is scoped by pyproject.toml to testpaths = ["tests"] and python_files = ["test_*.py"]. Source modules under relann/*.py keep if __name__ == "__main__": demo cells that run only when opened interactively in Jupyter — they aren't picked up at pytest collection time.

Paper & citation

License

Apache-2.0. See LICENSE.

Metadata

Release files for relann 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 relann 0.1.0
File Size Uploaded Provenance Actions
relann-0.1.0.tar.gz 178.3 kB Without provenance Details for relann-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for relann 0.1.0
File Interpreter ABI Platform Actions
relann-0.1.0-py3-none-any.whl Python 3 none any Details for relann-0.1.0-py3-none-any.whl

Total release size: 365.2 kB

Release files / relann-0.1.0.tar.gz

Download URL relann-0.1.0.tar.gz
Size 178.3 kB
Tags Source
SHA-256 checksum
How to use checksums
24923581b96230c12fbb0ce3626fbd76c8e42cc5725b78c78894536e8c75e0c6
BLAKE2b-256 checksum
How to use checksums
c065465448006e6d03b0e3d4bab4f37b9e9189b641711d87c818887a1816dc78
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.9

Release files / relann-0.1.0-py3-none-any.whl

Download URL relann-0.1.0-py3-none-any.whl
Size 186.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
59821520e092dc968a53d0c30160d05b6aeb48de204b31a06797bcb430c00802
BLAKE2b-256 checksum
How to use checksums
7f6256edc4c08f5a4a6dd7816ff3141219233b2a918e54f0981de309e9ac11ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.9

Security for relann 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