Repository: pyg-team/pytorch_geometric

Issue:
Approximate PPR implementation in the GDC transform expects the graph to not have isolated nodes
### 🐛 Describe the bug

Hi, the approximate implementation of the PPR algorithm that is present in the GDC transform expects the graph to not have any isolated nodes and crashes if it has. This is not documented in the docs or in the code (where there is a mention of coalesced edge index, but I believe that is a slightly different thing).

Example:
```python
from copy import deepcopy
from torch_geometric.data.data import Data
from torch_geometric.datasets import KarateClub
from torch_geometric.transforms import GDC

gdc = GDC(
    self_loop_weight = 0,
    normalization_in = "sym",
    normalization_out = "col",
    diffusion_kwargs = dict(method = "ppr", alpha = 0.15, eps = 1e-2),
    sparsification_kwargs = dict(method = "threshold", eps = 1e-4),
    exact = False
)

data: Data = KarateClub()[0]

# Run GDC on a graph without isolated nodes, works fine
data2 = gdc(deepcopy(data))

# Remove all edges leading to/from node 3
data.edge_index = data.edge_index[:, data.edge_index[0, :] != 3]
data.edge_index = data.edge_index[:, data.edge_index[1, :] != 3]

# Run GDC on graph with an isolated node, doesn't work
data3 = gdc(deepcopy(data))
```
The last line is where the problem lies. It may not manifest right away (in fact, with this minimal example it does not for me) because some o the code is JITed with numba. However, if I comment out line
https://github.com/pyg-team/pytorch_geometric/blob/01482d424bd04be2ca58fb921467d6b3933cc08b/torch_geometric/transforms/gdc.py#L545

I get:
```python
❯ python example.py
Traceback (most recent call last):
  File "/home/user/pytorch_geometric/example.py", line 25, in <module>
    data3 = gdc(deepcopy(data))
  File "/opt/miniconda3/envs/pytorch_geometric/lib/python3.9/site-packages/torch/autograd/grad_mode.py", line 27, in decorate_context
    return func(*args, **kwargs)
  File "/home/user/pytorch_geometric/torch_geometric/transforms/gdc.py", line 125, in __call__
    edge_index, edge_weight = self.diffusion_matrix_approx(
  File "/home/user/pytorch_geometric/torch_geometric/transforms/gdc.py", line 312, in diffusion_matrix_approx
    neighbors, neighbor_weights = self.__calc_ppr__(
  File "/home/user/torch_geometric/transforms/gdc.py", line 596, in calc_ppr
    if res_vnode >= alpha_eps * out_degree[vnode]:
IndexError: index 33 is out of bounds for axis 0 with size 33
```

If numba is enabled, the issue manifests as a total process freeze for more complicated examples.

### Environment

* PyG version: 01482d424bd04be2ca58fb921467d6b3933cc08b
* PyTorch version: 1.13.0
* OS: Debian testing
* Python version: 3.9
* CUDA/cuDNN version: CPU only
* How you installed PyTorch and PyG (`conda`, `pip`, source): PyG from source, everything else with conda
* Any other relevant information (*e.g.*, version of `torch-scatter`): torch-scatter 2.1.0, torch-sparse 0.6.15



Discussion:

Resolving patch:
diff --git a/torch_geometric/transforms/gdc.py b/torch_geometric/transforms/gdc.py
--- a/torch_geometric/transforms/gdc.py
+++ b/torch_geometric/transforms/gdc.py
@@ -303,11 +303,11 @@ def diffusion_matrix_approx(
                 deg = scatter_add(edge_weight, col, dim=0, dim_size=num_nodes)
 
             edge_index_np = edge_index.cpu().numpy()
-            # Assumes coalesced edge_index.
-            _, indptr, out_degree = np.unique(edge_index_np[0],
-                                              return_index=True,
-                                              return_counts=True)
-            indptr = np.append(indptr, len(edge_index_np[0]))
+
+            # Assumes sorted and coalesced edge indices:
+            indptr = torch._convert_indices_from_coo_to_csr(
+                edge_index[0], num_nodes).cpu().numpy()
+            out_degree = indptr[1:] - indptr[:-1]
 
             neighbors, neighbor_weights = self.__calc_ppr__(
                 indptr, edge_index_np[1], out_degree, kwargs['alpha'],


Test patch: