Graph Neural Network Library for PyTorch
PyG 2.5.3 includes a variety of bug fixes related to the MessagePassing
refactoring.
MessagePassing
via torch.load
(#9105)propagate
functions (#9079)propagate
method twice in MessagePassing
for decomposed_layers > 1
(#9198)Full Changelog: https://github.com/pyg-team/pytorch_geometric/compare/2.5.2...2.5.3
PyG 2.5.2 includes a bug fix for implementing MessagePassing
layers in Google Colab.
inspect.get_source
is not supported (#9068)Full Changelog: https://github.com/pyg-team/pytorch_geometric/compare/2.5.1...2.5.2
PyG 2.5.1 includes a variety of bugfixes.
self.propagate
appearances in comments when parsing MessagePassing
implementation (#9044)OSError
on read-only file systems within MessagePassing
(#9032)MessagePassing
interface thread-safe (#9001)Dataset
(#8999)MessagePassing
modules with nested inheritance (#8973)OSError
when downloading datasets with simplecache
(#8932)Full Changelog: https://github.com/pyg-team/pytorch_geometric/compare/2.5.0...2.5.1
We are excited to announce the release of PyG 2.5 🎉🎉🎉
PyG 2.5 is the culmination of work from 38 contributors who have worked on features and bug-fixes for a total of over 360 commits since torch-geometric==2.4.0
.
torch_geometric.distributed
We are thrilled to announce the first in-house distributed training solution for PyG via the torch_geometric.distributed
sub-package. Developers and researchers can now take full advantage of distributed training on large-scale datasets which cannot be fully loaded in memory of one machine at the same time. This implementation doesn't require any additional packages to be installed on top of the default PyG stack.
GraphStore
and FeatureStore
APIs provides a flexible and tailored interface for distributing large graph structure information and feature storage.See here for the accompanying tutorial. In addition, we provide two distributed examples in examples/distributed/pyg
to get started:
ogbn-products
MovieLens
EdgeIndex
Tensor Representationtorch-geometric==2.5.0
introduces the EdgeIndex
class.
EdgeIndex
is a torch.Tensor
, that holds an edge_index
representation of shape [2, num_edges]
. Edges are given as pairwise source and destination node indices in sparse COO format. While EdgeIndex
sub-classes a general torch.Tensor
, it can hold additional (meta)data, i.e.:
sparse_size
: The underlying sparse matrix sizesort_order
: The sort order (if present), either by row or columnis_undirected
: Whether edges are bidirectional.Additionally, EdgeIndex
caches data for fast CSR or CSC conversion in case its representation is sorted (i.e. its rowptr
or colptr
). Caches are filled based on demand (e.g., when calling EdgeIndex.sort_by()
), or when explicitly requested via EdgeIndex.fill_cache_()
, and are maintained and adjusted over its lifespan (e.g., when calling EdgeIndex.flip()
).
from torch_geometric import EdgeIndex
edge_index = EdgeIndex(
[[0, 1, 1, 2],
[1, 0, 2, 1]]
sparse_size=(3, 3),
sort_order='row',
is_undirected=True,
device='cpu',
)
>>> EdgeIndex([[0, 1, 1, 2],
... [1, 0, 2, 1]])
assert edge_index.is_sorted_by_row
assert edge_index.is_undirected
# Flipping order:
edge_index = edge_index.flip(0)
>>> EdgeIndex([[1, 0, 2, 1],
... [0, 1, 1, 2]])
assert edge_index.is_sorted_by_col
assert edge_index.is_undirected
# Filtering:
mask = torch.tensor([True, True, True, False])
edge_index = edge_index[:, mask]
>>> EdgeIndex([[1, 0, 2],
... [0, 1, 1]])
assert edge_index.is_sorted_by_col
assert not edge_index.is_undirected
# Sparse-Dense Matrix Multiplication:
out = edge_index.flip(0) @ torch.randn(3, 16)
assert out.size() == (3, 16)
EdgeIndex
is implemented through extending torch.Tensor
via the __torch_function__
interface (see here for the highly recommended tutorial).
EdgeIndex
ensures for optimal computation in GNN message passing schemes, while preserving the ease-of-use of regular COO-based PyG workflows. EdgeIndex
will fully deprecate the usage of SparseTensor
from torch-sparse
in later releases, leaving us with just a single source of truth for representing graph structure information in PyG.
Previously, all/most of our link prediction models were trained and evaluated using binary classification metrics. However, this usually requires that we have a set of candidates in advance, from which we can then infer the existence of links. This is not necessarily practical, since in most cases, we want to find the top-k
most likely links from the full set of O(N^2)
pairs.
torch-geometric==2.5.0
brings full support for using GNNs as a recommender system (#8452), including support for
MIPSKNNIndex
f1@k
, map@k
, precision@k
, recall@k
and ndcg@k
, including mini-batch supportmips = MIPSKNNIndex(dst_emb)
for src_batch in src_loader:
src_emb = model(src_batch.x_dict, src_batch.edge_index_dict)
_, pred_index_mat = mips.search(src_emb, k)
for metric in retrieval_metrics:
metric.update(pred_index_mat, edge_label_index)
for metric in retrieval_metrics:
metric.compute()
See here for the accompanying example.
PyG 2.5 is fully compatible with PyTorch 2.2 (#8857), and supports the following combinations:
PyTorch 2.2 | cpu |
cu118 |
cu121 |
---|---|---|---|
Linux | ✅ | ✅ | ✅ |
macOS | ✅ | ||
Windows | ✅ | ✅ | ✅ |
You can still install PyG 2.5 with an older PyTorch release up to PyTorch 1.12 in case you are not eager to update your PyTorch version.
torch.compile(...)
and TorchScript Supporttorch-geometric==2.5.0
introduces a full re-implementation of the MessagePassing
interface, which makes it natively applicable to both torch.compile
and TorchScript. As such, torch_geometric.compile
is now fully deprecated in favor of torch.compile
- model = torch_geometric.compile(model)
+ model = torch.compile(model)
and MessagePassing.jittable()
is now a no-op:
- conv = torch.jit.script(conv.jittable())
+ model = torch.jit.script(conv)
In addition, torch.compile
usage has been fixed to not require disabling of extension packages such as torch-scatter
or torch-sparse
.
torch_geometric.distributed
(examples/distributed/pyg/
) (#8713)examples/hetero/temporal_link_pred.py
) (#8383)examples/distributed/pyg/temporal_link_movielens_cpu.py
) (#8820)examples/multi_gpu/distributed_sampling_xpu.py
) (#8032)ogbn-papers100M
(examples/multi_gpu/papers100m_gcn_multinode.py
) (#8070)examples/multi_gpu/model_parallel.py
) (#8309)ViSNet
from "ViSNet: an equivariant geometry-enhanced graph neural network with vector-scalar interactive message passing for molecules" (#8287)examples/multi_gpu/distributed_sampling.py
) (#8880)GATConv
now initializes modules differently depending on whether their input is bipartite or non-bipartite (#8397). This will lead to issues when loading model state for GATConv
layers trained on earlier PyG versions.torch_geometric.compile
in favor of torch.compile
(#8780)torch_geometric.nn.DataParallel
in favor of torch.nn.parallel.DistributedDataParallel
(#8250)MessagePassing.jittable
(#8781, #8731)torch_geometric.data.makedirs
in favor of os.makedirs
(#8421)Package-wide Improvements
mypy
(#8254)fsspec
as file system backend (#8379, #8426, #8434, #8474)torch-scatter
is not installed (#8852)Temporal Graph Support
NeighborLoader
and LinkNeighborLoader
(#8372, #8428)Data.{sort_by_time,is_sorted_by_time,snapshot,up_to}
for temporal graph use-cases (#8454)torch_geometric.distributed
(#8718, #8815)torch_geometric.datasets
RCDD
) from "Datasets and Interfaces for Benchmarking Heterogeneous Graph Neural Networks" (#8196)StochasticBlockModelDataset(num_graphs: int)
argument (#8648)FakeDataset
and FakeHeteroDataset
(#8404)InMemoryDataset.to(device)
(#8402)force_reload: bool = False
argument to Dataset
and InMemoryDataset
in order to enforce re-processing of datasets (#8352, #8357, #8436)TreeGraph
and GridMotif
generators (#8736)torch_geometric.nn
KNNIndex
exclusion logic (#8573)KGEModel.test()
(#8298)nn.to_hetero_with_bases
on static graphs (#8247)ModuleDict
, ParameterDict
, MultiAggregation
and HeteroConv
for better support for torch.compile
(#8363, #8345, #8344)torch_geometric.metrics
f1@k
, map@k
, precision@k
, recall@k
and ndcg@k
metrics for link-prediction retrieval tasks (#8499, #8326, #8566, #8647)torch_geometric.explain
conv.explain = False
(#8216)visualize_graph(node_labels: list[str] | None)
argument (#8816)torch_geometric.transforms
AddRandomWalkPE
(#8431)Other Improvements
utils.to_networkx
(#8575)utils.noise_scheduler.{get_smld_sigma_schedule,get_diffusion_beta_schedule}
for diffusion-based graph generative models (#8347)utils.dropout_node
via relabel_nodes: bool
argument (#8524)utils.cross_entropy.sparse_cross_entropy
(#8340)profile.profileit("xpu")
(#8532)ClusterData
(#8438)HeteroData.to_homogeneous()
(#8858)InMemoryDataset
to reconstruct the correct data class when a pre_transform
has modified it (#8692)OnDiskDataset
(#8663)DMoNPooing
loss function (#8285)NaN
handling in SQLDatabase
(#8479)CaptumExplainer
in case no index
is passed (#8440)edge_index
construction in the UPFD
dataset (#8413)AttentionalAggregation
and DeepSetsAggregation
(#8406)GraphMaskExplainer
for GNNs with more than two layers (#8401)input_id
computation in NeighborLoader
in case a mask
is given (#8312)Linear
layers (#8311)Data.subgraph()
/HeteroData.subgraph()
in case edge_index
is not defined (#8277)MetaPath2Vec
(#8248)AttentionExplainer
usage within AttentiveFP
(#8244)load_from_state_dict
in lazy Linear
modules (#8242)DimeNet++
performance on QM9
(#8239)GNNExplainer
usage within AttentiveFP
(#8216)to_networkx(to_undirected=True)
in case the input graph is not undirected (#8204)TwoHop
and AddRandomWalkPE
transformations (#8197, #8225)HeteroData
objects converted via ToSparseTensor()
when torch-sparse
is not installed (#8356)add_self_loops=True
in GCNConv(normalize=False)
(#8210)use_segment_matmul
based on benchmarking results (from a heuristic-based version) (#8615)NELL
and AttributedGraphDataset
are now represented as torch.sparse_csr_tensor
instead of torch_sparse.SparseTensor
(#8679)torch.sparse
tensors (#8670)ExplainerDataset
will now contain node labels for any motif generator (#8519)utils.softmax
faster via the in-house pyg_lib.ops.softmax_csr
kernel (#8399)utils.mask.mask_select
faster (#8369)Dataset.num_classes
on regression datasets (#8550)Full Changelog: https://github.com/pyg-team/pytorch_geometric/compare/2.4.0...2.5.0
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.4 | |
---|---|
|
|
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 (#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)summary
on modules with uninitialized parameters (#7884)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)edge_label_index
computation in LinkNeighborLoader
for the homogeneous+disjoint mode (#7791)CaptumExplainer
for binary classification tasks (#7787)HeteroData
(#7714)get_mesh_laplacian
for normalization="sym"
(#7544)dim_size
to initialize output size of the EquilibriumAggregation
layer (#7530)SparseTensor
(#7519)scaler
tensor in GeneralConv
to the correct device (#7484)HeteroLinear
bug when used via mixed precision (#7473)utils.spmm
(#7428)QuantileAggregation
when dim_size
is passed (#7407)LightGCN.recommendation_loss()
to only use the embeddings of the nodes involved in the current mini-batch (#7384)to_hetero_with_bases
(#7363)node_default
and edge_default
attributes in from_networkx
(#7348)HGTConv
utility function _construct_src_node_feat
(#7194)subgraph
on unordered inputs (#7187)HeteroDictLinear
(#7185)numpy
incompatiblity when reading files for Planetoid
datasets (#7141)CaptumExplainer
to be called multiple times in a row (#7391)AddLaplacianEigenvectorPE
for small-scale graphs (#8143)top_k
computation in TopKPooling
(#7737)GIN
implementation in benchmarks to apply sequential batch normalization (#7955)QM9
data pre-processing to include the SMILES string (#7867)training
flag in to_hetero
modules (#7772)add_random_edge
to only add true negative edges (#7654)BasicGNN
models in DeepGraphInfomax
(#7648)num_edges
parameter to the forward method of HypergraphConv
(#7560)max_num_elements
parameter to the forward method of GraphMultisetTransformer
, GRUAggregation
, LSTMAggregation
, SetTransformerAggregation
and SortAggregation
(#7529, #7367)ClusterLoader
to integrate pyg-lib
METIS routine (#7416)filter_per_worker
option will not get automatically inferred by default based on the device of the underlying data (#7399)fill_value
as a torch.tensor
to utils.to_dense_batch
(#7367)NeighborLoader
instead of NeighborSampler
(#7152)batch_size
argument to avg_pool_x
and max_pool_x
(#7216)from_networkx
memory footprint by reducing unnecessary copies (#7119)batch_size
argument to LayerNorm
, GraphNorm
, InstanceNorm
, GraphSizeNorm
and PairNorm
(#7135)MultiAggregation
(#7077)HeterophilousGraphDataset
are now undirected by default (#7065)batch_size
and max_num_nodes
arguments to MemPooling
layer (#7239)Full Changelog: https://github.com/pyg-team/pytorch_geometric/compare/2.3.0...2.4.0
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
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 @RemyLau