Skip to content

Add torch 2.9/2.10/2.12 support via torch-geometric 2.8 - #916

Draft
sevmag wants to merge 2 commits into
graphnet-team:mainfrom
sevmag:feat/torch-29-212-tg28
Draft

Add torch 2.9/2.10/2.12 support via torch-geometric 2.8#916
sevmag wants to merge 2 commits into
graphnet-team:mainfrom
sevmag:feat/torch-29-212-tg28

Conversation

@sevmag

@sevmag sevmag commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds torch-29, torch-210, and torch-212 extras (torch 2.9.1 / 2.10.0 / 2.12.1), enabled by simultaneously moving these extras to torch-geometric==2.8.* — plus fixes for two latent graphnet bugs the new stack exposed.

Why torch-geometric 2.8 is the key

torch-geometric 2.8 rewrote knn_graph/radius_graph to run on pyg-lib>=0.6.0 (torch.ops.pyg.knn/radius) and dropped the torch-cluster backend — and pyg-lib >=0.6.0 wheels exist for all torch >=2.8. This resolves the reason for the existing torch-geometric<2.8 cap, which stays in place for the older extras (their torch versions have no compatible pyg-lib). The new extras therefore drop torch_cluster (superseded by pyg-lib) and torch_spline_conv (never imported by graphnet).

Wheel availability at data.pyg.org (why the ceiling is 2.12.1)

torch pyg_lib torch_scatter/sparse torch_cluster torch_spline_conv
≤2.10
2.11
2.12.x
2.13/2.14

torch_scatter/torch_sparse are still imported directly by graphnet models, so 2.12.1 is the highest reachable version without migrating those imports to torch_geometric.utils.scatter/native ops — left for a follow-up.

Latent bugs exposed by the backend swap (fixed here)

The first CI run failed two icetray-job tests. Both turned out to be pre-existing graphnet bugs that the knn-backend change surfaced, reproduced and verified in the icecube/icetray:icetray-devel-v1.13.0 container:

  1. cleaning_module._split_pulsemap_in_dom_types: iterating an I3Map yields OMKeys (not key/value pairs), and OMKey is itself indexable (om_key[0] is the string number), so the P[0]-style unpacking raised TypeError: Invalid index type on the first non-empty cleaned pulsemap. The loop body had never executed in CI — the QUESO test model cleaned away every pulse in the tiny test file, and pyg-lib's different knn tie-breaking now lets pulses survive the threshold. Fixed by iterating items(); correct on the old stack too.

  2. KNNEdges/RadialEdges on empty events: pyg-lib's knn/radius kernels segfault on empty input when batch is None (knn_graph(torch.rand(0, 3), k=8) reproduces it; with an explicit batch tensor it is fine — worth an upstream pyg-lib report). An empty event inside a DataLoader worker is exactly this call, killing the worker (DataLoader worker ... killed by signal: Segmentation fault). Not icetray-specific — the ERDA test just only runs in the icetray job. Fixed with an explicit empty edge_index guard, matching torch-cluster's behaviour.

Changes

  • setup.py: three new extras; existing extras untouched.
  • src/graphnet/deployment/icecube/cleaning_module.py, src/graphnet/models/data_representation/graphs/edges/edges.py: the two fixes above.
  • .github/workflows/build.yml: icetray and macOS jobs on 2.10.0, Ubuntu examples matrix on 2.12.1/2.10.0/2.9.1. pip show torch-clusterpip show pyg-lib (the step runs under bash -e, and torch-cluster is no longer installed).
  • .github/actions/install/action.yml: extended the documented torch_version/hardware option lists (cu128/cu130/cu132).
  • docs/source/installation/quick-start.html: picker offers the new versions with their CUDA flavors (verified against the published wheel indexes: 2.9.1/2.10.0 → cu126/cu128/cu130, 2.12.1 → cu126/cu130/cu132); unsupported torch/CUDA pairs are now derived from the install-command map instead of a hand-maintained blacklist. The optional jammy_flows line also gets the numpy<2 constraint from Fix IceTray CI: keep numpy<2 in the jammy_flows install resolve #914.

Validation

  • Examples matrix (2.9.1/2.10.0/2.12.1), macOS, docs: green on the first CI run already.
  • The two icetray failures were reproduced in the v1.13.0 container on a local cluster, root-caused as above, and both tests pass there with the fixes (alone and in CI test ordering, torch 2.10.0 + tg 2.8).
  • Behavioral note: the knn backend changes from torch-cluster to pyg-lib; semantics are equivalent up to tie-breaking among equidistant neighbors.

🤖 Generated with Claude Code

https://claude.ai/code/session_014H5hSfPGXaV5aabm1g45oH

sevmag and others added 2 commits September 11, 2026 11:25
torch-geometric 2.8 runs knn_graph/radius_graph on pyg-lib>=0.6.0
instead of torch-cluster, and pyg-lib>=0.6.0 wheels exist for all
torch>=2.8, so the new extras pin torch-geometric==2.8.* and drop
torch-cluster along with the never-imported torch-spline-conv. The
older extras keep torch-geometric<2.8, which cannot work on their
torch versions. torch-scatter and torch-sparse stay required by
graphnet code; their wheels end at torch 2.12.1, the current ceiling.

CI exercises the new stack (icetray and macOS on 2.10.0, examples on
2.12.1/2.10.0/2.9.1), and the docs install picker gains the new
versions with unsupported torch/CUDA pairs derived from the
install-command map instead of a separate blacklist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014H5hSfPGXaV5aabm1g45oH
cleaning_module: iterating an I3Map yields OMKeys (not key/value
pairs), and OMKey is itself indexable, so the P[0]-style unpacking in
_split_pulsemap_in_dom_types produced 'Invalid index type' on the first
non-empty cleaned pulsemap. Iterate items() instead. The loop body had
never executed in CI: the QUESO test model cleaned away every pulse in
the test file, and the pyg-lib knn backend's different tie-breaking now
lets pulses survive the threshold.

KNNEdges/RadialEdges: pyg-lib's knn/radius kernels segfault on empty
input when batch is None, which is what an empty event produces inside
a DataLoader worker. Return an explicit empty edge_index for empty
graphs, matching torch-cluster's behaviour.

Verified in the icetray v1.13.0 container on torch 2.10.0: both
previously failing tests pass, alone and in CI ordering.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014H5hSfPGXaV5aabm1g45oH
@sevmag
sevmag force-pushed the feat/torch-29-212-tg28 branch from cf39301 to cafef32 Compare September 11, 2026 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant