# Graph matching means node correspondence, and pygmtools wraps the solvers

> pygmtools is a solver library for one specific hard problem: finding node-to-node correspondence between graphs. It puts linear, quadratic, multi-graph and neural solvers behind one API and one set of arguments across six backends, from numpy on CPU to PyTorch or MindSpore on GPU. What it is not is a graph store or a graph neural network library.

**Thinklab-SJTU/pygmtools** — A Python Graph Matching Toolkit.

- Repository: https://github.com/Thinklab-SJTU/pygmtools
- Website: https://pygmtools.readthedocs.io/
- Stars: 352 · Forks: 19
- Language: Python
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/thinklab-sjtu-pygmtools

## The problem is correspondence, not graph storage

Graph matching, as this library defines it, is finding node-to-node correspondence among multiple graphs by solving an NP-hard combinatorial optimization problem. The README places it in pattern recognition and data mining and calls it fundamental yet challenging, which is an accurate summary of why the code for it tends to live in somebody's thesis repository rather than in a package.

The audience is researchers reproducing or extending published methods, which the citation request in the README makes explicit: the toolkit is published in JMLR and the authors ask you to cite the paper if the tools prove useful.

What the package is not matters as much as what it is. It is not a graph database and not a graph neural network framework, and it does not compete with them. networkx is a required dependency at version 2.8.8 or newer, which tells you the boundary: networkx builds, stores and analyses the graph, and pygmtools solves the correspondence problem once you have two graphs whose nodes you want to line up.

## Six backends, one API, and extras declared as empty

The same solver signature is available on numpy, which is the default and CPU only, and on PyTorch, Jittor, PaddlePaddle, TensorFlow and MindSpore, each of which is described as GPU friendly and deep learning friendly. Jittor adds JIT support to that list. You install your backend by following that project's own instructions, not through this package.

That choice is visible in the packaging. The EXTRAS dictionary in setup.py is empty, so none of the five GPU frameworks is declared as an optional dependency group, and pip install pygmtools gives you the numpy path and nothing more. The required list is modest by comparison: requests, scipy, Pillow, numpy, easydict, appdirs, tqdm, networkx, aiohttp and async-timeout, with Python 3.8 or newer.

The reason to care about the backends is gradient flow. The README describes the operations as designed to best preserve the gradient during computation, with batched operations for performance, which is what lets a soft solver sit inside a larger differentiable model instead of being a preprocessing step that severs the graph.

## Sinkhorn next to Hungarian, and the differentiable middle ground

The two-graph module is where most people start, and it is organised by how much of the problem you are willing to relax. Linear assignment solvers come in two flavours: Sinkhorn, which is differentiable and soft, and Hungarian, which is exact. Both take an affinity matrix and return a correspondence.

Quadratic assignment has three entries and the spread is wider. Spectral graph matching and the random-walk based solver are soft and differentiable, so the correspondence can be part of a learned pipeline. The integer projected fixed point method is discrete and not differentiable, which is what you want when the answer has to be a real permutation rather than a relaxation of one.

That three-way split is the practical decision in this library, and it is a decision the CLI cannot make for you: a probabilistic model needs Sinkhorn or the spectral and random-walk solvers, while an evaluation that must report an exact assignment needs Hungarian or IPFP. Having all four in one place is the reason to install the package rather than copying one function out of a paper's repository.

## Multi-graph matching optimises affinity while infusing consistency

Matching three or more graphs together is a different problem, not three pairwise problems stacked, and the multi-graph solvers here acknowledge that. Composition based Affinity Optimization optimises the affinity score while gradually infusing consistency across the graphs, which is how it avoids settling on a set of pairwise answers that contradict each other.

Two other approaches sit beside it. One is built on the Floyd shortest path algorithm, turning pairwise similarity into a path problem across the graph set. The other is graduated assignment based multi-graph matching, which works by graduated annealing of Sinkhorn's temperature: start with a soft, high-temperature solution and cool it into something closer to a hard assignment.

That last idea is worth noticing because it is the same mechanism the linear solver family relies on, applied as a schedule rather than a single step. If your multi-graph problem is too large for an exact assignment, a temperature schedule is a reasonable place to start before you write your own.

## Neural solvers reach into edit distance, and their weights download at first use

The neural module covers three different problems. PCA-GM and IPCA-GM use intra-graph and cross-graph embeddings for matching individual graphs. Channel independent embedding is another solver for that same individual-graph case. NGM handles the general quadratic assignment formulation, and GENN-A*, a graph edit network with A-star search, targets the graph edit distance problem, which is a different question from matching.

Weights arrive at runtime. Pretrained models are downloaded automatically when a solver needs them, and if the automatic download fails you place the files yourself at ~/.cache/pygmtools, a path given for Linux. Mirrors are listed for HuggingFace, Google Drive and Baidu drive, which is a reasonable amount of redundancy for research code that a pip install cannot fully describe.

The practical caveat is that this is the part of the package that depends on your backend being right. A downloaded checkpoint and a framework you installed by hand are two separate failure surfaces, and neither error will come with a message that names the other.

## Two install commands, and a dependency floor from 2020

The stable path is one command:

```bash
pip install pygmtools
```

The development path points at the master archive instead, with --user noted for an install without root:

```bash
pip install -U https://github.com/Thinklab-SJTU/pygmtools/archive/master.zip
```

What pip brings along, all of it version-floored: Python 3.8 or newer, requests 2.25.1, scipy 1.4.1, Pillow 7.2.0, numpy 1.18.5, easydict 1.7, appdirs 1.4.4, tqdm 4.64.1 and networkx 2.8.8, plus aiohttp and async-timeout. Those floors are low enough that a current Python environment will not trip over them, and high enough that a 2020 stack will.

Documentation lives at pygmtools.readthedocs.io, with the backend installation instructions on its getting started page, and the repository builds that site through .readthedocs.yaml.

## Eight numbered examples, from isomorphic graphs to RDKit

The examples directory is the fastest way to see which solver you are looking for, because each folder is a task rather than an algorithm. 1 covers matching isomorphic graphs, the case with a known answer. 2 is seeded graph matching. 3 is discovering subgraphs inside a larger structure. 4 is multi-graph matching. 5 is model fusion.

The last three move out of abstract graphs. 6 matches images through quadratic assignment, 7 does image matching by nearest neighbour, and 8 does graph matching with RDKit, which is the bridge to molecules. That progression is a fair description of the field's centre of gravity: the same correspondence solver, applied to shapes, then to images, then to chemical structures.

Running the tests is pytest-shaped: conftest.py sits at the repository root next to tests/ and codecov.yml, so the suite is wired for coverage reporting.

## Version 0.6.0, a version string parsed out of __init__.py

The packaging is older setuptools style, and one detail explains how versions stay in sync. AUTHOR and VERSION are not declared in setup.py; both are read out of pygmtools/__init__.py by a regular expression in a get_property helper, so the package version has exactly one home. The long description is likewise read from README.md, which is why MANIFEST.in has to ship it.

There is a compatibility shim for the wheel build. setup.py checks the installed setuptools version and imports bdist_wheel from setuptools.command.bdist_wheel when it is at least 70.1.0, falling back to the standalone wheel package otherwise, with a comment noting the condition can fail for setuptools below 70.1.0 paired with wheel 0.44 or newer.

On cadence: 0.6.0 was released on 2026-04-02, after 0.5.5 in September 2025 and 0.5.3 in June 2024, and the last push was on 2026-06-05. That is a research library rather than a frequently patched product, so check the version you have against the paper you are reproducing before assuming a fix landed. A LICENSE file sits at the root next to CITATION.cff and CODE_OF_CONDUCT.md, though the README does not name the licence, so read the file if that matters for your use.

## Conclusion

Adopt pygmtools if your problem is the assignment itself, aligning nodes between two graphs or many, and you want a differentiable solver next to an exact one so you can compare them in the same code. Do not reach for it to store or draw graphs, since networkx is a dependency here rather than a substitute, and do not expect the GPU backends to be installed for you. Verify first which solver family your problem needs, because the two-graph, multi-graph and neural modules expose different classes and mixing them is manual work.

## FAQ

### How do I install pygmtools?

pip install pygmtools takes the stable release from PyPI. For the development version the README points at pip install -U with the master.zip archive from GitHub, and notes --user for an install without root. pip pulls requests, scipy, Pillow, numpy, easydict, appdirs, tqdm, networkx, aiohttp and async-timeout automatically.

### Which pygmtools backend should I use?

numpy is the default and is CPU only. PyTorch, Jittor, PaddlePaddle, TensorFlow and MindSpore are GPU friendly and deep learning friendly, and you install each by following that project's own instructions since the package declares no extras. The API is the same across all of them.

### What is the difference between the Sinkhorn and Hungarian solvers in pygmtools?

Both are linear assignment solvers for two graphs, but Sinkhorn is differentiable and soft while Hungarian is exact. For quadratic assignment the same split appears: spectral graph matching and the random-walk based solver are soft and differentiable, and the integer projected fixed point method is discrete.

### Where do the pretrained models for the neural solvers come from?

They are downloaded automatically from a hosted model repository the first time a solver needs them. If the automatic download fails, the README says to put the files at ~/.cache/pygmtools on Linux, and it lists mirrors on HuggingFace, Google Drive and Baidu drive.

### Is pygmtools a replacement for NetworkX?

No. networkx is a required dependency of pygmtools at version 2.8.8 or newer. pygmtools solves the correspondence problem between graphs, while networkx is what you use to build, store and analyse the graph you then match.

## Sources

- [Issues](https://github.com/Thinklab-SJTU/pygmtools/issues)
- [Project website](https://pygmtools.readthedocs.io/)
- [README](https://github.com/Thinklab-SJTU/pygmtools/blob/main/README.md)
- [Releases](https://github.com/Thinklab-SJTU/pygmtools/releases)
- [Thinklab-SJTU/pygmtools on GitHub](https://github.com/Thinklab-SJTU/pygmtools)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/thinklab-sjtu-pygmtools
