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 relannworks 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/cpuin step 1 and+cpuin step 3.Why is step 3 separate?
torch-scatter/torch-sparse/torch-clusterare 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
- Paper: Incorporating Deep Learning Design in Database Queries. Yuval Lev Lubarsky, Dean Light, Boaz Berger, Shunit Agmon, Benny Kimelfeld. VLDB TaDA 2026. arXiv:2605.24207
- Source: https://github.com/yuvallu/relann
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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.