RuntimeError: index 5 is out of bounds for dimension 0 with size 5

PARUL_JOSHI: <p>I’m stuck with this error and not able to rectify.</p>
<hr>
<p>RuntimeError                              Traceback (most recent call last)<br>
Cell In[40], line 38<br>
35 edge_index = edge_index.to(device)  # Move edge indices to device<br>
36 batch_labels = batch_labels.to(device)  # Move labels to device<br>
—&gt; 38 output = mil_model(batch_data, edge_index)<br>
39 edl_outputs = edl_model(output)<br>
40 test_loss += criterion(edl_outputs, batch_labels).item()</p>
<p>File ~\AppData\Local\anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)<br>
1126 # If we don’t have any hooks, we want to skip the rest of the logic in<br>
1127 # this function, and just call forward.<br>
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks<br>
1129         or _global_forward_hooks or _global_forward_pre_hooks):<br>
 → 1130     return forward_call(*input, **kwargs)<br>
1131 # Do not call functions when jit is used<br>
1132 full_backward_hooks, non_full_backward_hooks = [], []</p>
<p>Cell In[28], line 81, in MILModel.forward(self, x, edge_index)<br>
80 def forward(self, x, edge_index):<br>
—&gt; 81     x = self.gcn_fe_extractor(x, edge_index)<br>
82     x = self.edl_model(x)<br>
83     return x</p>
<p>File ~\AppData\Local\anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)<br>
1126 # If we don’t have any hooks, we want to skip the rest of the logic in<br>
1127 # this function, and just call forward.<br>
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks<br>
1129         or _global_forward_hooks or _global_forward_pre_hooks):<br>
 → 1130     return forward_call(*input, **kwargs)<br>
1131 # Do not call functions when jit is used<br>
1132 full_backward_hooks, non_full_backward_hooks = [], []</p>
<p>Cell In[28], line 33, in GCNFeatureExtractor.forward(self, x, edge_index)<br>
31 def forward(self, x, edge_index):<br>
32     # Implement the forward pass of the GCN feature extractor<br>
—&gt; 33     x = self.conv1(x, edge_index)<br>
34     x = torch.relu(x)<br>
35     x = self.conv2(x, edge_index)</p>
<p>File ~\AppData\Local\anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)<br>
1126 # If we don’t have any hooks, we want to skip the rest of the logic in<br>
1127 # this function, and just call forward.<br>
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks<br>
1129         or _global_forward_hooks or _global_forward_pre_hooks):<br>
 → 1130     return forward_call(*input, **kwargs)<br>
1131 # Do not call functions when jit is used<br>
1132 full_backward_hooks, non_full_backward_hooks = [], []</p>
<p>File ~\AppData\Local\anaconda3\lib\site-packages\torch_geometric\nn\conv\gcn_conv.py:210, in GCNConv.forward(self, x, edge_index, edge_weight)<br>
208 cache = self._cached_edge_index<br>
209 if cache is None:<br>
 → 210     edge_index, edge_weight = gcn_norm(  # yapf: disable<br>
211         edge_index, edge_weight, x.size(self.node_dim),<br>
212         self.improved, self.add_self_loops, self.flow, x.dtype)<br>
213     if self.cached:<br>
214         self._cached_edge_index = (edge_index, edge_weight)</p>
<p>File ~\AppData\Local\anaconda3\lib\site-packages\torch_geometric\nn\conv\gcn_conv.py:100, in gcn_norm(edge_index, edge_weight, num_nodes, improved, add_self_loops, flow, dtype)<br>
98 row, col = edge_index[0], edge_index[1]<br>
99 idx = col if flow == ‘source_to_target’ else row<br>
 → 100 deg = scatter(edge_weight, idx, dim=0, dim_size=num_nodes, reduce=‘sum’)<br>
101 deg_inv_sqrt = deg.pow_(-0.5)<br>
102 deg_inv_sqrt.masked_fill_(deg_inv_sqrt == float(‘inf’), 0)</p>
<p>File ~\AppData\Local\anaconda3\lib\site-packages\torch_geometric\utils\scatter.py:74, in scatter(src, index, dim, dim_size, reduce)<br>
72 if reduce == ‘sum’ or reduce == ‘add’:<br>
73     index = broadcast(index, src, dim)<br>
—&gt; 74     return src.new_zeros(size).scatter_add_(dim, index, src)<br>
76 if reduce == ‘mean’:<br>
77     count = src.new_zeros(dim_size)</p>
<p>RuntimeError: index 5 is out of bounds for dimension 0 with size 5</p>

ptrblck: <p>The <code>scatter_add_</code> operation fails in your PyG model as the index is out of bounds.<br>
Here is a simple code reproducing the error:</p>
<pre><code class="lang-python">src = torch.ones((2, 5))
index = torch.tensor([[0, 1, 2, 3, 4]])

# works
torch.zeros(5, 5, dtype=src.dtype).scatter_add_(0, index, src)

# fails
index[0, 0] = 5
torch.zeros(5, 5, dtype=src.dtype).scatter_add_(0, index, src)
# RuntimeError: index 5 is out of bounds for dimension 0 with size 5
</code></pre>
<p>Make sure the <code>index</code> is valid for the <code>size</code>.<br>
Based on your code I would probably start by checking the <code>edge_index</code> tensor and its values.</p>
<p>PS: you can post code snippets by wrapping them into three backticks ```, which makes debugging easier. <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=12" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>

PARUL_JOSHI: <p>Thanks you for the solution. Can you just review my model and help me with the debugging.<br>
Below is the link to my colab:</p>
<p>[<a href="https://colab.research.google.com/drive/137Op-sLteijOW3UhgxRayKZPbPMx4Sgq?usp=sharing" class="inline-onebox" rel="noopener nofollow ugc">Google Colab</a>]</p>

ptrblck: <p>I won’t be able to execute the notebook as the data is missing. Could you check the inputs and maybe create random tensors using the same ranges, which could reproduce the issue, and would allow me to run the code locally?</p>

PARUL_JOSHI: <p>Hey, I have updated the code accordingly and have replicated the error. Although its not exactly the same, only the number difference is there that is original code error said</p>
<p><code>RuntimeError: index 5 is out of bounds for dimension 0 with size 5</code></p>
<p>The error provided in the link has the number change from 5 to 10</p>
<p>link of the colab is:<br>
[<a href="https://colab.research.google.com/drive/1Dg523Mcw87evnxE2pb5wYwURWD6mA0XJ?usp=sharing" class="inline-onebox" rel="noopener nofollow ugc">Google Colab</a>]</p>

ptrblck: <p>Thanks for the code!<br>
As mentioned before the <code>scatter</code> operation fails <a href="https://github.com/pyg-team/pytorch_geometric/blob/48df293c7a87ac998cb33deec239af28e7794e3f/torch_geometric/nn/conv/gcn_conv.py#L100C11-L100">here</a> which is called from <a href="https://github.com/pyg-team/pytorch_geometric/blob/48df293c7a87ac998cb33deec239af28e7794e3f/torch_geometric/nn/conv/gcn_conv.py#L228-L230">here</a>.<br>
You can see that the <code>num_nodes</code> argument is calculated from <code>x.size(self.node_dim)</code>, which is <code>10</code> in your case and explains the error:</p>
<pre><code class="lang-python">batch_data.size(mil_model.gcn_fe_extractor.conv1.node_dim)
# 10
</code></pre>
<p>If you <code>clamp_</code> the <code>edge_index</code> to <code>[0, 9]</code> the code works as expected and also if you <code>repeat</code> the input to <code>&gt; edge_index.max() = tensor(75202)</code> it also works (but fails later in the model with a shape mismatch).<br>
You would thus still need to check why the edge indices are out of bounds given the input shape.</p>

PARUL_JOSHI: <p>Thank you for clarifying the issue!! <img src="https://discuss.pytorch.org/images/emoji/apple/blush.png?v=12" title=":blush:" class="emoji" alt=":blush:" loading="lazy" width="20" height="20"></p>