Open-source project
NVIDIA/torch-harmonics avatar
NVIDIA/torch-harmonics

torch-harmonics: differentiable spherical harmonic transforms in PyTorch

Differentiable signal processing on the sphere for PyTorch

729 stars80 forksJupyter NotebookBSD-3-Clause

At a glance

What is it?
torch-harmonics packages the spherical harmonic transform, its vector counterpart and discrete-continuous convolutions on the sphere as differentiable PyTorch operations. It is a research-grade building block for geophysical and PDE work on spherical domains, and the wheel matrix is the first thing to check before you commit.
Who is it for?
Adopt torch-harmonics if your model already lives in PyTorch and you need spherical harmonic transforms or sphere convolutions inside an autograd graph, and if your CUDA and PyTorch versions match one of the four published wheel rows. Do not adopt it if you only need a one-off spectral transform on a CPU grid, or if you are pinned to a PyTorch release outside those rows and are unwilling to compile.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • NVIDIA/torch-harmonics729 ★ · +27
Star history
Repository2026-09-112026-11-13
NVIDIA/torch-harmonics702729

27 Stars in the last 63 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The gap torch-harmonics fills: spectral operators that sit inside an autograd graph

Most spherical harmonic code is written as a numerical library: you hand it a grid, it hands you coefficients, and the operation is opaque to whatever trained the model. That is fine for post-processing and useless for training. torch-harmonics takes the opposite position. The README states the package implements differentiable signal processing on the sphere, covering spherical harmonic transforms, vector spherical harmonic transforms and discrete-continuous convolutions, and it says these are built from PyTorch primitives so the whole path is differentiable. The stated motivation is that the package was originally implemented to enable Spherical Fourier Neural Operators, which is the clearest signal of the intended user: someone building a neural operator or a differentiable PDE solver whose state lives on a sphere. Weather, climate and geophysical simulation are the obvious fits. If your data is a latitude-longitude grid and your model needs to move between grid space and harmonic space repeatedly during training, this is the layer you were going to write yourself.

Quadrature plus FFTs: the mechanism the README actually describes

The transform algorithm is described in two sentences and they are worth reading carefully. According to the README, the SHT uses quadrature rules to compute the projection onto the associated Legendre polynomials and FFTs for the projection onto the harmonic basis. So the work splits into a Legendre projection handled by quadrature and a longitudinal projection handled by FFT. The README also claims this algorithm tends to outperform others with better asymptotic scaling for most practical purposes, citing reference [2], but it gives no numbers, no complexity class and no benchmark table. Treat that as a design claim, not a measurement. The second architectural fact is more concrete: the quadrature can be distributed onto multiple ranks, making it spatially distributed. That is the part that matters at scale, because the Legendre projection is the expensive stage and the README places it under the distributed path rather than the FFT stage. The repository is primarily Jupyter Notebook, which tells you the reference material is tutorial-shaped. Expect to read notebooks to learn the calling conventions rather than a generated API reference.

Installation is a version-matching exercise, not a single pip command

There is no single install line that works everywhere, and the README is explicit about why. Prebuilt Linux wheels with compiled CUDA extensions live on pypi.nvidia.com and are split by toolkit version. CUDA 12.6 maps to torch-harmonics-cu126 and PyTorch 2.6.0; 12.8 maps to torch-harmonics-cu128 and PyTorch 2.7.0; 12.9 maps to torch-harmonics-cu129 and PyTorch 2.8.0; 13.0 maps to torch-harmonics-cu130 and PyTorch 2.9.1. Each installs with the extra index, for example pip install torch-harmonics-cu129 --extra-index-url https://pypi.nvidia.com. The README suggests running nvidia-smi to check your driver's CUDA version, which is the right first step. If you do not care about a specific toolkit, the rolling aliases torch-harmonics-cuda-latest and torch-harmonics-cpu-latest exist. The plain torch-harmonics package on PyPI is CPU only and built for the newest PyTorch release, so installing it and expecting GPU kernels is a common and avoidable mistake. Building from source is the fallback when your OS, PyTorch or CUDA version is not covered, and the README recommends --no-build-isolation so custom CPU and CUDA kernels compile against your existing torch installation. For containers where CUDA devices are not auto-detected, set TORCH_HARMONICS_BUILD_CUDA_EXTENSION=1, and set TORCH_CUDA_ARCH_LIST to only the architectures you need to cut compile time.

The CUDA and PyTorch pairing is a real constraint, not a footnote

The wheel table is the sharpest limitation. Four CUDA rows, four PyTorch versions, one-to-one. If your cluster is on CUDA 12.4, or your training stack is pinned to PyTorch 2.5 for reasons outside your control, the prebuilt path is closed and you are compiling from source against custom kernels. That is a meaningful operational cost: it needs a matching toolchain, it takes time proportional to how many entries you leave in TORCH_CUDA_ARCH_LIST, and it has to be redone on every upgrade of either torch or the toolkit. The rolling aliases soften this but do not remove it, because a rolling alias tracks the newest build rather than your build. The second limitation is scope. The README frames the package around transforms and convolutions on the sphere. If your inference stack is not PyTorch, this is the wrong tool regardless of how good the transforms are. A third gap: the README gives no accuracy or convergence guidance for the quadrature, so the sampling requirements of your grid are something you will have to establish yourself from the cited literature.

Where torch-harmonics stops and a classical SHT library begins

The natural alternative is a classical spherical harmonic library, of the kind used in geodesy and atmospheric science, which computes transforms as standalone numerical routines. The difference is not accuracy, it is where the transform sits in your program. A classical library gives you a function you call between training steps; gradients do not flow through it, so a learned model that needs to operate in harmonic space has to be assembled around it, usually by treating the transform as a fixed pre- and post-processing stage. torch-harmonics inverts that: the transform is an operation in the graph, so a network can be defined partly in harmonic space and trained end to end. That is exactly the property Spherical Fourier Neural Operators need, and it is why the README names SFNO as the original motivation. The trade is that you inherit PyTorch's constraints, including the version pairing above, in exchange for differentiability. If your task is analysis rather than learning, the classical route has fewer moving parts.

Licensing and the NOASSERTION flag on the repository

The repository metadata reports the licence as NOASSERTION, which means the platform could not map the project to a recognised licence identifier. The README's own header resolves the ambiguity: the file carries an SPDX-License-Identifier of BSD-3-Clause, together with the full three-clause text, copyright 2022 The torch-harmonics Authors. The three clauses are the standard ones: source redistributions must retain the copyright notice, conditions list and disclaimer; binary redistributions must reproduce them in the documentation or other materials; and neither the copyright holder's nor contributors' names may be used to endorse or promote derived products without prior written permission. The disclaimer is the usual all-caps warranty exclusion. This is a permissive licence, but the mismatch between the repository field and the file header is worth resolving with your own legal review before you depend on it, particularly if you are redistributing a compiled wheel. Nothing here is legal advice.

Upgrade cost and release cadence

The releases include v0.9.0 in April 2026, v0.9.1 in May 2026 and v0.9.2 in August 2026, with the repository last pushed in September 2026. The version numbers are still in the 0.9 series, which is a reasonable signal that interfaces can move. The practical upgrade cost is dominated by the wheel matrix rather than by API churn. Because each CUDA wheel is tied to a specific PyTorch version, moving from torch-harmonics-cu126 to torch-harmonics-cu128 is not a version bump, it is a paired migration of both the toolkit and PyTorch. Plan for that as a scheduled change rather than something you do casually on a Friday. If you built from source, the same migration means recompiling the CPU and CUDA extensions against the new torch, with TORCH_CUDA_ARCH_LIST trimmed to the architectures your fleet actually uses so you are not paying for targets you will never run.

Editorial conclusion

Adopt torch-harmonics if your model already lives in PyTorch and you need spherical harmonic transforms or sphere convolutions inside an autograd graph, and if your CUDA and PyTorch versions match one of the four published wheel rows. Do not adopt it if you only need a one-off spectral transform on a CPU grid, or if you are pinned to a PyTorch release outside those rows and are unwilling to compile. Before writing any code, run nvidia-smi, pick the matching torch-harmonics-cuXXX package, and confirm the package metadata declares the same PyTorch version you have installed.

Frequently asked questions

How do I install the GPU build of torch-harmonics for CUDA 12.9?

Install the cu129 wheel, which is the row paired with PyTorch 2.8.0: `pip install torch-harmonics-cu129 --extra-index-url https://pypi.nvidia.com`.

Does the torch-harmonics package on PyPI include CUDA support?

No. The vanilla torch-harmonics package on PyPI ships a CPU-only prebuilt wheel built for the newest PyTorch release, and GPU support comes from the separate packages on pypi.nvidia.com.

What is the minimum Python version for torch-harmonics?

pyproject.toml sets requires-python to >=3.10, and the classifier list names Programming Language :: Python :: 3.10 as the only Python version.

Which license does torch-harmonics use?

Package metadata records no license name, while pyproject.toml points license at LICENSE.txt at the root and README.md, setup.py and the Dockerfile each carry an SPDX-License-Identifier line reading BSD-3-Clause.

What version number does a source build report if I download the ZIP instead of cloning with git?

A tree with no git metadata and no pre-generated version file falls back to the sentinel 0.0.0, which sorts below every real release and satisfies no >= constraint.

Official sources

  1. Issues
  2. NVIDIA/torch-harmonics on GitHub
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nvidia-torch-harmonics.svg)](https://hysenlabs.com/projects/nvidia-torch-harmonics)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/nvidia-torch-harmonics.svg)](https://hysenlabs.com/projects/nvidia-torch-harmonics)

Was this useful?