Skip to content

Commit 964bca4

Browse files
authored
Merge pull request #309 from zaz/support-cu128
Support CUDA 12.8
2 parents 70959fc + 9741e93 commit 964bca4

11 files changed

Lines changed: 95 additions & 33 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ TopoBench now uses [**uv**](https://docs.astral.sh/uv/), an extremely fast Pytho
6767
3. **Initialize Environment**:
6868
Use our centralized setup script to handle Python 3.11 virtualization and specialized hardware (CUDA) mapping.
6969
```bash
70-
# Usage: source uv_env_setup.sh [cpu|cu118|cu121]
70+
# Usage: source uv_env_setup.sh [cpu|cu118|cu121|cu128]
7171
source uv_env_setup.sh cpu
7272
```
7373
*This script performs the following:*

pyproject.toml

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ classifiers = [
2626
requires-python = ">=3.11, <3.12"
2727

2828
dependencies=[
29-
"torch==2.3.0",
29+
"torch>=2.3.0",
3030
"tqdm",
3131
"charset-normalizer",
3232
"numpy",
@@ -56,12 +56,16 @@ dependencies=[
5656
"topomodelx @ git+https://github.com/pyt-team/TopoModelX.git",
5757
"toponetx @ git+https://github.com/pyt-team/TopoNetX.git@c378925",
5858
"lightning==2.4.0",
59+
]
60+
61+
[project.optional-dependencies]
62+
# Required for NSD, ED-GNN, and point cloud lifting backbones.
63+
# Wheels must match your PyTorch + CUDA version; see find-links below.
64+
sparse = [
5965
"torch-scatter",
6066
"torch-sparse",
6167
"torch-cluster",
6268
]
63-
64-
[project.optional-dependencies]
6569
doc = [
6670
"jupyter",
6771
"nbsphinx",
@@ -87,7 +91,7 @@ test = [
8791
]
8892

8993
dev = ["TopoBench[test, lint]"]
90-
all = ["TopoBench[dev, doc]"]
94+
all = ["TopoBench[dev, doc, sparse]"]
9195

9296
[project.urls]
9397
homepage="https://geometric-intelligence.github.io/topobench/index.html"
@@ -112,21 +116,22 @@ name = "pytorch-cu121"
112116
url = "https://download.pytorch.org/whl/cu121"
113117
explicit = true
114118

119+
[[tool.uv.index]]
120+
name = "pytorch-cu128"
121+
url = "https://download.pytorch.org/whl/cu128"
122+
explicit = true
123+
115124
# Default find-links (will be overwritten by bash script)
116125
[tool.uv]
117126
find-links = ["https://data.pyg.org/whl/torch-2.3.0+cu121.html"]
127+
no-build-package = ["torch-scatter", "torch-sparse", "torch-cluster"]
118128

119129
[tool.uv.sources]
120130
torch = [
121131
{ index = "pytorch-cpu", marker = "sys_platform == 'darwin' or sys_platform == 'win32'" },
122132
{ index = "pytorch-cu121", marker = "sys_platform == 'linux'" },
123133
]
124134

125-
[tool.uv.extra-build-dependencies]
126-
torch-cluster = ["torch==2.3.0"]
127-
torch-scatter = ["torch==2.3.0"]
128-
torch-sparse = ["torch==2.3.0"]
129-
130135
# ==============================================================================
131136
# TOOL CONFIGS
132137
# ==============================================================================
@@ -172,7 +177,7 @@ disable_error_code = ["import-untyped"]
172177
plugins = "numpy.typing.mypy_plugin"
173178

174179
[[tool.mypy.overrides]]
175-
module = ["torch_cluster.*","networkx.*","scipy.spatial","scipy.sparse","toponetx.classes.simplicial_complex"]
180+
module = ["torch_cluster.*","torch_sparse.*","torch_scatter.*","networkx.*","scipy.spatial","scipy.sparse","toponetx.classes.simplicial_complex"]
176181
ignore_missing_imports = true
177182

178183
[tool.pytest.ini_options]

test/test_import.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Tests for package import behavior."""
2+
3+
import subprocess
4+
import sys
5+
6+
7+
def test_import_without_sparse():
8+
"""Verify topobench imports without torch_sparse/scatter/cluster.
9+
10+
Runs in a subprocess that blocks the sparse imports via sys.modules
11+
to avoid modifying the test environment.
12+
"""
13+
result = subprocess.run(
14+
[
15+
sys.executable,
16+
"-c",
17+
"import sys;"
18+
"sys.modules['torch_sparse'] = None;"
19+
"sys.modules['torch_scatter'] = None;"
20+
"sys.modules['torch_cluster'] = None;"
21+
"import topobench;"
22+
"from topobench.nn.backbones.graph import BACKBONE_CLASSES;"
23+
"from topobench.nn.backbones.hypergraph import BACKBONE_CLASSES;"
24+
"print('ok')",
25+
],
26+
capture_output=True,
27+
text=True,
28+
)
29+
assert result.returncode == 0, (
30+
f"import topobench failed without sparse packages:\n{result.stderr}"
31+
)
32+
assert "ok" in result.stdout

topobench/data/utils/io_utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import torch_geometric
1313
from toponetx.classes import SimplicialComplex
1414
from torch_geometric.data import Data
15-
from torch_sparse import coalesce
1615

1716
from topobench.data.utils import get_complex_connectivity
1817

@@ -370,6 +369,8 @@ def load_hypergraph_pickle_dataset(data_dir, data_name):
370369
torch_geometric.data.Data
371370
Hypergraph dataset.
372371
"""
372+
from torch_sparse import coalesce
373+
373374
data_dir = osp.join(data_dir, data_name)
374375

375376
# Load node features:
@@ -478,6 +479,8 @@ def load_hypergraph_content_dataset(data_dir, data_name):
478479
torch_geometric.data.Data
479480
Hypergraph dataset.
480481
"""
482+
from torch_sparse import coalesce
483+
481484
# data_dir = osp.join(data_dir, data_name)
482485

483486
p2idx_features_labels = osp.join(data_dir, f"{data_name}.content")

topobench/dataloader/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import torch
77
import torch_geometric
8-
from torch_sparse import SparseTensor
98

109

1110
class DomainData(torch_geometric.data.Data):
@@ -70,6 +69,8 @@ def to_data_list(batch):
7069
list
7170
List of data objects.
7271
"""
72+
from torch_sparse import SparseTensor
73+
7374
for key, _ in batch:
7475
if batch[key].is_sparse:
7576
sparse_data = batch[key].coalesce()

topobench/nn/backbones/graph/nsd_utils/inductive_discrete_models.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
import torch
1414
import torch.nn.functional as F
15-
import torch_sparse
1615
from torch import nn
1716

1817
from .laplacian_builders import (
@@ -102,6 +101,8 @@ def forward(self, x, edge_index):
102101
torch.Tensor
103102
Output node features of shape [num_nodes, output_dim].
104103
"""
104+
import torch_sparse
105+
105106
# Get actual number of nodes dynamically
106107
actual_num_nodes = x.size(0)
107108

@@ -281,6 +282,8 @@ def forward(self, x, edge_index):
281282
torch.Tensor
282283
Output node features of shape [num_nodes, output_dim].
283284
"""
285+
import torch_sparse
286+
284287
# Get actual number of nodes dynamically
285288
actual_num_nodes = x.size(0)
286289

@@ -453,6 +456,8 @@ def forward(self, x, edge_index):
453456
torch.Tensor
454457
Output node features of shape [num_nodes, output_dim].
455458
"""
459+
import torch_sparse
460+
456461
# Get actual number of nodes dynamically
457462
actual_num_nodes = x.size(0)
458463

topobench/nn/backbones/graph/nsd_utils/laplacian_builders.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import torch
1515
from torch import nn
1616
from torch_geometric.utils import degree
17-
from torch_scatter import scatter_add
1817

1918
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
2019
from .laplace import (
@@ -170,6 +169,8 @@ def forward(self, maps):
170169
saved_tril_maps : torch.Tensor
171170
Saved lower triangular restriction maps for analysis.
172171
"""
172+
from torch_scatter import scatter_add
173+
173174
assert len(maps.size()) == 2
174175
assert maps.size(1) == self.d
175176
left_idx, right_idx = self.left_right_idx
@@ -352,6 +353,8 @@ def forward(self, maps):
352353
saved_tril_maps : torch.Tensor
353354
Saved lower triangular transport maps for analysis.
354355
"""
356+
from torch_scatter import scatter_add
357+
355358
left_idx, right_idx = self.left_right_idx
356359
tril_row, tril_col = self.vertex_tril_idx
357360
tril_indices, diag_indices = self.tril_indices, self.diag_indices

topobench/nn/backbones/hypergraph/edgnn.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import torch.nn as nn
66
import torch.nn.functional as F
77
import torch_geometric
8-
import torch_scatter
98

109

1110
class EDGNN(nn.Module):
@@ -482,6 +481,8 @@ def forward(self, X, vertex, edges, X0):
482481
Tensor
483482
Output features.
484483
"""
484+
import torch_scatter
485+
485486
N = X.shape[-2]
486487

487488
Xve = self.W1(X)[..., vertex, :] # [nnz, C]
@@ -562,6 +563,8 @@ def forward(self, X, vertex, edges, X0, beta=1.0):
562563
Tensor
563564
Output features.
564565
"""
566+
import torch_scatter
567+
565568
N = X.shape[-2]
566569

567570
Xve = X[..., vertex, :] # [nnz, C]
@@ -666,6 +669,8 @@ def forward(self, X, vertex, edges, X0):
666669
Tensor
667670
Output features.
668671
"""
672+
import torch_scatter
673+
669674
N = X.shape[-2]
670675

671676
Xve = self.W1(X[..., vertex, :]) # [nnz, C]

topobench/transforms/liftings/pointcloud2hypergraph/pointnet_lifting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import torch
44
import torch_geometric
5-
from torch_cluster import fps, radius
65

76
from topobench.transforms.liftings.pointcloud2hypergraph.base import (
87
PointCloud2HypergraphLifting,
@@ -45,6 +44,7 @@ def lift_topology(self, data: torch_geometric.data.Data) -> dict:
4544
dict
4645
The lifted topology.
4746
"""
47+
from torch_cluster import fps, radius
4848

4949
batch = (
5050
torch.zeros(data.num_nodes, dtype=torch.long)

topobench/transforms/liftings/pointcloud2hypergraph/voronoi_lifting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import torch
44
import torch_geometric
5-
from torch_cluster import fps, knn
65

76
from topobench.transforms.liftings.pointcloud2hypergraph.base import (
87
PointCloud2HypergraphLifting,
@@ -37,6 +36,7 @@ def lift_topology(self, data: torch_geometric.data.Data) -> dict:
3736
dict
3837
The lifted topology.
3938
"""
39+
from torch_cluster import fps, knn
4040

4141
# Sample FPS induced Voronoi graph
4242
support_idcs = fps(data.x, ratio=self.support_ratio)

0 commit comments

Comments
 (0)