Skip to main content

GPU-native Persistent Topological Laplacians in PyTorch

Project description

petls-pytorch

PyPI CI Python License

PyTorch-native persistent topological Laplacians, with CUDA support for large dense eigendecompositions.

Status: beta

A PyTorch-native implementation of persistent topological Laplacians, based on the public PETLS API, PETLS documentation, and the algorithms described in the PETLS paper.

The goal of this project is to make PETLS-style computations easier to use in Python and PyTorch workflows, especially when downstream code already works with torch tensors or CUDA devices. The original C++/pybind11 PETLS implementation remains the reference for correctness.

Contents

Quick Start

import petls_pytorch
import gudhi

# Alpha complex from point cloud
alpha = petls_pytorch.Alpha(points=[[0, 0], [1, 0], [0.5, 1]], max_dim=2)
eigs = alpha.spectra(0, 0.0, 1.0)

# Rips complex from distance matrix
rips = petls_pytorch.Rips(distances=[[0, 1, 1], [1, 0, 1], [1, 1, 0]], max_dim=2)

# Directed flag complex from .flag file
dflag = petls_pytorch.dFlag("graph.flag", max_dim=3)

# Sheaf Laplacian
st = gudhi.SimplexTree()
st.insert([0], filtration=0.0)
st.insert([1], filtration=0.0)
st.insert([0, 1], filtration=1.0)
extra_data = {(0,): 1.0, (1,): 1.0, (0, 1): 1.0}


def restriction(simplex, coface, sst):
    return 1.0


sst = petls_pytorch.sheaf_simplex_tree(st, extra_data, restriction)
psl = petls_pytorch.PersistentSheafLaplacian(sst)
filtrations = psl.get_all_filtrations()
sheaf_eigs = psl.spectra(dim=0, a=filtrations[0], b=filtrations[-1])

For spectra(dim, a, b), choose a and b from the filtration values in psl.get_all_filtrations() with a <= b.

Relationship to PETLS

petls-pytorch is an independent PyTorch-native implementation of the PETLS methods and public API behavior, with attribution to the original PETLS paper and project. Correctness tests compare against the original implementation using shared inputs.

The full test suite includes 65 reference/parity tests against original PETLS fixtures and variants, with default comparison tolerances of atol=1e-4 and rtol=1e-3 unless a test specifies a stricter tolerance.

This project is based on the public PETLS API, PETLS documentation, and the algorithms described in the PETLS paper. No source code from the original PETLS implementation is included in this repository.

API Coverage

Original PETLS API PyTorch API Status
Complex Complex Implemented
Alpha Alpha Implemented
Rips Rips Implemented
dFlag dFlag Implemented
sheaf_simplex_tree sheaf_simplex_tree Implemented
PersistentSheafLaplacian PersistentSheafLaplacian Implemented
Profile, timer Profile, Timer Implemented
summaries, plot_summary summaries, plot_summary Implemented
up_Algorithms enum up_Algorithms enum Implemented
eigvalsh_wrapper, sparse_wrapper, matrix_is_diagonal Same Implemented
flipped optimization flipped + get_L_top_dim_flipped Implemented
nonzero_spectra() nonzero_spectra() Implemented
store_L(), store_spectra(), store_spectra_summary() Same Implemented
time_to_csv() time_to_csv() Implemented

Directed Flag Files

dFlag reads weighted directed graphs from .flag files with a dim 0 vertex-weight section and an optional dim 1 directed-edge section:

dim 0
0.0 0.0 0.0 0.0
dim 1
0 1 1.25
1 2 2.50
0 2 3.00

The dim 0 line after the header contains one whitespace-separated vertex weight per vertex. Each dim 1 row is source target weight, using zero-based vertex indices. Missing directed edges are absent from the file; self-loops are not supported. Filtration values for higher-dimensional directed simplices are the maximum edge weight in each simplex.

Benchmark Notes

The benchmark runner compares petls-pytorch and the original PETLS package on identical synthetic inputs. It streams progress for every trial and writes all CSV, JSON, and plot outputs under benchmark-results/ by default.

The standard preset is the main comparison workload. It exercises Alpha complexes on torus, sphere, swiss roll, and Klein bottle point clouds, plus a bounded Rips-complex case. It samples dimensions 0, 1, and 2 and completes all standard rows by default, including empty Laplacians and the largest sampled Alpha matrices. Use --max_matrix_rows only for custom capped runs.

Final benchmark on our Windows 11 Pro machine:

  • CPU: Intel Core i7-13700K, 16 cores / 24 logical processors
  • GPU: NVIDIA GeForce RTX 4070 Ti, 12GB
  • PyTorch: 2.10.0+cu130
  • Original PETLS: petls==1.0.1, native Windows C++ build
Package Device Completed Skipped Trial Time Mean Trial Mean Eigs Complex Builds Max Completed Matrix
petls CPU 78 0 8.05 s 103.2 ms 97.7 ms 0.52 s 2399 x 2399
petls-pytorch CPU 78 0 2.20 s 28.2 ms 24.2 ms 0.57 s 2399 x 2399
petls-pytorch CUDA 78 0 1.05 s 13.4 ms 9.7 ms 0.66 s 2399 x 2399

On this workload, petls-pytorch CPU is 3.65x faster by trial time and 4.03x faster on eigensolves than native PETLS. On the RTX 4070 Ti, petls-pytorch CUDA is 7.70x faster by trial time and 10.04x faster on eigensolves. A few tiny rows are still slower row-by-row because fixed overhead dominates, but the standard CPU and CUDA aggregate comparisons are both clear wins with no skipped benchmark rows.

Running Benchmarks

From a source checkout, run the benchmark module with uv. Add --with petls when benchmarking against the original PETLS package.

# Representative CPU/GPU comparison
uv run python -m benchmark --preset standard --package petls-pytorch --algorithm eigvalsh --device cpu
uv run python -m benchmark --preset standard --package petls-pytorch --algorithm eigvalsh --device cuda

# Reference PETLS, if installed for your platform
uv run --with petls python -m benchmark --preset standard --package petls --algorithm selfadjoint

# Larger GPU stress run
uv run python -m benchmark --preset stress --package petls-pytorch --algorithm eigvalsh --device cuda

# Custom single run
uv run python -m benchmark \
    --dataset torus --n_points 2000 --complex alpha --max_dim 3 \
    --package petls-pytorch --algorithm eigvalsh --device cuda \
    --max_matrix_rows 12000

By default, benchmark files are written under benchmark-results/results. Use --output_dir benchmark-results/<run-name> to keep named runs together.

Verify CUDA before benchmarking:

nvidia-smi
python -c "import torch; print(torch.__version__, torch.version.cuda, torch.cuda.is_available(), torch.cuda.get_device_name(0) if torch.cuda.is_available() else None)"

If you are not using uv, install from the source checkout first:

python -m pip install -e .
python -m pip install petls  # only needed for --package petls
python -m benchmark --preset standard --package petls-pytorch --algorithm eigvalsh --device cpu

Installation

pip install petls-pytorch

Then import it in Python with import petls_pytorch.

Requires CPython 3.10, 3.11, 3.12, 3.13, or 3.14.

For GPU acceleration, install a CUDA-enabled PyTorch build that matches your system using the official selector at https://pytorch.org/get-started/locally/.

Release notes are tracked in CHANGELOG.md.

Dependencies:

  • torch
  • numpy
  • scipy
  • gudhi
  • tadasets for benchmarks

Test Suite

From a source checkout, run the default test suite with development dependencies:

uv run --extra dev pytest tests/ -v

By default, tests that compare against the original PETLS package are skipped when petls is not installed. To run the full parity suite against the reference implementation:

uv run --extra dev --with petls pytest tests/ -v

If you are not using uv, install the package and test dependencies first:

python -m pip install -e ".[dev]"
python -m pip install petls  # only needed for the full parity suite
pytest tests/ -v

The full parity suite covers core functionality, Rips complexes, alpha complexes, directed flag complexes, sheaf support, eigenvalue utilities, and I/O helpers.

Contributing

Issues and pull requests are welcome at https://github.com/Sylverity/petls-pytorch/issues. Contributions that expand coverage against the reference PETLS implementation are especially helpful.

License

This project is licensed under the Apache License 2.0 — see LICENSE.

petls_pytorch is an independent, clean-room implementation and contains no source code from the original PETLS project. It depends on third-party packages with their own licenses, including gudhi (MIT, with GPL-licensed dependencies such as CGAL used by some modules, e.g. alpha complexes). These are installed separately and are not redistributed as part of this project.

Citation

If you use petls-pytorch in research, please cite both this PyTorch implementation and the original PETLS paper.

petls-pytorch

@software{marston2026petlspytorch,
  title        = {petls-pytorch: A PyTorch-native implementation of persistent topological Laplacians},
  author       = {Marston, Sumner K.},
  year         = {2026},
  publisher    = {Sylverity Research},
  url          = {https://github.com/Sylverity/petls-pytorch}
}

Original PETLS paper

@misc{jones2025petlspersistenttopologicallaplacian,
    title={PETLS: PErsistent Topological Laplacian Software},
    author={Benjamin Jones and Guo-Wei Wei},
    year={2025},
    eprint={2508.11560},
    archivePrefix={arXiv},
    primaryClass={math.AT},
    url={https://arxiv.org/abs/2508.11560},
}

This project is an independent PyTorch-native implementation based on the public PETLS API, PETLS documentation, and the PETLS paper. No source code from the original PETLS implementation is included in this repository.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

petls_pytorch-1.0.2.tar.gz (36.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

petls_pytorch-1.0.2-py3-none-any.whl (38.7 kB view details)

Uploaded Python 3

File details

Details for the file petls_pytorch-1.0.2.tar.gz.

File metadata

  • Download URL: petls_pytorch-1.0.2.tar.gz
  • Upload date:
  • Size: 36.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for petls_pytorch-1.0.2.tar.gz
Algorithm Hash digest
SHA256 e22645d24c13db0c13db697897dcab8e4aebcf513434492dab614cdc72aabc33
MD5 454617e5052e34e011f66feffdbac5fc
BLAKE2b-256 90831ef543101cbb748c26353670341b2fc94412ab54dc09f4315ebe4a37fbf8

See more details on using hashes here.

Provenance

The following attestation bundles were made for petls_pytorch-1.0.2.tar.gz:

Publisher: release.yml on Sylverity/petls-pytorch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file petls_pytorch-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: petls_pytorch-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 38.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for petls_pytorch-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 28474c867a06918aa8041357bd57581a7eebbb4965e46dba65602b355d66bb72
MD5 5d1af4f6ac65e6f646009fbddce92834
BLAKE2b-256 feb9742c4f759e9df09bc5faa6b30f4bed0cf1e407e07205370cd89be0a12ef6

See more details on using hashes here.

Provenance

The following attestation bundles were made for petls_pytorch-1.0.2-py3-none-any.whl:

Publisher: release.yml on Sylverity/petls-pytorch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page