NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3990 most downloaded on PyPI
Graph Neural Network Library for PyTorch
Last release 2 months ago
20 Jul 2026
Release timing varies
gaps range from 8 days to 13 months
Most releases are documented
notes for 41 of 46 stable releases
1 version withdrawn
withdrawn after publishing
8 years old
47 releases · first in 2018
Deprecated contrib.explain.GraphMaskExplainer in favor of explain.algorithm.GraphMaskExplainer
We are excited to announce the release of PyG 2.4 🎉🎉🎉
PyG 2.4 is the culmination of work from 62 contributors who have worked on features and bug-fixes for a total of over 500 commits since torch-geometric==2.3.1.
torch.compile(dynamic=True) supportThe long wait has an end! With the release of PyTorch 2.1, PyG 2.4 now brings full support for torch.compile to graphs of varying size via the dynamic=True option, which is especially useful for use-cases that involve the usage of DataLoader or NeighborLoader. Examples and tutorials have been updated to reflect this support accordingly (#8134), and models and layers in torch_geometric.nn have been tested to produce zero graph breaks:
import torch_geometric
model = torch_geometric.compile(model, dynamic=True)When enabling the dynamic=True option, PyTorch will up-front attempt to generate a kernel that is as dynamic as possible to avoid recompilations when sizes change across mini-batches changes. As such, you should only ever not specify dynamic=True when graph sizes are guaranteed to never change. Note that dynamic=True requires PyTorch >= 2.1.0 to be installed.
PyG 2.4 is fully compatible with PyTorch 2.1, and supports the following combinations:
| PyTorch 2.1 | cpu |
cu118 |
cu121 |
|---|---|---|---|
| Linux | ✅ | ✅ | ✅ |
| macOS | ✅ | ||
| Windows | ✅ | ✅ | ✅ |
You can still install PyG 2.4 on older PyTorch releases up to PyTorch 1.11 in case you are not eager to update your PyTorch version.
OnDiskDataset InterfaceWe added the OnDiskDataset base class for creating large graph datasets (e.g., molecular databases with billions of graphs), which do not easily fit into CPU memory at once (#8028, #8044, #8046, #8051, #8052, #8054, #8057, #8058, #8066, #8088, #8092, #8106). OnDiskDataset leverages our newly introduced Database backend (sqlite3 by default) for on-disk storage and access of graphs, supports DataLoader out-of-the-box, and is optimized for maximum performance.
OnDiskDataset utilizes a user-specified schema to store data as efficient as possible (instead of Python pickling). The schema can take int, float str, object or a dictionary with dtype and size keys (for specifying tensor data) as input, and can be nested as a dictionary. For example,
dataset = OnDiskDataset(root, schema={
'x': dict(dtype=torch.float, size=(-1, 16)),
'edge_index': dict(dtype=torch.long, size=(2, -1)),
'y': float,
})creates a database with three columns, where x and edge_index are stored as binary data, and y is stored as a float.
Afterwards, you can append data to the OnDiskDataset and retrieve data from it via dataset.append()/dataset.extend(), and dataset.get()/dataset.multi_get(), respectively. We added a fully working example on how to set up your own OnDiskDataset here (#8102). You can also convert in-memory dataset instances to an OnDiskDataset instance by running InMemoryDataset.to_on_disk_dataset() (#8116).
One drawback of NeighborLoader is that it computes a representations for all sampled nodes at all depths of the network. However, nodes sampled in later hops no longer contribute to the node representations of seed nodes in later GNN layers, thus performing useless computation. NeighborLoader will be marginally slower since we are computing node embeddings for nodes we no longer need. This is a trade-off we have made to obtain a clean, modular and experimental-friendly GNN design, which does not tie the definition of the model to its utilized data loader routine.
With PyG 2.4, we introduced the option to eliminate this overhead and speed-up training and inference in mini-batch GNNs further, which we call "Hierarchical Neighborhood Sampling" (see here for the full tutorial) (#6661, #7089, #7244, #7425, #7594, #7942). Its main idea is to progressively trim the adjacency matrix of the returned subgraph before inputting it to each GNN layer, and works seamlessly across several models, both in the homogeneous and heterogeneous graph setting. To support this trimming and implement it effectively, the NeighborLoader implementation in PyG and in pyg-lib additionally return the number of nodes and edges sampled in each hop, which are then used on a per-layer basis to trim the adjacency matrix and the various feature matrices to only maintain the required amount (see the trim_to_layer method):
class GNN(torch.nn.Module):
def __init__(self, in_channels: int, out_channels: int, num_layers: int):
super().__init__()
self.convs = ModuleList([SAGEConv(in_channels, 64)])
for _ in range(num_layers - 1):
self.convs.append(SAGEConv(hidden_channels, hidden_channels))
self.lin = Linear(hidden_channels, out_channels)
def forward(
self,
x: Tensor,
edge_index: Tensor,
num_sampled_nodes_per_hop: List[int],
num_sampled_edges_per_hop: List[int],
) -> Tensor:
for i, conv in enumerate(self.convs):
# Trim edge and node information to the current layer `i`.
x, edge_index, _ = trim_to_layer(
i, num_sampled_nodes_per_hop, num_sampled_edges_per_hop,
x, edge_index)
x = conv(x, edge_index).relu()
return self.lin(x)Corresponding examples can be found here and here.
Additionally, we added support for weighted/biased sampling in NeighborLoader/LinkNeighborLoader scenarios. For this, simply specify your edge_weight attribute during NeighborLoader initialization, and PyG will pick up these weights to perform weighted/biased sampling (#8038):
data = Data(num_nodes=5, edge_index=edge_index, edge_weight=edge_weight)
loader = NeighborLoader(
data,
num_neighbors=[10, 10],
weight_attr='edge_weight',
)
batch = next(iter(loader))As part of our algorithm and documentation sprints (#7892), we have added:
MixHopConv: “MixHop: Higher-Order Graph Convolutional Architecturesvia Sparsified Neighborhood Mixing” (examples/mixhop.py) (#8025)LCMAggregation: “Learnable Commutative Monoids for Graph Neural Networks” (examples/lcm_aggr_2nd_min.py) (#7976, #8020, #8023, #8026, #8075)DirGNNConv: “Edge Directionality Improves Learning on Heterophilic Graphs” (examples/dir_gnn.py) (#7458)Performer in GPSConv: “Recipe for a General, Powerful, Scalable Graph Transformer” (examples/graph_gps.py) (#7465)PMLP: “Graph Neural Networks are Inherently Good Generalizers: Insights by Bridging GNNs and MLPs” (examples/pmlp.py) (#7470, #7543)RotateE: “RotatE: Knowledge Graph Embedding by Relational Rotation in Complex Space” (examples/kge_fb15k_237.py) (#7026)NeuralFingerprint: “Convolutional Networks on Graphs for Learning Molecular Fingerprints” (#7919)HM (#7515), BrcaTcga (#7994), MyketDataset (#7959), Wikidata5M (#7864), OSE_GVCS (#7811), MovieLens1M (#7479), AmazonBook (#7483), GDELTLite (#7442), IGMCDataset (#7441), MovieLens100K (#7398), EllipticBitcoinTemporalDataset (#7011), NeuroGraphDataset (#8112), PCQM4Mv2 (#8102)CaptumExplainer (examples/captum_explainer_hetero_link.py) (#7096)LightGCN on AmazonBook for recommendation (examples/lightgcn.py) (#7603)FeatureStore (examples/kuzu) (#7298)ogbn-papers100M (examples/papers100m_multigpu.py) (#7921)OGC model on Cora (examples/ogc.py) (#8168)graphlearn-for-pytorch (examples/distributed/graphlearn_for_pytorch) (#7402)Join our Slack here if you're interested in joining community sprints in the future!
Data.keys() is now a method instead of a property (#7629):
| <=2.3 | 2.4 |
|---|---|
data = Data(x=x, edge_index=edge_index)
print(data.keys)
# ['x', 'edge_index'] |
data = Data(x=x, edge_index=edge_index)
print(data.keys())
# ['x', 'edge_index'] |
FastHGTConv in favor of HGTConv (#7117)layer_type argument from GraphMaskExplainer (#7445)dest argument to dst in utils.geodesic_distance (#7708)contrib.explain.GraphMaskExplainer in favor of explain.algorithm.GraphMaskExplainer (#7779)Data and HeteroData improvements
HeteroData.validate() (#7995)HeteroData support in to_networkx (#7713)Data.sort() and HeteroData.sort() (#7649)HeteroData.to_homogeneous() in case feature dimensionalities do not match (#7374)torch.nested_tensor support in Data and Batch (#7643, #7647)keep_inter_cluster_edges option to ClusterData to support inter-subgraph edge connections when doing graph partitioning (#7326)Data-loading improvements
Dataset, e.g., dataset[:0.9] (#7915)save and load methods to InMemoryDataset (#7250, #7413)IBMBNodeLoader and IBMBBatchLoader data loaders (#6230)HyperGraphData to support hypergraphs (#7611)CachedLoader (#7896, #7897)NodeLoader and LinkLoader (#7572)PrefetchLoader capabilities (#7376, #7378, #7383)NodeLoader and LinkLoader (#7197)Better support for sparse tensors
SparseTensor support to WLConvContinuous, GeneralConv, PDNConv and ARMAConv (#8013)torch_sparse.SparseTensor logic to utilize torch.sparse_csr instead (#7041)torch.sparse.Tensor in DataLoader (#7252)torch.jit.script within MessagePassing layers without torch_sparse being installed (#7061, #7062)torch.sparse.Tensor (#7037)Data.num_edges for native torch.sparse.Tensor adjacency matrices (#7104)cross_entropy implementation (#7447, #7466)Integration with 3rd-party libraries
torch_geometric.transforms
HalfHop graph upsampling augmentation (#7827)Cartesian, LocalCartesian and Distance transformations (#7533, #7614, #7700)add_pad_mask argument to the Pad transform (#7339)NodePropertySplit transformation for creating node-level splits using structural node properties (#6894)AddRemainingSelfLoops transformation (#7192)HeteroConv for layers that have a non-default argument order, e.g., GCN2Conv (#8166)ModuleDict and ParameterDict (#8163)DynamicBatchSampler.__len__ to raise an error in case num_steps is undefined (#8137)DimeNet models (#8019)batch.e_id was not correctly computed on unsorted graph inputs (Note truncated.
One column per quarter.
ogc method as example (#8168)NeighborLoader (#7931)segment_matmul/grouped_matmul via the torch_geometric.backend.use_segment_matmul flag (#8148)NeuroGraphDataset benchmark collection (#8122)mask tensor in dense_to_sparse (#8117)to_on_disk_dataset() method to convert InMemoryDataset instances to OnDiskDataset instances (#8116)torch-frame support (#8110, #8118, #8151, #8152)DistLoader base class (#8079)HyperGraphData to support hypergraphs (#7611)PCQM4Mv2 dataset as a reference implementation for OnDiskDataset (#8102)module_headers property to nn.Sequential models (#8093)OnDiskDataset interface with data loader support (#8066, #8088, #8092, #8106)Node2Vec and MetaPath2Vec usage (#7938)edge_attr support to ResGatedGraphConv (#8048)Database interface and SQLiteDatabase/RocksDatabase implementations (#8028, #8044, #8046, #8051, #8052, #8054, #8057, #8058)NeighborLoader/LinkNeighborLoader (#8038)MixHopConv layer and an corresponding example (#8025)BasicGNN and MLP (#8024, #8033)IBMBNodeLoader and IBMBBatchLoader data loaders (#6230)NeuralFingerprint model for learning fingerprints of molecules (#7919)SparseTensor support to WLConvContinuous, GeneralConv, PDNConv and ARMAConv (#8013)LCMAggregation, an implementation of Learnable Communitive Monoids, along with an example (#7976, #8020, #8023, #8026, #8075)HeteroData.validate() (#7995)utils.cumsum implementation (#7994)BrcaTcga dataset (#7905)MyketDataset (#7959)ogbn-papers100M example (#7921)group_argsort implementation (#7948)CachedLoader implementation (#7896, #7897)utils.ppr for personalized PageRank computation (#7917)PrefetchLoader (#7918)Dataset, e.g., dataset[:0.9] (#7915)HalfHop graph upsampling augmentation (#7827)Wikidata5M dataset (#7864)BasicGNN models (#7865)batch_size argument to unbatch functionalities (#7851)graphlearn-for-pytorch (#7402)neg_sampling_ratio into TemporalDataLoader (#7644)faiss-based KNNINdex classes for L2 or maximum inner product search (#7842)OSE_GVCS dataset (#7811)output_initializer argument to DimeNet models (#7774, #7780)lexsort implementation (#7775)HeteroData support in to_networkx (#7713)FlopsCount support via fvcore (#7693)Data.sort() and HeteroData.sort() functionalities (#7649)torch.nested_tensor support in Data and Batch (#7643, #7647)interval argument to Cartesian, LocalCartesian and Distance transformations (#7533, #7614, #7700)LightGCN example on the AmazonBook dataset (7603)HypergraphConv via the attention_mode argument (#7601)FilterEdges graph coarsening operator (#7361)DirGNN model for learning on directed graphs (#7458)NodeLoader and LinkLoader (#7572)embedding_device option to allow for GPU inference in BasicGNN (#7548, #7829)Performer to GPSConv and remove attn_dropout argument from GPSConv (#7465)LinkNeighborLoader to return number of sampled nodes and edges per hop (#7516)HM personalized fashion recommendation dataset (#7515)GraphMixer model (#7501, #7459)disable_dynamic_shape experimental flag (#7246, #7534)MovieLens-1M heterogeneous dataset (#7479)map_index implementation (#7493, #7764 #7765)AmazonBook heterogeneous dataset (#7483)torch_geometric.distributed package (#7451, #7452), #7482, #7502, #7628, #7671, #7846, #7715, #7974)GDELTLite dataset (#7442)approx_knn function for approximated nearest neighbor search (#7421)IGMCDataset (#7441)cross_entropy implementation (#7447, #7466)MovieLens-100K heterogeneous dataset (#7398)PMLP model and an example (#7370, #7543)HeteroData.to_homogeneous() in case feature dimensionalities do not match (#7374)batch_size argument to fps, knn, knn_graph, radius and radius_graph (#7368)PrefetchLoader capabilities (#7376, #7378, #7383)add_pad_mask argument to the Pad transform (#7339)keep_inter_cluster_edges option to ClusterData to support inter-subgraph edge connections when doing graph partitioning (#7326)ModuleDict/ParameterDict (#7294)NodePropertySplit transform for creating node-level splits using structural node properties (#6894)CitationFull datasets (#7275)torch.sparse.Tensor in DataLoader (#7252)save and load methods to InMemoryDataset (#7250, #7413)CaptumExplainer (#7096)visualize_feature_importance functionality to HeteroExplanation (#7096)AddRemainingSelfLoops transform (#7192)optimizer_resolver (#7209)type_ptr argument to HeteroLayerNorm (#7208)"any"-reductions in scatter (#7198)NodeLoader and LinkLoader (#7197)torch.sparse support (#7155)LightGCN (#7157)SparseTensor support to trim_to_layer function (#7089)ComposeFilters class to compose pre_filter functions in Dataset (#7097)EllipticBitcoinDataset called EllipticBitcoinTemporalDataset (#7011)to_dgl and from_dgl conversion functions (#7053)torch.jit.script within MessagePassing layers without torch_sparse being installed (#7061, #7062)torch.sparse tensors (#7037)RotatE KGE model (#7026)HeteroConv for layers that have a non-default argument order, e.g., GCN2Conv (#8166)ModuleDict and ParameterDict (#8163)torch.compile(dynamic=True) in PyTorch 2.1.0 (#8145)AddLaplacianEigenvectorPE for small-scale graphs (#8143)DynamicBatchSampler.__len__ to raise an error in case num_steps is undefined (#8137)DimeNet models (#8019)trim_to_layer function to filter out non-reachable node and edge types when operating on heterogeneous graphs (#7942)top_k computation in TopKPooling (#7737)GIN implementation in kernel benchmarks to have sequential batchnorms (#7955)cache argument in heterogeneous models (#7956batch.e_id was not correctly computed on unsorted graph inputs (#7953)from_networkx conversion from nx.stochastic_block_model graphs (#7941)bias_initializer in HeteroLinear (#7923)HGBDataset (#7907)SetTransformerAggregation produced NaN values for isolates nodes (#7902)model_summary on modules with uninitialized parameters (#7884)QM9 data pre-processing to include the SMILES string (#7867)add_self_loops for a dynamic number of nodes (#7330)PNAConv.get_degree_histogram (#7830)edge_label_time when using temporal sampling on homogeneous graphs (#7807)torch_geometric.contrib.explain.GraphMaskExplainer to torch_geometric.explain.algorithm.GraphMaskExplainer (#7779)FieldStatus enum picklable to avoid PicklingError in a multi-process setting (#7808)edge_label_index computation in LinkNeighborLoader for the homogeneous+disjoint mode (#7791)CaptumExplainer for binary_classification tasks (#7787)training flag in to_hetero modules (#7772)HeteroData (#7714)dest argument to dst in utils.geodesic_distance (#7708)add_random_edge to only add true negative edges (#7654)BasicGNN models in DeepGraphInfomax (#7648)Data.keys a method rather than a property (#7629)num_edges parameter to the forward method of HypergraphConv (#7560)get_mesh_laplacian for normalization="sym" (#7544)dim_size to initialize output size of the EquilibriumAggregation layer (#7530)max_num_elements parameter to the forward method of GraphMultisetTransformer, GRUAggregation, LSTMAggregation and SetTransformerAggregation (#7529)SparseTensor (#7519)scaler tensor in GeneralConv to the correct device (#7484)HeteroLinear bug when used via mixed precision (#7473)output_size in the repeat_interleave operation in QuantileAggregation (#7426)utils.spmm (#7428)ClusterLoader to integrate pyg-lib METIS routine (#7416)QuantileAggregation when dim_size is passed (#7407)filter_per_worker option will not get automatically inferred by default based on the device of the underlying data (#7399)LightGCN.recommendation_loss() to only use the embeddings of the nodes involved in the current mini-batch (#7384)max_num_elements argument to SortAggregation (#7367)fill_value as a torch.tensor to utils.to_dense_batch (#7367)to_hetero_with_bases (#7363)node_default and edge_default attributes in from_networkx (#7348)NeighborLoader instead of NeighborSampler (#7152)HGTConv utility function _construct_src_node_feat (#7194)batch_size argument to avg_pool_x and max_pool_x (#7216)subgraph on unordered inputs (#7187)HeteroDictLinear (#7185)from_networkx memory footprint by reducing unnecessary copies (#7119)batch_size argument to LayerNorm, GraphNorm, InstanceNorm, GraphSizeNorm and PairNorm (#7135)numpy incompatiblity when reading files for Planetoid datasets (#7141)Data.num_edges for native torch.sparse.Tensor adjacency matrices (#7104)MultiAggregation (#7077)HeterophilousGraphDataset are now undirected by default (#7065)FastHGTConv that computed values via parameters used to compute the keys (#7050)torch_sparse.SparseTensor logic to utilize torch.sparse_csr instead (#7041)batch_size and max_num_nodes arguments to MemPooling layer (#7239)CaptumExplainer to be called multiple times in a row (#7391)Removed DeprecationWarning of TypedStorage usage in DataLoader
PyG 2.3.1 includes a variety of bugfixes.
cugraph GNN layer support for pylibcugraphops==23.04 (#7023)DeprecationWarning of TypedStorage usage in DataLoader (#7034)FastHGTConv that computed values via parameters used to compute the keys (#7050)numpy incompatiblity when reading files in Planetoid datasets (#7141)utils.subgraph on unordered inputs (#7187)Data.num_edges for native torch.sparse.Tensor adjacency matrices (#7104)Full Changelog: https://github.com/pyg-team/pytorch_geometric/compare/2.3.0...2.3.1
Breaking Change: Temporal sampling will now also sample nodes with an equal timestamp to the seed time (requires pyg-lib>0.1.0)
We are thrilled to announce the release of PyG 2.3 🎉
PyG 2.3 is the culmination of work from 59 contributors who have worked on features and bug-fixes for a total of over 470 commits since torch-geometric==2.2.0.
PyG 2.3 is fully compatible with the next generation release of PyTorch, bringing many new innovations and features such as torch.compile() and Python 3.11 support to PyG out-of-the-box. In particular, many PyG models and functions are speeded up significantly using torch.compile() in torch >= 2.0.0.
We have prepared a full tutorial and a set of examples to get you going with torch.compile() immediately:
import torch_geometric
from torch_geometric.nn import GraphSAGE
model = GraphSAGE(in_channels, hidden_channels, num_layers, out_channels)
model = model.to(device)
model = torch_geometric.compile(model)
Overall, we observed runtime improvements of nearly up to 300%:
| Model | Mode | Forward | Backward | Total | Speedup |
|---|---|---|---|---|---|
GCN |
Eager | 2.6396s | 2.1697s | 4.8093s | |
GCN |
Compiled | 1.1082s | 0.5896s | 1.6978s | 2.83x |
GraphSAGE |
Eager | 1.6023s | 1.6428s | 3.2451s | |
GraphSAGE |
Compiled | 0.7033s | 0.7465s | 1.4498s | 2.24x |
GIN |
Eager | 1.6701s | 1.6990s | 3.3690s | |
GIN |
Compiled | 0.7320s | 0.7407s | 1.4727s | 2.29x |
Please note that torch.compile() within PyG is in beta mode and under active development. For example, currently torch.compile(model, dynamic=True) does not yet work seamlessly, but fixes are on its way. We are very eager to improve its support across the whole PyG code base, so do not hesitate to reach out if you notice anything unexpected.
With the recent upstreams of torch-scatter and torch-sparse to native PyTorch, we are happy to announce that any installation of the extension packages torch-scatter, torch-sparse, torch-cluster and torch-spline-conv is now fully optional.
All it takes to install PyG is now encapsulated into a single command
pip install torch-geometric
and finally resolves a lot of previous installation issues.
Extension packages are still picked up for the following use-cases (if installed):
pyg-lib: Heterogeneous GNN operators and graph sampling routines like NeighborLoadertorch-scatter: Accelerated "min" and "max" reductionstorch-sparse: SparseTensor supporttorch-cluster: Graph clustering routines like knn or radiustorch-spline-conv: SplineConv supportWe recommend to start with a minimal installation, and only install additional dependencies once you actually get notified about them being missing during PyG usage.
With the recent additions of torch.sparse_csr_tensor and torch.sparse_csc_tensor classes and accelerated sparse matrix multiplication routines to PyTorch, we finally enable MessagePassing on pure PyTorch sparse tensors as well. In particular, you can now use torch.sparse_csr_tensor and torch.sparse_csc_tensor as a drop-in replacement for torch_sparse.SparseTensor:
from torch_geometric.nn import GCN
import torch_geometric.transforms as T
from torch_geometric.datasets import Planetoid
transform = T.ToSparseTensor(layout=torch.sparse_csr)
dataset = Planetoid("Planetoid", name="Cora", transform=transform)
model = GCN(in_channels, hidden_channels, num_layers=2)
model = model(data.x, data.adj_t)
Nearly all of the native PyG layers have been tested to work seamlessly with native PyTorch sparse tensors (#5906, #5944, #6003, #6033, #6514, #6532, #6748, #6847, #6868, #6874, #6897, #6930, #6932, #6936, #6937, #6939, #6947, #6950, #6951, #6957).
In PyG 2.2 we introduced the torch_geometric.explain package that provides a flexible interface to generate and visualize GNN explanations using various algorithms. We are happy to add the following key improvements on this front:
HeteroExplanationvisualize_feature_importance and to visualize_graph explanationsCaptumExplainer, PGExplainer, AttentionExplainer, PGMExplainer, and GraphMaskExplainerUsing the new explainer interface is as simple as:
explainer = Explainer(
model=model,
algorithm=CaptumExplainer('IntegratedGradients'),
explanation_type='model',
model_config=dict(
mode='multiclass_classification',
task_level='node',
return_type='log_probs',
),
node_mask_type='attributes',
edge_mask_type='object',
)
explanation = explainer(data.x, data.edge_index)
Read more about torch_geometric.explain in our newly added tutorial and example scripts. We also added a blog post that describes the new interface and functionality in depth.
Together with Intel and NVIDIA, we are excited about new PyG accelerations:
[Experimental] Support for native cugraph-based GNN layers for commonly used layers such as CuGraphSAGEConv, CuGraphGATConv, and CuGraphRGCNConv (#6278, #6388, #6412):
RGCN with neighbor sampling:
| Dataset | CuGraphRGCNConv (ms) |
FastRGCNConv (ms) |
RGCNConv (ms) |
|---|---|---|---|
| AIFB | 7,2 | 13,4 | 70 |
| BGS | 7,1 | 8,8 | 146,9 |
| MUTAG | 8,3 | 21,8 | 47,6 |
| AM | 17,5 | 51 | 330,1 |
Full-batch GAT:
| Dataset | CuGraphGATConv (ms) |
GATConv (ms) |
|---|---|---|
| Cora | 7 | 8,7 |
| Citeseer | 7 | 9 |
| Pubmed | 8,2 | 11,4 |
GraphSAGE with neighbor sampling:
| Dataset | CuGraphSAGEConv (ms) |
SAGEConv (ms) |
|---|---|---|
ogbn-products |
2591,8 | 3040,3 |
A fast alternative to HGTConv via FastHGTConv that utilizes pyg-lib integration for improved runtimes. Overall, FastHGTConv achieves a speed-up of approximately 300% compared to the original implementation (#6178).
A fast implementation of HeteroDictLinear that utilizes pyg-lib integration for improved runtimes (#6178).
GNN inference and training optimizations on CPU within native PyTorch 2.0. Optimizations include:
scatter_reduce: performance hotspot in message passing when edge_index is stored in Coordinate format (COO).gather: backward of scatter_reduce, specially tuned for the GNN compute when the index is an expanded tensor.torch.sparse.mm with reduce flag: performance hotspot in message passing when the edge_index is stored in Compressed Sparse Row (CSR). Supported reduce flags are "sum", "mean", "amax" and "amin".
On OGB benchmarks, a 1.12x - 4.07x performance speedup is measured (PyTorch 1.13.1 vs PyTorch 2.0) for single node inference and training.Introduction of index_sort via pyg-lib>=0.2.0, which implements a (way) faster alternative to sorting one-dimensional indices compared to torch.sort (#6554). Overall, this achieves speed-ups in dataset loading times by up to 600%.
Introduction of AffinityMixin to accelerate PyG workflows on CPU. CPU affinity can be enabled via the AffinityMixin.enable_cpu_affinity() method for num_workers > 0 data loading use-cases, and will guarantee that a separate core is assigned to each worker at initialization. Over all benchmarked model/dataset samples, the average training time is decreased by up to 1.85x. We added an in-depth tutorial on how to speed-up your PyG workflows on CPU.
The documentation has undergone a revision of design and structure, making it faster to load and easier to navigate. Take a look at its new design here.
We had our third community sprint in the last two weeks of January. The goal was to improve code coverage by writing more thorough tests. Thanks to the efforts of many contributors, the total code coverage went from ~85% to ~92% (#6528, #6523, #6538, #6555, #6558, #6568, #6573, #6578, #6597, #6600, #6618, #6619, #6621, #6623, #6637, #6638, #6640, #6645, #6648, #6647, #6653, #6657, #6662, #6664, #6667, #6668, #6669, #6670, #6671, #6673, #6675, #6676, #6677, #6678, #6681, #6683, #6703, #6720, #6735, #6736, #6763, #6781, #6797, #6799, #6824, #6858)
NeighborLoader will now also sample nodes with an equal timestamp to the seed time. Changed from sampling only nodes with a smaller timestamp (requires pyg-lib>=0.2.0) (#6517)GraphMultisetTransformer such that GNN execution is no longer performed inside its module (#634))Explanation.node_mask and Explanation.node_feat_mask into a single attribute in Explainer (#6267)ExplainerConfig arguments to the Explainer class (#6176)torch_geometric.data.lightning (#6140)target_index argument in the Explainer interface (#6270)Aggregation.set_validate_args option (#6175)__dunder__ names in MessagePassing (#6999)datasets.BAShapes is now deprecated. Use the BAGraph graph generator to generate Barabasi-Albert graphs instead (#6072)DenseGATConv layer (https://github.com/pyg-team/pytorch_geometric/pull/6928)DistMult KGE model (https://github.com/pyg-team/pytorch_geometric/pull/6958)ComplEx KGE model (#6898)TransE KGE model (#6314)HeteroLayerNorm and HeteroBatchNorm layers (#6838)TemporalEncoding module (#6785)SimpleConv to perform non-trainable propagation (#6718)torch.jit examples for example/film.py and example/gcn.py (#6602)AntiSymmetricConv layer (#6577)PyGModelHubMixin for Huggingface model hub integration (#5930, #6591)PGMExplainer (#6149, #6588, #6589)ToHeteroLinear and ToHeteroMessagePassing modules to accelerate to_hetero functionality (#5992, #6456)GraphMaskExplainer (#6284)GRBCDAttack and PRBCDAttack adversarial attack models (#5972)CaptumExplainer (#6383, #6387, #6433, #6487)GNNFF model (#5866)MLPAggregation, SetTransformerAggregation, GRUAggregation, and DeepSetsAggregation as adaptive readout functions (#6301, #6336, #6338)
(https://github.com/pyg-team/pytorch_geometric/pull/6331), #6332)GPSConv Graph Transformer layer (#6326, #6327)PGExplainer (#6204)AttentionExplainer (#6279)PointGNNConv layer (#6194)AirfRANS dataset (#6287)HeterophilousGraphDataset suite (#6846)MD17 dataset (#6734)BAMultiShapesDataset (#6541)Taobao dataset and a corresponding example (#6144)FB15k_237 dataset (#3204)BA2MotifDataset explainer dataset (#6257)CycleMotif motif generator to generate n-node cycle shaped motifs (#6256)InfectionDataset to evaluate explanations (#6222)CustomMotif motif generator (#6179)ERGraph graph generator to generate Ergos-Renyi (ER) graphs (#6073)ExplainerDataset to evaluate explanation methods (#6104)NeighborLoader to return the number of sampled nodes and edges per hop, and added corresponding trim_to_layer functionality for more efficient NeighborLoader use-cases (#6661, #6834)ZipLoader to execute multiple NodeLoader or LinkLoader instances (#6829)seed_time attribute to temporal NodeLoader outputs in case input_time is given (#6196)Pad transformation (#5940, #6697, #6731, #6758)RemoveDuplicatedEdges transformation (#6709)utils.one_hot implementation (https://github.com/pyg-team/pytorch_geometric/pull/7005)utils.softmax implementation (#6113, #6155, #6805)topk implementation for graph pooling on large graphs (#6123)utils.select and utils.narrow functionality to support filtering of both tensors and lists (#6162)normalization customization in get_mesh_laplacian (#6790)spmm functionality via CSR format (#6699, #6759)RECT_L model (#6727)Node2Vec model (#6726)utils.to_edge_index to convert sparse tensors to edge indices and edge attributes (#6728)LINKX model (#6712)dropout option to GraphMultisetTransformer (#6484)LightningNodeData and LightningLinkData (#6450, #6456)num_neighbors in NeighborSampler after instantiation (#6446)HeteroData mini-batch class in remote backends (#6377)ChebConv within GNNExplainer (https://github.com/pyg-team/pytorch_geometric/pull/6778)Dataset.to_datapipe functionality for converting PyG datasets into a PyTorch DataPipe(#6141)to_nested_tensor and from_nested_tensor functionality (#6329, #6330, [#6331]networkit conversion utilities (#6321)Data.update() and HeteroData.update functionality (#6313)HeteroData.set_value_dict functionality (https://github.com/pyg-team/pytorch_geometric/pull/6961, https://github.com/pyg-team/pytorch_geometric/pull/6974)fidelity explainability metric (#6116, #6510)characterization_score and fidelity_curve_auc explainer metrics (#6188)LinkNeighborLoader (#6264)get_embeddings function (#6201)Explanation.visualize_feature_importance to support node feature importance visualizations (#6094)HeteroExplanation (#6091, #6218)summary method for PyG/PyTorch models (#5859, #6161)input_time option to LightningNodeData and transform_sampler_output to NodeLoader and LinkLoader (#6187)Data.edge_subgraph and HeteroData.edge_subgraph functionalities (#6193)Data.subgraph() and HeteroData.subgraph() for bipartite graphs (#6613, #6654)PNAConv and DegreeScalerAggregation to correctly incorporate degree statistics of isolated nodes (#6609)Data.to_heterogeneous filtered attributes in the wrong dimension (#6522)to_hetero when using an uninitialized submodule without implementing reset_parameters (#6863)get_mesh_laplacian (#6790)GNNExplainer on link prediction tasks (#6787)ImbalancedSampler when operating on a sliced InMemoryDataset (#6374)transforms.GDC to not crash on graphs with isolated nodes (#6242)transforms.RemoveIsolatedNodes (#6308)DimeNet that causes an output dimension mismatch (#6305)Data.to_heterogeneous when used with an empty edge_index (#6304)HeteroLinear for un-sorted type vectors (#6198)<details> <summary><b>Added</b></summary>
utils.one_hot implementation (#7005)HeteroDictLinear and an optimized FastHGTConv module (#6178, #6998)DenseGATConv module (#6928)trim_to_layer utility function for more efficient NeighborLoader use-cases (#6661)DistMult KGE model (#6958)HeteroData.set_value_dict functionality (#6961, #6974)ComplEx KGE model (#6898)HeteroLayerNorm and HeteroBatchNorm layers (#6838)HeterophilousGraphDataset suite (#6846)NeighborLoader to return number of sampled nodes and edges per hop (#6834)ZipLoader to execute multiple NodeLoader or LinkLoader instances (#6829)utils.select and utils.narrow functionality to support filtering of both tensors and lists (#6162)normalization customization in get_mesh_laplacian (#6790)TemporalEncoding module (#6785)spmm_reduce functionality via CSR format (#6699, #6759)MD17 dataset (#6734)RECT_L model (#6727)Node2Vec model (#6726)utils.to_edge_index to convert sparse tensors to edge indices and edge attributes (#6728)PolBlogs dataset (#6714)SimpleConv to perform non-trainable propagation (#6718)RemoveDuplicatedEdges transform (#6709)LINKX model (#6712)torch.jit examples for example/film.py and example/gcn.py(#6602)Pad transform (#5940, #6697, #6731, #6758)cat aggregation type to the HeteroConv class so that features can be concatenated during grouping (#6634)torch.compile support and benchmark study (#6610, #6952, #6953, #6980, #6983, #6984, #6985, #6986, #6989, #7002)AntiSymmetricConv layer (#6577)nn.conv.cugraph via cugraph-ops (#6278, #6388, #6412)index_sort function from pyg-lib for faster sorting (#6554)EquilibriumAggregration (#6560)dense_to_sparse() (#6546)BAMultiShapesDataset (#6541)n_id and e_id attributes to mini-batches produced by NodeLoader and LinkLoader (#6524)PGMExplainer to torch_geometric.contrib (#6149, #6588, #6589)NumNeighbors helper class for specifying the number of neighbors when sampling (#6501, #6505, #6690)is_node_attr() and is_edge_attr() calls (#6492)ToHeteroLinear and ToHeteroMessagePassing modules to accelerate to_hetero functionality (#5992, #6456)GraphMaskExplainer (#6284)GRBCD and PRBCD adversarial attack models (#5972)dropout option to SetTransformer and GraphMultisetTransformer (#6484)LightningNodeData and LightningLinkData (#6450, #6456)num_neighbors in NeighborSampler after instantiation (#6446)Taobao dataset and a corresponding example for it (#6144)pyproject.toml (#6431)torch_geometric.contrib sub-package (#6422)pyright type checker support (#6415)CaptumExplainer (#6383, #6387, #6433, #6487, #6966)HeteroData mini-batch class in remote backends (#6377)GNNFF model (#5866)MLPAggregation, SetTransformerAggregation, GRUAggregation, and DeepSetsAggregation as adaptive readout functions (#6301, #6336, #6338)Dataset.to_datapipe for converting PyG datasets into a torchdata DataPipe(#6141)to_nested_tensor and from_nested_tensor functionality (#6329, #6330, #6331, #6332)GPSConv Graph Transformer layer and example (#6326, #6327)networkit conversion utilities (#6321)dataset.{attr_name} (#6319)TransE KGE model and example (#6314)FB15k_237 dataset (#3204)Data.update() and HeteroData.update() functionality (#6313)PGExplainer (#6204)AirfRANS dataset (#6287)AttentionExplainer (#6279)LinkNeighborLoader (#6264)BA2MotifDataset explainer dataset (#6257)CycleMotif motif generator to generate n-node cycle shaped motifs (#6256)InfectionDataset to evaluate explanations (#6222)characterization_score and fidelity_curve_auc explainer metrics (#6188)get_message_passing_embeddings (#6201)PointGNNConv layer (#6194)GridGraph graph generator to generate grid graphs (#6220visualize_feature_importance to support node feature visualizations (#6094)Explanation framework (#6091, #6218)CustomMotif motif generator (#6179)ERGraph graph generator to generate Ergos-Renyi (ER) graphs (#6073)BAGraph graph generator to generate Barabasi-Albert graphs - the usage of datasets.BAShapes is now deprecated (#6072seed_time attribute to temporal NodeLoader outputs in case input_time is given (#6196)Data.edge_subgraph and HeteroData.edge_subgraph functionalities (#6193)input_time option to LightningNodeData and transform_sampler_output to NodeLoader and LinkLoader (#6187)summary for PyG/PyTorch models (#5859, #6161)torch.sparse support to PyG (#5906, #5944, #6003, #6033, #6514, #6532, #6748, #6847, #6868, #6874, #6897, #6930, #6932, #6936, #6937, #6939, #6947, #6950, #6951, #6957)inputs_channels back in training benchmark (#6154)utils.to_dense_batch in case max_num_nodes is smaller than the number of nodes (#6124)</details>
<details> <summary><b>Changed</b></summary>
__dunder__ names (#6999)sort_edge_index, coalesce and to_undirected to only return single edge_index information in case the edge_attr argument is not specified (#6875, #6879, #6893)to_hetero when using an uninitialized submodule without implementing reset_parameters (#6863)get_mesh_laplacian (#6790)GNNExplainer on link prediction tasks (#6787)ChebConv within GNNExplainer (#6778)EdgeStorage.num_edges property (#6710)utils.bipartite_subgraph() and updated docs of HeteroData.subgraph() (#6654)data_list cache of an InMemoryDataset when accessing dataset.data (#6685)Data.subgraph() and HeteroData.subgraph() (#6613)PNAConv and DegreeScalerAggregation to correctly incorporate degree statistics of isolated nodes (#6609)data.to_heterogeneous() filtered attributs in the wrong dimension (#6522)pyg-lib>0.1.0) (#6517)DataLoader workers with affinity to start at cpu0 (#6512)global_*_pool functions (#6504)RGCNConv (#6482)numpy 1.24.0 (#6495)examples/mnist_voxel_grid.py (#6478)LightningNodeData and LightningLinkData code paths (#6473)RGCNConv (#6463)DataParallel class (#6376)ImbalancedSampler on sliced InMemoryDataset (#6374)GraphMultisetTransformer (#6343)transforms.GDC to not crash on graphs with isolated nodes (#6242)InMemoryDataset.data (#6318)SparseTensor dependency in GraphStore (#5517)NeighborSampler with NeighborLoader in the distributed sampling example (#6204)transforms.RemoveIsolatedNodes (#6308)DimeNet that causes a output dimension mismatch (#6305)Data.to_heterogeneous() with empty edge_index (#6304)Explanation.node_mask and Explanation.node_feat_mask (#6267)Explainer to Explanation (#6215)HeteroLinear for un-sorted type vectors (#6198)ExplainerConfig arguments to the Explainer class (#6176)NeighborSampler to be input-type agnostic (#6173)profileit decorator (#6164)GDC example (#6159)torch_geometric.data.lightning (#6140)torch_sparse an optional dependency (#6132, #6134, #6138, #6139)utils.softmax implementation (#6113, #6155, #6805)topk implementation for large enough graphs (#6123)</details>
<details> <summary><b>Removed</b></summary>
torch-sparse is now an optional dependency (#6625, #6626, #6627, #6628, #6629, #6630)torch-scatter dependencies (#6394, #6395, #6399, #6400, #6615, #6617)GNNExplainer and Explainer from nn.models (#6382)target_index argument in the Explainer interface (#6270)Aggregation.set_validate_args option (#6175)</details>
Full Changelog: https://github.com/pyg-team/pytorch_geometric/compare/2.2.0...2.3.0
Breaking change: removed num_neighbors as an attribute of loader
We are excited to announce the release of PyG 2.2 🎉🎉🎉
PyG 2.2 is the culmination of work from 78 contributors who have worked on features and bug-fixes for a total of over 320 commits since torch-geometric==2.1.0.
pyg-lib IntegrationWe are proud to release and integrate pyg-lib==0.1.0 into PyG, the first stable version of our new low-level Graph Neural Network library to drive all CPU and GPU acceleration needs of PyG (#5330, #5347, #5384, #5388).
You can install pyg-lib as described in our README.md:
pip install pyg-lib -f https://data.pyg.org/whl/torch-${TORCH}+${CUDA}.html
import pyg_lib
Once pyg-lib is installed, it will get automatically picked up by PyG, e.g., to accelerate neighborhood sampling routines or to accelerate heterogeneous GNN execution:
pyg-lib provides fast and optimized CPU routines to iteratively sample neighbors in homogeneous and heterogeneous graphs, and heavily improves upon the previously used neighborhood sampling techniques utilized in PyG.pyg-lib provides efficient GPU-based routines to parallelize workloads in heterogeneous graphs across different node types and edge types. We achieve this by leveraging type-dependent transformations via NVIDIA CUTLASS integration, which is flexible to implement most heterogeneous GNNs with, and efficient, even for sparse edge types or a large number of different node types.GraphStore and FeatureStore AbstractionsPyG 2.2 includes numerous primitives to easily integrate with simple paradigms for scalable graph machine learning, enabling users to train GNNs on graphs far larger than the size of their machine's available memory. It does so by introducing simple, easy-to-use, and extensible abstractions of a FeatureStore and a GraphStore that plug directly into existing familiar PyG interfaces (see here for the accompanying tutorial).
feature_store = CustomFeatureStore()
feature_store['paper', 'x', None] = ... # Add paper features
feature_store['author', 'x', None] = ... # Add author features
graph_store = CustomGraphStore()
graph_store['edge', 'coo'] = ... # Add edges in "COO" format
# `CustomGraphSampler` knows how to sample on `CustomGraphStore`:
graph_sampler = CustomGraphSampler(
graph_store=graph_store,
num_neighbors=[10, 20],
...
)
from torch_geometric.loader import NodeLoader
loader = NodeLoader(
data=(feature_store, graph_store),
node_sampler=graph_sampler,
batch_size=20,
input_nodes='paper',
)
for batch in loader:
pass
Data loading and sampling routines are refactored and decomposed into torch_geometric.loader and torch_geometric.sampler modules, respectively (#5563, #5820, #5456, #5457, #5312, #5365, #5402, #5404, #5418).
PyG 2.2 further accelerates scatter aggregations based on CPU/GPU and with/without backward computation paths (requires torch>=1.12.0 and torch-scatter>=2.1.0) (#5232, #5241, #5353, #5386, #5399, #6051, #6052).
We also optimized the usage of nn.aggr.MultiAggregation by fusing the computation of multiple aggregations together (see here for more details) (#6036, #6040).
Here are some benchmarking results on PyTorch 1.12 (summed over 1000 runs):
| Aggregators | Vanilla | Fusion |
|---|---|---|
[sum, mean] |
0.3325s | 0.1996s |
[sum, mean, min, max] |
0.7139s | 0.5037s |
[sum, mean, var] |
0.6849s | 0.3871s |
[sum, mean, var, std] |
1.0955s | 0.3973s |
Lastly, we have incorporated "fused" GNN operators via the dgNN package, starting with a FusedGATConv implementation (#5140).
We are running regular community sprints to get our community more involved in building PyG. Whether you are just beginning to use graph learning or have been leveraging GNNs in research or production, the community sprints welcome members of all levels with different types of projects.
We had our first community sprint on 10/12 to fully-incorporate type hints and TorchScript support over the entire code base. The goal was to improve usability and cleanliness of our codebase. We had 20 contributors participating, contributing to 120 type hints within 2 weeks, adding around 2400 lines of code (#5842, #5603, #5659, #5664, #5665, #5666, #5667, #5668, #5669, #5673, #5675, #5673, #5678, #5682, #5683, #5684, #5685, #5687, #5688, #5695, #5699, #5701, #5702, #5703, #5706, #5707, #5710, #5714, #5715, #5716, #5722, #5724, #5725, #5726, #5729, #5730, #5731, #5732, #5733, #5743, #5734, #5735, #5736, #5737, #5738, #5747, #5752, #5753, #5754, #5756, #5757, #5758, #5760, #5766, #5767, #5768, #5781, #5778, #5797, #5798, #5799, #5800, #5806, #5810, #5811, #5828, #5847, #5851, #5852).
Our second community sprint began on 11/15 with the goal to improve the explainability capabilities of PyG. With this, we introduce the torch_geometric.explain module to provide a unified set of tools to explain the predictions of a PyG model or to explain the underlying phenomenon of a dataset.
Some of the features developed in the sprint are incorporated into this release:
torch_geometric.explain module (#5804, #6054, #6089)GNNExplainer module to torch_geometric.explain (#5967, #6065). See here and here for the accompanying examples.GNNExplainer to support edge level explanations (#6056)to_captum_model and to_captum_input (#5886, #5934)data = HeteroData(...)
model = HeteroGNN(...)
# Explain predictions on heterogenenous graphs for output node 10:
captum_model = to_captum_model(model, mask_type, output_idx, metadata)
inputs, additional_forward_args = to_captum_input(data.x_dict, data.edge_index_dict, mask_type)
ig = IntegratedGradients(captum_model)
ig_attr = ig.attribute(
inputs=inputs,
target=int(y[output_idx]),
additional_forward_args=additional_forward_args,
internal_batch_size=1,
)
drop_unconnected_nodes to drop_unconnected_node_types and drop_orig_edges to drop_orig_edge_types in AddMetapaths (#5490)nn.models.GNNExplainer is now deprecated in favor of explain.GNNExplainerutils.dropout_adj is now deprecated in favor of utils.dropout_edgeloader.RandomNodeSampler is now deprecated in favor of loader.RandomNodeLoaderto_captum is now deprecated in favor of to_captum_model.SSGConv layer (#5599)WLConvContinuous layer for performing WL-refinement with continuous attributes (#5316)PositionalEncoding module (#5381)LinkNeighborLoader (#6004)temporal_strategy = uniform/last option to NeighborLoader and LinkNeighborLoader (#5576)disjoint option to NeighborLoader and LinkNeighborLoader (#5717, #5775)HeteroData support in RandomNodeLoader (#6007int32-based edge_index support in NeighborLoader (#5948)input_time in NeighborLoader (#5763)np.memmap support in NeighborLoader (#5696)NeighborLoader (#6005)FeaturePropagation transform (#5387)IndexToMask and MaskToIndex transforms (#5375, #5455)shuffle_node, mask_feature and add_random_edge augmentations (#5548)dropout_node, dropout_edge and dropout_path augmentations (#5481, #5495, #5531)AddRandomMetaPaths transform that adds edges based on random walks along a metapath (#5397)utils.to_smiles function (#6038)HeteroData support for transforms.Constant (#5700)LRGBDataset to include 5 datasets from the Long Range Graph Benchmark (#5935)HydroNet water cluster dataset (#5537, #5902, #5903)DGraphFin dynamic graph dataset (#5504)MalNetTiny dataset (#5078)print_summary method to torch_geometric.data.Dataset (#5438)utils.assortativity function to compute the degree assortativity coefficient (#5587)HeteroData.to_homogeneous() (#5540)torch.onnx.export support (see here for an example) (#5877, #5997)PNAConv (#6039)semi_grad option in VarAggregation and StdAggregation (#6042)HeteroData (#5990)lr_scheduler_solver and customized lr_scheduler classes (#5942)to_fixed_size graph transformer (#5939)SchNet model (#5938)SchNet model (#5919)SparseTensor support to SuperGATConv (#5888)AttentiveFP (#5868)return_semantic_attention_weights argument HANConv (#5787)dense_mincut_pool (#5908)in_channels in GENConv for bipartite message passing (#5627, #5641)Aggregation.set_validate_args option to skip validation of dim_size (#5290)BaseStorage.get() functionality (#5240)BatchNorm (#5530, #5614)AttentionalAggregation module can now be applied to compute attention on a per-feature level (#5449)ASAPooling (#5395)GraphSAGE example to leverage LinkNeighborLoader (#5317)MessagePassing (#5339)PNAConv (#5262)TUDataset, in which node features were wrongly constructed whenever node_attributes only hold a single feature (e.g., in PROTEINS) (#5441)VirtualNode transform, in which node features were mistakenly treated as edge features (#5819)PNAConv (#5514)setter and getter handling in BaseStorage (#5815)auto_select_device routine in GraphGym for pytorch_lightning>=1.7 (#5677)RandomLinkSplit in case there aren't enough negative edges to sample (#5642)mode_kwargs in MultiAggregation (#5601)utils.to_dense_adj routine in case edge_index is empty (#5476)PointTransformerConv to now correctly use sum aggregation (#5332)InMemoryDataset.num_classes in case a transform modifies data.y (#5274)GLIBC errors within torch-spline-conv (#5276)<details> <summary><b>Added</b></summary>
GNNExplainer to support edge level explanations (#6056)NodeLoader (#6005)LinkNeighborLoader (#6004)FusedAggregation of simple scatter reductions (#6036)to_smiles function (#6038)PNAConv (#6039)semi_grad option in VarAggregation and StdAggregation (#6042)MultiAggregation (#6036, #6040)HeteroData support for to_captum_model and added to_captum_input (#5934)HeteroData support in RandomNodeLoader (#6007)GraphSAGE example (#5834)LRGBDataset to include 5 datasets from the Long Range Graph Benchmark (#5935)HeteroData (#5990)int32 support in NeighborLoader (#5948)dgNN support and FusedGATConv implementation (#5140)lr_scheduler_solver and customized lr_scheduler classes (#5942)to_fixed_size graph transformer (#5939)SchNet model (#5938)SchNet model (#5919)torch.sparse support to PyG (#5906, #5944, #6003)HydroNet water cluster dataset (#5537, #5902, #5903)SparseTensor support to SuperGATConv (#5888)AttentiveFP (#5868)num_steps argument to training and inference benchmarks (#5898)torch.onnx.export support (#5877, #5997)sampler support in LightningDataModule (#5820)return_semantic_attention_weights argument HANConv (#5787)disjoint argument to NeighborLoader and LinkNeighborLoader (#5775)input_time in NeighborLoader (#5763)disjoint mode for temporal LinkNeighborLoader (#5717)HeteroData support for transforms.Constant (#5700)np.memmap support in NeighborLoader (#5696)assortativity that computes degree assortativity coefficient (#5587)SSGConv layer (#5599)shuffle_node, mask_feature and add_random_edge augmentation methdos (#5548)dropout_path augmentation that drops edges from a graph based on random walks (#5531)HeteroData.to_homogeneous() (#5540)temporal_strategy option to neighbor_sample (#5576)torch_geometric.sampler package to docs (#5563)DGraphFin dynamic graph dataset (#5504)dropout_edge augmentation that randomly drops edges from a graph - the usage of dropout_adj is now deprecated (#5495)dropout_node augmentation that randomly drops nodes from a graph (#5481)AddRandomMetaPaths that adds edges based on random walks along a metapath (#5397)WLConvContinuous for performing WL refinement with continuous attributes (#5316)print_summary method for the torch_geometric.data.Dataset interface (#5438)sampler support to LightningDataModule (#5456, #5457)MalNetTiny dataset (#5078)IndexToMask and MaskToIndex transforms (#5375, #5455)FeaturePropagation transform (#5387)PositionalEncoding (#5381)torch_geometric.sampler, enabling ease of extensibility in the future (#5312, #5365, #5402, #5404), #5418)pyg-lib neighbor sampling (#5384, #5388)pyg_lib.segment_matmul integration within HeteroLinear (#5330, #5347))bf16 support in benchmark scripts (#5293, #5341)Aggregation.set_validate_args option to skip validation of dim_size (#5290)SparseTensor support to inference and training benchmark suite (#5242, #5258, #5881)utils.scatter (#5232, #5241, #5386)HGBDataset (#5233)BaseStorage.get() functionality (#5240)to_hetero works with SparseTensor (#5222)torch_geometric.explain module with base functionality for explainability methods (#5804, #6054, #6089)</details>
<details> <summary><b>Changed</b></summary>
GNNExplainer from torch_geometric.nn to torch_geometric.explain.algorithm (#5967, #6065)dense_mincut_pool (#5908)VirtualNode mistakenly treated node features as edge features (#5819)setter and getter handling in BaseStorage (#5815)path in hetero_conv_dblp.py example (#5686)auto_select_device routine in GraphGym for PyTorch Lightning>=1.7 (#5677)in_channels with tuple in GENConv for bipartite message passing (#5627, #5641)RandomLinkSplit (#5642)RGCN+pyg-lib for LongTensor input (#5610)mode_kwargs in MultiAggregation (#5601)BatchNorm to allow for batches of size one during training (#5530, #5614)PNAConv (#5514). in ParameterDict key names (#5494)drop_unconnected_nodes to drop_unconnected_node_types and drop_orig_edges to drop_orig_edge_types in AddMetapaths (#5490)utils.scatter performance by explicitly choosing better implementation for add and mean reduction (#5399)to_dense_adj with empty edge_index (#5476)AttentionalAggregation module can now be applied to compute attentin on a per-feature level (#5449)num_neighbors across edge types in NeighborLoader (#5444)TUDataset in which node features were wrongly constructed whenever node_attributes only hold a single feature (e.g., in PROTEINS) (#5441)num_neighbors as an attribute of loader (#5404)ASAPooling is now jittable (#5395)GraphSAGE example to leverage LinkNeighborLoader (#5317)torch.scatter_reduce API (#5353)PointTransformerConv now correctly uses sum aggregation (#5332)MessagePassing (#5339)Dataset to be specified as either property and method (#5338)SparseTensor within InMemoryDataset (#5299)GLIBC errors within torch-spline-conv (#5276)Dataset.num_classes in case a transform modifies data.y (#5274)PNAConv (#5262)InMemoryDataset cache on dataset.num_features (#5264)dblp datasets to instead use synthetic data (#5250)custom_graphgym (#5243)</details>
<details> <summary><b>Removed</b></summary>
scatter_reduce option from experimental mode (#5399)</details>
Full commit list: https://github.com/pyg-team/pytorch_geometric/compare/2.1.0...2.2.0
Nothing published for this version
The usage of the `torch_geometric.nn.glob` package is now deprecated in favor of `torch_geometric.nn.aggr`
We are excited to announce the release of PyG 2.1.0 🎉🎉🎉
PyG 2.1.0 is the culmination of work from over 60 contributors who have worked on features and bug-fixes for a total of over 320 commits since torch-geometric==2.0.4.
See here for the accompanying tutorial.
Aggregation functions play an important role in the message passing framework and the readout functions of Graph Neural Networks. Specifically, many works in the literature (Hamilton et al. (2017), Xu et al. (2018), Corso et al. (2020), Li et al. (2020), Tailor et al. (2021), Bartunov et al. (2022)) demonstrate that the choice of aggregation functions contributes significantly to the representational power and performance of the model.
To facilitate further experimentation and unify the concepts of aggregation within GNNs across both MessagePassing and global readouts, we have made the concept of Aggregation a first-class principle in PyG (#4379, #4522, #4687, #4721, #4731, #4762, #4749, #4779, #4863, #4864, #4865, #4866, #4872, #4927, #4934, #4935, #4957, #4973, #4973, #4986, #4995, #5000, #5021, #5034, #5036, #5039, #4522, #5033, #5085, #5097, #5099, #5104, #5113, #5130, #5098, #5191). As of now, PyG provides support for various aggregations — from simple ones (e.g., mean, max, sum), to advanced ones (e.g., median, var, std), learnable ones (e.g., SoftmaxAggregation, PowerMeanAggregation), and exotic ones (e.g., LSTMAggregation, SortAggregation, EquilibriumAggregation). Furthermore, multiple aggregations can be combined and stacked together:
from torch_geometric.nn import MessagePassing, SoftmaxAggregation
class MyConv(MessagePassing):
def __init__(self, ...):
# Combines a set of aggregations and concatenates their results.
# The interface also supports automatic resolution.
super().__init__(aggr=['mean', 'std', SoftmaxAggregation(learn=True)])
We added a new LinkNeighborLoader class for training scalable GNNs that perform edge-level predictions on giant graphs (#4396, #4439, #4441, #4446, #4508, #4509, #4868). LinkNeighborLoader comes with automatic support for both homogeneous and heterogenous data, and supports link prediction via automatic negative sampling as well as edge-level classification and regression models:
from torch_geometric.loader import LinkNeighborLoader
loader = LinkNeighborLoader(
data,
num_neighbors=[30] * 2, # Sample 30 neighbors for each node for 2 iterations
batch_size=128, # Use a batch size of 128 for sampling training links
edge_label_index=data.edge_index, # Use the entire graph for supervision
negative_sampling_ratio=1.0, # Sample negative edges
)
sampled_data = next(iter(loader))
print(sampled_data)
>>> Data(x=[1368, 1433], edge_index=[2, 3103], edge_label_index=[2, 256], edge_label=[256])
Both NeighborLoader and LinkNeighborLoader now support temporal sampling via the time_attr argument (#4025, #4877, #4908, #5137, #5173). If set, temporal sampling will be used such that neighbors are guaranteed to fulfill temporal constraints, i.e. neighbors have an earlier timestamp than the center node:
from torch_geometric.loader import NeighborLoader
data['paper'].time = torch.arange(data['paper'].num_nodes)
loader = NeighborLoader(
data,
input_nodes='paper',
time_attr='time', # Only sample papers that appeared before the seed paper
num_neighbors=[30] * 2,
batch_size=128,
)
Note that this feature requires torch-sparse>=0.6.14.
DataPipesSee here for the accompanying example.
PyG now fully supports data loading using the newly introduced concept of DataPipes in PyTorch for easily constructing flexible and performant data pipelines (#4302, #4345, #4349). PyG provides DataPipe support for batching multiple PyG data objects together and for applying any PyG transform:
datapipe = FileOpener(['SMILES_HIV.csv'])
datapipe = datapipe.parse_csv_as_dict()
datapipe = datapipe.parse_smiles(target_key='HIV_active')
datapipe = datapipe.in_memory_cache() # Cache graph instances in-memory.
datapipe = datapipe.shuffle()
datapipe = datapipe.batch_graphs(batch_size=32)
datapipe = FileLister([root_dir], masks='*.off', recursive=True)
datapipe = datapipe.read_mesh()
datapipe = datapipe.in_memory_cache() # Cache graph instances in-memory.
datapipe = datapipe.sample_points(1024) # Use PyG transforms from here.
datapipe = datapipe.knn_graph(k=8)
datapipe = datapipe.shuffle()
datapipe = datapipe.batch_graphs(batch_size=32)
torch_geometric.utils.metric package has been removed. We now recommend to use the torchmetrics package instead.len(batch) of the data.Batch class will now return the number of graphs inside the batch, not the number of attributes (#4931)torch_geometric.nn.glob package is now deprecated in favor of torch_geometric.nn.aggrRandomTranslate is now deprecated in favor of RandomJitter (#4828)GroupAddRev module with support for reducing training GPU memory (#4671, #4701, #4715, #4730) [Example]MaskLabel module for performing masked label propagation (#4197) **[Example]DimeNetPlusPlus module (#4432, #4699, #4700, #4800)MeanSubtractionNorm module (#5068)DynamicBatchSampler for filling a mini-batch with a variable number of samples up to a maximum size (#4972)GraphSAGE on the PPI dataset (#4416)EdgeCNN model (#4991)AddPositionalEncoding transforms with two implementations: AddLaplacianEigenvectorPE and AddRandomWalkPE (#4521)Rooted transform with two implementations: RootedEgoNets and RootedRWSubgraph (#3926)AddMetapaths (#5049)Genius and Wiki datasets to the LINKXDataset (#4570, #4600)AQSOL dataset (#4626)Geom-GCN splits to the Planetoid datasets (#4442)GATv2Conv in the GAT model (#4357)SAGEConv (#4437)MessagePassing.explain_message() method to customize making explanations on messages (#4278, #4448))MLP.plain_last = False option (4652)networkx conversion (#4343)Data.validate() and HeteroData.validate() functionality to validate the correctness of the data (#4885)JumpingKnowledge module (#4805)predict() support to the LightningNodeData module (#4884)HeteroData.rename() (#4329)HeteroData.num_features functionality (#4504)HeteroData.subgraph, HeteroData.node_type_subgraph and HeteroData.edge_type_subgraph functionality (#4243)HeteroData support to the RemoveIsolatedNodes transform (#4479)to_hetero (#4582)HeteroData.is_undirected() support (#4604)HeteroData.node_items() and HeteroData.edge_items() functionality (#4644)HeteroData.subgraph() support (#4635)LayerNorm (#4944)utils.unbatch and utils.unbatch_edge_index functionality for splitting an edge_index tensor according to a batch vector (#4628, #4903)inference mode in BasicGNN with layer-wise neighbor loading (#4977)bias and dropout per layer in the MLP model (#4981)BasicGNN models within to_hetero (#5091)ImbalancedSampler accept torch.Tensor as input (#5138)edge_type == rev_edge_type argument in RandomLinkSplit (#4757)RGATConv that produced device mismatches for "f-scaled" mode (#5187]GINEConv bug for non-Sequential neural network layers (#5154]HGTLoader which produced outputs with missing edge types, will require torch-sparse>=0.6.15 (#5067)load_state_dict for Linear with strict=False mode (5094)data.num_node_features computation for sparse matrices (5089)BasicGNN for num_layers=1, which now respects a desired number of out_channels (#4943)data.subgraph for 0-dim tensors (#4932)InMemoryDataset inferring wrong length for lists of tensors (#4837)TUDataset where pre_filter was not applied whenever pre_transform was present (#4842)HeteroData via two node types when there exists multiple relations between them (#4782)HANConv in which destination node features rather than source node features were propagated (#4753)RGCN link prediction example (#4688)TUDataset and pre_transform transformations that modify node features (#4669)bias argument in TAGConv is now correctly applied (#4597)__cat_dim__ != 0 (#4629)SparseTensor support in NeighborLoader (#4320)PNAConv (#4312)from_networkx in case some attributes are PyTorch tensors (#4486)DimeNet model (#4506, #4562)DBP15K (#4428)DimeNet when resetting parameters (#4424)flow="target_to_source" (#4418)num_nodes was not properly updated in the FixedPoints transform (#4394)GATConv was not jittable (#4347)nn.models.GAT did not produce out_channels many output channels (#4299)GCNConv could not be combined with to_hetero on heterogeneous graphs with one node type (#4279)<details> <summary><b>Added</b></summary>
edge_label_time argument to LinkNeighborLoader (#5137, #5173)ImbalancedSampler accept torch.Tensor as input (#5138)flow argument to gcn_norm to correctly normalize the adjacency matrix in GCNConv (#5149)NeighborSampler supports graphs without edges (#5072)MeanSubtractionNorm layer (#5068)pyg_lib.segment_matmul integration within RGCNConv (#5052, #5096)SparseTensor as edge label in LightGCN (#5046)BasicGNN models within to_hetero (#5091)AddMetapaths (#5049)bias and dropout per layer in the MLP model (#4981)EdgeCNN model (#4991)inference mode in BasicGNN with layer-wise neighbor loading (#4977)unbatch_edge_index functionality for splitting an edge_index tensor according to a batch vector (#4903)LayerNorm (#4944)normalization_resolver (#4926, #4951, #4958, #4959)torch_geometric.nn.aggr package to documentation (#4927)follow_batch for lists or dictionaries of tensors (#4837)Data.validate() and HeteroData.validate() functionality (#4885)LinkNeighborLoader support to LightningDataModule (#4868)predict() support to the LightningNodeData module (#4884)time_attr argument to LinkNeighborLoader (#4877, #4908)filter_per_worker argument to data loaders to allow filtering of data within sub-processes (#4873)NeighborLoader benchmark script (#4815, #4862)FeatureStore and GraphStore in NeighborLoader (#4817, #4851, #4854, #4856, #4857, #4882, #4883, #4929, #4992, #4962, #4968, #5037, #5088)normalize parameter to dense_diff_pool (#4847)size=None explanation to jittable MessagePassing modules in the documentation (#4850)DataLoaderIterator class (#4838)GraphStore support to Data and HeteroData (#4816)FeatureStore support to Data and HeteroData (#4807, #4853)FeatureStore and GraphStore abstractions (#4534, #4568)global_*_pool (#4827)JumpingKnowledge module (#4805)max_sample argument to AddMetaPaths in order to tackle very dense metapath edges (#4750)HANConv with empty tensors (#4756, #4841)bias vector to the GCN model definition in the "Create Message Passing Networks" tutorial (#4755)transforms.RootedSubgraph interface with two implementations: RootedEgoNets and RootedRWSubgraph (#3926)ptr vectors for follow_batch attributes within Batch.from_data_list (#4723)torch_geometric.nn.aggr package (#4687, #4721, #4731, #4762, #4749, #4779, #4863, #4864, #4865, #4866, #4872, #4934, #4935, #4957, #4973, #4973, #4986, #4995, #5000, #5034, #5036, #5039, #4522, #5033, #5085, #5097, #5099, #5104, #5113, #5130, #5098, #5191)DimeNet++ model (#4432, #4699, #4700, #4800)GroupAddRev module with support for reducing training GPU memory (#4671, #4701, #4715, #4730)wandb (#4656, #4672, #4676)unbatch functionality (#4628)to_hetero() works with custom functions, e.g., dropout_adj (4653)MLP.plain_last=False option (4652)HeteroConv and to_hetero() to ensure that MessagePassing.add_self_loops is disabled (4647)HeteroData.subgraph() support (#4635)AQSOL dataset (#4626)HeteroData.node_items() and HeteroData.edge_items() functionality (#4644)MLP models (#4625)NeighborLoader in case edge indices are already sorted (via is_sorted=True) (#4620, #4702)AddPositionalEncoding transform (#4521)HeteroData.is_undirected() support (#4604)Genius and Wiki datasets to nn.datasets.LINKXDataset (#4570, #4600)nn.aggr.EquilibrumAggregation implicit global layer (#4522)to_hetero (#4582)CHANGELOG.md (#4581)HeteroData support to the RemoveIsolatedNodes transform (#4479)HeteroData.num_features functionality (#4504)SAGEConv (#4437)Geom-GCN splits to the Planetoid datasets (#4442)LinkNeighborLoader for training scalable link predictions models #4396, #4439, #4441, #4446, #4508, #4509)GraphSAGE example on PPI (#4416)LSTM aggregation in SAGEConv (#4379)RandomLinkSplit (#4311, #4383)torch.data DataPipes (#4302, #4345, #4349)cosine argument in the KNNGraph/RadiusGraph transforms (#4344)networkx conversion (#4343)HeteroData.rename (#4329)MessagePassing.explain_message method to customize making explanations on messages (#4278, #4448))GATv2Conv in the nn.models.GAT model (#4357)HeteroData.subgraph functionality (#4243)MaskLabel module and a corresponding masked label propagation example (#4197)NeighborLoader (#4025)<details> <summary><b>Changed</b></summary>
RandomLinkSplit (#5190)scatter_reduce implementation - experimental feature (#5120)RGATConv device mismatches for f-scaled mode (#5187]edge_labels in LinkNeighborLoader (#5186]GINEConv bug with non-sequential input (#5154]HGTLoader bug which produced outputs with missing edge types (#5067)load_state_dict in Linear with strict=False mode (5094)MaskLabel.ratio_mask (5093)data.num_node_features computation for sparse matrices (5089)torch.fx bug with torch.nn.aggr package (#5021))GenConv test (4993)act_dict (part of graphgym) to create individual instances instead of reusing the same ones everywhere (4978)F.one_hot (4970)bool arugments in argparse in benchmark/ (#4967)BasicGNN for num_layers=1, which now respects a desired number of out_channels (#4943)len(batch) will now return the number of graphs inside the batch, not the number of attributes (#4931)data.subgraph generation for 0-dim tensors (#4932)InMemoryDataset inferring wrong len for lists of tensors (#4837)Batch.separate when using it for lists of tensors (#4837)TUDataset where pre_filter was not applied whenever pre_transform was present (#4842)RandomTranslate to RandomJitter - the usage of RandomTranslate is now deprecated (#4828)HeteroData with two node types when there exists multiple relations between these types (#4782)edge_type == rev_edge_type argument in RandomLinkSplit (#4757)GeneralConv and neighbor_sample tests (#4754)HANConv in which destination node features rather than source node features were propagated (#4753)checkout and setup-python in CI (#4751)protobuf version (#4719)setter properties in Data (#4682, #4686)edge_weight in GCN2Conv (#4670)TUDataset and pre_transform that modify node features (#4669)pyg_sphinx_theme documentation template (#4664, #4667)MLP.jittable() bug in case return_emb=True (#4645, #4648)StochasticBlockModelDataset are now ordered with respect to their labels (#4617)bias argument in TAGConv is now actually applied (#4597)process and download in Datsaet (#4586)__cat_dim__ != 0 (#4629)SparseTensor support in NeighborLoader (#4320)PNAConv (#4312)from_networkx in case some attributes are PyTorch tensors (#4486)DimeNet (#4506, #4562)DBP15K (#4428)DimeNet when resetting parameters (#4424)flow="target_to_source" (#4418)num_nodes was not properly updated in the FixedPoints transform (#4394)GATConv was not jittable (#4347)nn.models.GAT did not produce out_channels-many output channels (#4299)GCNConv could not be combined with to_hetero on heterogeneous graphs with one node type (#4279)
</details><details> <summary><b>Removed</b></summary>
torchmetrics (#4287)
</details>Full commit list: https://github.com/pyg-team/pytorch_geometric/compare/2.0.4...2.1.0
A new minor PyG version release, bringing PyTorch 1.11 support to PyG. It further includes a variety of new features and bugfixes:
A new minor PyG version release, bringing PyTorch 1.11 support to PyG. It further includes a variety of new features and bugfixes:
GraphSAGE (#4103), thanks to @eedalong and @luomainn.model.to_captum: Full integration of explainability methods provided by the Captum library (#3990, #4076), thanks to @RBendiasnn.conv.RGATConv: The relational graph attentional operator (#4031, #4110), thanks to @fork123aniketnn.pool.DMoNPooling: The spectral modularity pooling operator (#4166, #4242), thanks to @fork123aniketnn.*: Support for shape information in the documentation (#3739, #3889, #3893, #3946, #3981, #4009, #4120, #4158), thanks to @saiden89 and @arunppsg and @konstantinosKokosloader.TemporalDataLoader: A dataloader to load a TemporalData object in mini-batches (#3985, #3988), thanks to @otaviocxloader.ImbalancedSampler: A weighted random sampler that randomly samples elements according to class distribution (#4198)transforms.VirtualNode: A transform that adds a virtual node to a graph (#4163)transforms.LargestConnectedComponents: Selects the subgraph that corresponds to the largest connected components in the graph (#3949), thanks to @abojchevskiutils.homophily: Support for class-insensitive edge homophily (#3977, #4152), thanks to @hash-ir and @jinjh0123utils.get_mesh_laplacian: Mesh Laplacian computation (#4187), thanks to @daniel-unyi-42datasets.EllipticBitcoinDataset: A dataset of Bitcoin transactions (#3815), thanks to @shravankumar147nn.models.MLP: MLPs can now either be initialized via a list of channels or by specifying hidden_channels and num_layers (#3957)nn.models.BasicGNN: Final Linear transformations are now always applied (except for jk=None) (#4042)nn.conv.MessagePassing: Message passing modules that make use of edge_updater are now jittable (#3765), thanks to @Padarnnn.conv.MessagePassing: (Official) support for min and mul aggregations (#4219)nn.LightGCN: Initialize embeddings via xavier_uniform for better model performance (#4083), thanks to @nishithshowri006nn.conv.ChebConv: Automatic eigenvalue approximation (#4106), thanks to @daniel-unyi-42nn.conv.APPNP: Added support for optional edge_weight, (690a01d), thanks to @YueeXiangnn.conv.GravNetConv: Support for torch.jit.script (#3885), thanks to @RobMcHnn.pool.global_*_pool: The batch vector is now optional (#4161)nn.to_hetero: Added a warning in case to_hetero is used on HeteroData metadata with unused destination node types (#3775)nn.to_hetero: Support for nested modules (ea135bf)nn.Sequential: Support for indexing (#3790)nn.Sequential: Support for OrderedDict as input (#4075)datasets.ZINC: Added an in-depth description of the task (#3832), thanks to @gasteigerjodatasets.FakeDataset: Support for different feature distributions across different labels (#4065), thanks to @arunppsgdatasets.FakeDataset: Support for custom global attributes (#4074), thanks to @arunppsgtransforms.NormalizeFeatures: Features will no longer be transformed in-place (ada5b9a)transforms.NormalizeFeatures: Support for negative feature values (6008e30)utils.is_undirected: Improved efficiency (#3789)utils.dropout_adj: Improved efficiency (#4059)utils.contains_isolated_nodes: Improved efficiency (970de13)utils.to_networkx: Support for to_undirected options (upper triangle vs. lower triangle) (#3901, #3948), thanks to @RemyLaugraphgym: Support for custom metrics and loggers (#3494), thanks to @RemyLaugraphgym.register: Register operations can now be used as class decorators (#3779, #3782)CONTRIBUTUNG.md (#3803, #3991, #3995), thanks to @Cho-Geonwoo and @RBendias and @RodrigoVillatoroyamllint (#3886)isort (66b1780), thanks to @mananshah99torch.package: Model packaging via torch.package (#3997)data.HeteroData: Fixed a bug in data.{attr_name}_dict in case data.{attr_name} does not exist (#3897)data.Data: Fixed data.is_edge_attr in case data.num_edges == 1 (#3880)data.Batch: Fixed a device mismatch bug in case a batch object was indexed that was created from GPU tensors (e6aa4c9, c549b3b)data.InMemoryDataset: Fixed a bug in which copy did not respect the underlying slice (d478dcb, #4223)nn.conv.MessagePassing: Fixed message passing with zero nodes/edges (#4222)nn.conv.MessagePassing: Fixed bipartite message passing with flow="target_to_source" (#3907)nn.conv.GeneralConv: Fixed an issue in case skip_linear=False and in_channels=out_channels (#3751), thanks to @danielegrattarolann.to_hetero: Fixed model transformation in case node type names or edge type names contain whitespaces or dashes (#3882, b63a660)nn.dense.Linear: Fixed a bug in lazy initialization for PyTorch < 1.8.0 (973d17d, #4086)nn.norm.LayerNorm: Fixed a bug in the shape of weights and biases (#4030), thanks to @marshkann.pool: Fixed torch.jit.script support for torch-cluster functions (#4047)datasets.TOSCA: Fixed a bug in which indices of faces started at 1 rather than 0 (8c282a0), thanks to @JRowbottomGitdatasets.WikiCS: Fixed WikiCS to be undirected by default (#3796), thanks to @pmernyeiutils.contains_isolated_nodes and data.has_isolated_nodes (#4138)graphgym: Fixed the loss function regarding multi-label classification (#4206), thanks to @RemyLauYour coding agent can read these notes before it upgrades. Set up the MCP server →