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

702 stars73 forksJupyter NotebookNOASSERTION

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?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
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 September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE 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 in the material. 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. Nothing in the material suggests a general-purpose spectral toolkit for arbitrary manifolds, and nothing suggests a non-PyTorch path. 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, and the metadata discrepancy is a documentation problem rather than a licensing one as far as the supplied material shows.

Upgrade cost and release cadence

Three releases are listed in the supplied material: 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.

Official sources

  1. Issues
  2. NVIDIA/torch-harmonics on GitHub
  3. README
  4. Releases
Community notes

Community notes