# PyPose promises an efficiency comparison against Theseus and then shows no numbers

> A PyTorch library for differentiable robotics whose README points at a benchmark chart that is not on the page, dates its sparse Jacobian feature to a month after the tag that introduced it, and declares a Python floor of 3.6 in a guard copied from another project.

**pypose/pypose** — A library for differentiable robotics on manifolds.

- Repository: https://github.com/pypose/pypose
- Website: https://pypose.org
- Stars: 1,614 · Forks: 133
- Language: Python
- License: Apache-2.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/pypose-pypose

## The comparison chart promised here is not on this page

The efficiency claim is the one performance statement in the README, and it is stated without any numbers attached. The page says PyPose supports parallel computing for the Jacobian of Lie groups and Lie algebras and tells the reader to see the following comparison. The next line says it is an efficiency and memory comparison of batched Lie group operations, and adds the one methodological detail available: Theseus performance is taken as 1x.

Then the table is not there. What follows is a link to the paper for efficiency comparison, and then the installation section. So the normalization baseline is given, the metric is named, and the figures are somewhere else, presumably in the paper linked a line later.

That ordering is worth noting because a reader skimming for the claim finds the confident part first and the evidence second, or not at all. Nothing on the page says whether the comparison covers Jacobians only or Jacobians plus forward passes, whether memory means peak resident size per batch, or which PyTorch and CUDA versions were involved. For a library whose selling point is that its batched operations are cheap, that is the one measurement a reader would want to see before installing anything.

## A May 2026 feature attributed to a tag published in April

The third example carries a dated note. It reads May 2026, and says that starting from v0.9.5 PyPose introduces sparse Jacobian tracing for sparse second-order optimization, with bundle adjustment named as the kind of application it accelerates.

The tag says otherwise. v0.9.5 is dated 2026-04-12, which is before May, and v0.9.0 came four days earlier on 2026-04-08. Five patch versions inside four days is also a cadence worth noticing, since it suggests a release made to close an open issue rather than a steady version train. Either the note's month is wrong, or the feature was merged into the default branch after the tag that the note credits for it. In the second case the two statements are both true and a reader who installs 0.9.5 from a package index does not get the feature the README attributes to it.

The repository's own dates add a third data point. The last push to the default branch is 2026-09-03, which leaves v0.9.5 as the newest published version for close to six months, with the preceding release before it at v0.7.5 from 2025-12-21.

## The examples import a solver, a strategy and a scheduler the feature list never names

The feature list is grouped into LieTensor, Modules and Second-order Optimizers, and each group ends with an ellipsis. The optimizer group names exactly two entries, GaussNewton and LevenbergMarquardt.

The examples then use more than that. The second one imports LM from `pypose.optim`, Constant from `pypose.optim.strategy`, and StopOnPlateau from `pypose.optim.scheduler`. The third imports LM, PCG from `pypose.optim.solver`, TrustRegion from `pypose.optim.strategy`, StopOnPlateau from `pypose.optim.scheduler`, and `psjac` from `pypose.autograd.function`. None of PCG, TrustRegion, StopOnPlateau, Constant or psjac appears anywhere in the feature list, and neither does the `autograd` subpackage.

The examples directory matches the feature list rather than the examples. It contains `lietensor/` and `module/` directories plus a readme, so the optimizer half of the library, including the sparse Jacobian work that is the current headline, has no example directory of its own.

The module list has the same shape, with system modules LTI, LTV and NLS, filters EKF, UKF and PF, an EPnP solver, an LQR, and an IMU preintegrator. That is a state estimation toolkit living beside an optimizer in the same import root, which is a design choice worth naming before anyone assumes the two halves share conventions.

## The prose calls two things schedulers while one of them imports as a strategy

The second example is introduced with a sentence saying two usage options for a scheduler are provided, each of which can work independently. The code below it imports Constant from the strategy subpackage and StopOnPlateau from the scheduler subpackage. So the word the sentence uses does not match the module one of the two comes from.

Whether that is a naming problem or a documentation problem depends on what those objects do, and the page does not say. What it does show is the shape: `pypose.optim` is a package with subpackages for solver, strategy and scheduler, and the constructor arguments that tune a run are objects from two of them.

The API is deliberately doubled, which the first example shows explicitly. A rotation is written as `r.Exp()`, and the comment beside it says the same thing is available as `R = pp.Exp(r)`. Random Lie algebra tensors are made by module-level constructors such as `pp.randn_so3`, and parameters are wrapped with `pp.Parameter`. Both spellings exist throughout, which is convenient inside a PyTorch model and doubles the surface a reader has to learn.

One detail is worth copying exactly when writing against this API: parameters take a keyword argument named `sjac`, set to true for sparse Jacobian tracing in the third example.

## Two examples stop mid-line and neither BibTeX entry can be copied

Of the three code samples, one is complete. The first ends after a batched point rotation, with its output shown. The second ends at `invnet = InvNet(2,`, an unfinished constructor call. The third ends on a decorator line reading `@psjac  # par`, with the word after the hash cut off. Neither truncated sample shows a loss, an optimizer step or a loop, which are the parts a reader needs in order to see how a second-order solve is actually driven.

The citation section has the same problem, and it matters more for anyone who has to comply with a request for citations. Two papers are required: one for the library itself, and one more if the work uses the sparse Jacobian, the GPU sparse linear algebra, the conjugate gradient solver, or the sparse LevenbergMarquardt optimizer. The first BibTeX block ends partway down an author list, and the second begins with an entry key of `z` and stops almost immediately.

So the page states a two-paper citation obligation and then supplies neither entry in a usable form. The arXiv identifiers are printed as links for both, which is the only path to a complete citation from this page.

## The Python floor is 3.6 and the guard's own comment belongs to kornia

The setup script opens with a version check that raises a runtime error on anything older than 3.6.0, and the comment above it says to make sure that kornia is running on Python 3.6.0 or later, citing a Python bug tracker issue. PyPose is a PyTorch library with nothing to do with kornia, so the guard is carried over from another project's setup script. The declared floor in the package metadata is the same 3.6.

Three install paths are offered. The package index path is one command, `pip install pypose`. The source path asks for PyTorch to be installed first on Ubuntu, macOS or Windows, with no version stated for it, then:

```bash
pip install -r requirements/runtime.txt
```

followed by a clone and an editable install:

```bash
git clone  https://github.com/pypose/pypose.git
cd pypose && pip install -e .
```

and a test run:

```bash
pytest
```

The gap between a declared floor of 3.6 and a dependency on a current PyTorch is left unstated. Anyone on a modern interpreter will satisfy both, and anyone reading the floor as a support statement will be misled about how old the supported range really is.

## The version is regexed out of a source file and comments become requirements

Two details in the setup script will bite anyone building from a fork or vendoring the package. The version is not written in the setup script. It is read from `pypose/_version.py` with a regular expression anchored to a line of the form `__version__ = '...'`, and a version file that does not match that pattern fails the build with a runtime error rather than a sensible default.

The extras loader reads `requirements/runtime.txt` and `requirements/docs.txt` and builds an `all` extra as the union of the two. Each line is stripped of whitespace and kept unless its first two raw characters are `-r`, which is how nested requirement files are skipped. Because the filter looks at the unstripped line, a comment or a blank line is not skipped and becomes an entry in the extras list, and pip receives it as a requirement string. The `-r` check also misses an indented include.

The test tooling is declared the old way, with `setup_requires` set to pytest-runner and `tests_require` set to pytest. On older setuptools, a build requirement is fetched during the build itself rather than installed by the user, and both fields have been deprecated for years in favour of extras. Combined with the version regex and the comment filter, this is a setup script that has not been revisited since the early days of the project, even though the library itself is being developed.

## Conclusion

PyPose earns its place for anyone already inside PyTorch who needs batched Lie group operations with gradients that reach the optimizer, and the sparse Jacobian work from v0.9.5 is the reason to look now. Before adopting it, read the source rather than the README: the feature list stops at ellipses, two of the three examples stop mid-line, the efficiency claim has no table behind it, and the setup script declares support for Python 3.6 while its own guard comment belongs to a different library.

## FAQ

### What is PyPose used for?

It is a robotics-oriented PyTorch library that combines deep perceptual models with physics-based optimization. LieTensor covers the groups SO3, SE3, Sim3 and RxSO3, modules cover LTI, LTV, NLS, EKF, UKF, PF, an EPnP solver, an LQR and IMU preintegration, and the optimizers include GaussNewton and LevenbergMarquardt.

### How do I install PyPose?

From a package index with pip install pypose, or from source after installing PyTorch: pip install -r requirements/runtime.txt, then clone the repository, change into it and run pip install -e ., then run pytest to check the installation.

### Does PyPose support sparse Jacobians and batched second-order optimization?

The README claims parallel computing for the Jacobian of Lie groups and Lie algebras, and says v0.9.5 introduced sparse Jacobian tracing. The sparse example enables it with sjac=True on pp.Parameter and applies a psjac decorator imported from pypose.autograd.function.

### Which papers do I have to cite when using PyPose?

The library's own paper, arXiv 2209.15428, and additionally arXiv 2409.12190 if your work uses the sparse Jacobian, the GPU sparse linear algebra, the conjugate gradient solver or the sparse LevenbergMarquardt optimizer. The BibTeX entries on the README page are both incomplete.

### What Python version does PyPose require?

The setup script raises PyPose requires Python 3.6.0 or later below 3.6, and the package metadata declares the same floor. PyTorch is installed separately beforehand and no version for it is stated anywhere on the page.

## Sources

- [License: Apache-2.0](https://github.com/pypose/pypose/blob/main/LICENSE)
- [Project website](https://pypose.org)
- [pypose/pypose on GitHub](https://github.com/pypose/pypose)
- [README](https://github.com/pypose/pypose/blob/main/README.md)
- [Releases](https://github.com/pypose/pypose/releases)

---

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