Repository: pyg-team/pytorch_geometric
Pull request #7589 (2023-06-15 11:44:04)

Check lazy initialization with `SAGEConv(project=True)`

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/pyg-team/pytorch_geometric/pull/7589?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyg-team) Report
> Merging [#7589](https://app.codecov.io/gh/pyg-team/pytorch_geometric/pull/7589?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyg-team) (45efef2) into [master](https://app.codecov.io/gh/pyg-team/pytorch_geometric/commit/8cb9bf29516b9bc069b38fe37d562ca83f2838df?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyg-team) (8cb9bf2) will **decrease** coverage by `0.32%`.
> The diff coverage is `100.00%`.

> :exclamation: Current head 45efef2 differs from pull request most recent head d63c455. Consider uploading reports for the commit d63c455 to get more accurate results

```diff
@@            Coverage Diff             @@
##           master    #7589      +/-   ##
==========================================
- Coverage   91.73%   91.42%   -0.32%     
==========================================
  Files         449      449              
  Lines       25128    25123       -5     
==========================================
- Hits        23052    22968      -84     
- Misses       2076     2155      +79     
```


| [Impacted Files](https://app.codecov.io/gh/pyg-team/pytorch_geometric/pull/7589?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyg-team) | Coverage Δ | |
|---|---|---|
| [torch\_geometric/nn/conv/sage\_conv.py](https://app.codecov.io/gh/pyg-team/pytorch_geometric/pull/7589?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyg-team#diff-dG9yY2hfZ2VvbWV0cmljL25uL2NvbnYvc2FnZV9jb252LnB5) | `100.00% <100.00%> (+3.17%)` | :arrow_up: |

... and [17 files with indirect coverage changes](https://app.codecov.io/gh/pyg-team/pytorch_geometric/pull/7589/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyg-team)

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyg-team)


Patch:
diff --git a/torch_geometric/nn/conv/sage_conv.py b/torch_geometric/nn/conv/sage_conv.py
index 3eba1674d..636550267 100644
--- a/torch_geometric/nn/conv/sage_conv.py
+++ b/torch_geometric/nn/conv/sage_conv.py
@@ -2,7 +2,6 @@ from typing import List, Optional, Tuple, Union
 
 import torch.nn.functional as F
 from torch import Tensor
-from torch.nn import LSTM
 
 from torch_geometric.nn.aggr import Aggregation, MultiAggregation
 from torch_geometric.nn.conv import MessagePassing
@@ -92,12 +91,12 @@ class SAGEConv(MessagePassing):
         super().__init__(aggr, **kwargs)
 
         if self.project:
+            if in_channels[0] <= 0:
+                raise ValueError(f"'{self.__class__.__name__}' does not "
+                                 f"support lazy initialization with "
+                                 f"`project=True`")
             self.lin = Linear(in_channels[0], in_channels[0], bias=True)
 
-        if self.aggr is None:
-            self.fuse = False  # No "fused" message_and_aggregate.
-            self.lstm = LSTM(in_channels[0], in_channels[0], batch_first=True)
-
         if isinstance(self.aggr_module, MultiAggregation):
             aggr_out_channels = self.aggr_module.get_out_channels(
                 in_channels[0])


Test patch:
diff --git a/test/nn/conv/test_sage_conv.py b/test/nn/conv/test_sage_conv.py
index afc1f3076..0ff0066ea 100644
--- a/test/nn/conv/test_sage_conv.py
+++ b/test/nn/conv/test_sage_conv.py
@@ -56,6 +56,22 @@ def test_sage_conv(project, aggr):
         assert torch.allclose(jit((x1, None), adj.t()), out2, atol=1e-6)
 
 
+@pytest.mark.parametrize('project', [False, True])
+def test_lazy_sage_conv(project):
+    x = torch.randn(4, 8)
+    edge_index = torch.tensor([[0, 1, 2, 3], [0, 0, 1, 1]])
+
+    if project:
+        with pytest.raises(ValueError, match="does not support lazy"):
+            SAGEConv(-1, 32, project=project)
+    else:
+        conv = SAGEConv(-1, 32, project=project)
+        assert str(conv) == 'SAGEConv(-1, 32, aggr=mean)'
+
+        out = conv(x, edge_index)
+        assert out.size() == (4, 32)
+
+
 def test_lstm_aggr_sage_conv():
     x = torch.randn(4, 8)
     edge_index = torch.tensor([[0, 1, 2, 3], [0, 0, 1, 1]])