question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

device of 'edge_index' is changed when' edge_index' is empty

See original GitHub issue

🐛 Bug

To Reproduce

Steps to reproduce the behavior:

import torch
from torch_geometric.nn import EdgeConv
import torch.nn as nn
import torch.nn.functional as F
from torch_geometric.data import Data

class MLP(nn.Module):
    def __init__(self, F_in, F_out):
        super(MLP, self).__init__()
        self.mlp = nn.Sequential(
            nn.Linear(2 * F_in, F_out),
            nn.ReLU(inplace=True))

    def forward(self, x):
        return self.mlp(x)

class TestBlock(nn.Module):
    def __init__(self, F_in, F_out):
        super(TestBlock, self).__init__()
        self.edge_conv1 = EdgeConv(MLP(F_in, F_out),aggr='mean')
        self.edge_conv2 = EdgeConv(MLP(F_out, F_out), aggr='mean') 
        self.fc = nn.Linear(F_out, 16)
        
    def forward(self, data):
        x = data.x
        edge_index = data.edge_index 
        x = self.edge_conv1(x, edge_index)
        x = self.fc(self.edge_conv2(x, edge_index))
        return x

d = torch.device('cuda:1')
block = TestBlock(4, 8).to(d)
edge_index = torch.tensor([[], []], dtype=torch.long)
data = Data(x=x, edge_index=edge_index)
y = block(data.to(d))
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-34-d1a9b2a113f2> in <module>
      1 edge_index = torch.tensor([[], []], dtype=torch.long)
      2 data = Data(x=x, edge_index=edge_index)
----> 3 y = block(data.to(d))
      4 print(y)
      5 print(data.edge_index.data)

~/miniconda3/envs/py36_pytorch110/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    491             result = self._slow_forward(*input, **kwargs)
    492         else:
--> 493             result = self.forward(*input, **kwargs)
    494         for hook in self._forward_hooks.values():
    495             hook_result = hook(self, input, result)

<ipython-input-31-b450444a54a6> in forward(self, data)
     24         edge_index = data.edge_index
     25         x = self.edge_conv1(x, edge_index)
---> 26         x = self.fc(self.edge_conv2(x, edge_index))
     27         return x

~/miniconda3/envs/py36_pytorch110/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    491             result = self._slow_forward(*input, **kwargs)
    492         else:
--> 493             result = self.forward(*input, **kwargs)
    494         for hook in self._forward_hooks.values():
    495             hook_result = hook(self, input, result)

~/miniconda3/envs/py36_pytorch110/lib/python3.6/site-packages/torch_geometric/nn/conv/edge_conv.py in forward(self, x, edge_index)
     42         x = x.unsqueeze(-1) if x.dim() == 1 else x
     43 
---> 44         return self.propagate(edge_index, x=x)
     45 
     46     def message(self, x_i, x_j):

~/miniconda3/envs/py36_pytorch110/lib/python3.6/site-packages/torch_geometric/nn/conv/message_passing.py in propagate(self, edge_index, size, **kwargs)
     99                         raise ValueError(__size_error_msg__)
    100 
--> 101                     tmp = torch.index_select(tmp, 0, edge_index[idx])
    102                     message_args.append(tmp)
    103             else:

RuntimeError: arguments are located on different GPUs at /opt/conda/conda-bld/pytorch_1556653183467/work/aten/src/THC/generic/THCTensorIndex.cu:521
'''

## Expected behavior

<!-- A clear and concise description of what you expected to happen. -->

## Environment

* OS:   Linux 16.04
* Python version:  3.6
* PyTorch version: 1.1.0
* CUDA/cuDNN version:  9.0
* GCC version:  5.4.0
* Any other relevant information:

## Additional context

<!-- Add any other context about the problem here. -->
Maybe there are some problems in initialization, and I find some interesting thing in the function:
 `gen` in  `torch_scatter/utils/gen.py`

def gen(src, index, dim=-1, out=None, dim_size=None, fill_value=0): dim = range(src.dim())[dim] # Get real dim value.

# Automatically expand index tensor to the right dimensions.
if index.dim() == 1:
    index_size = list(repeat(1, src.dim()))
    index_size[dim] = src.size(dim)
    index = index.view(index_size).expand_as(src)

# Generate output tensor if not given.
if out is None:
    out_size = list(src.size())
    dim_size = maybe_dim_size(index, dim_size)
    out_size[dim] = dim_size
    out = src.new_full(out_size, fill_value)

return src, out, index, dim

The device of the index.data is 'cuda:1' before `index.view(index_size)` , but after that it changes to 'cuda:0' while the device of `index` is still 'cuda:1'. 


B.T.W, if the 'edge_index` of the first sample fed to the network is not empty , the bug is gone.

edge_index = torch.tensor([[0], [1]], dtype=torch.long) data = Data(x=x, edge_index=edge_index) y = block(data.to(d)) edge_index = torch.tensor([[], []], dtype=torch.long) data = Data(x=x, edge_index=edge_index) y = block(data.to(d)) print(y.device) print(data.edge_index.data)



The output:

cuda:1 tensor([], device=‘cuda:1’, size=(2, 0), dtype=torch.int64)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
WMF1997commented, Aug 18, 2019

p.s. @ZongweiZhou1 in most of time, edge_index may not be [[],[]]. (i.e. may not be empty…) while testing… (meaningful datasets, or random edge_index)

indeed, after adding something to the null edge_index, it works. (no error, and showing the device is cuda:1.

yours sincerely: @WMF1997

0reactions
rusty1scommented, Aug 24, 2019

I fixed the bug in torch-scatter master. In the end, this is not a PyTorch Geometric bug but rather a PyTorch bug, where view() seems to make stupid things when applied on zero-element tensors.

I do not think that bug is critical, so I wait till releasing a new torch-scatter release. Thank you very much!

Read more comments on GitHub >

github_iconTop Results From Across the Web

device of 'edge_index' is changed when' edge_index' is empty
If the edge_index of the first sample sent to the EdgeConv is not empty, while of the second sample is empty, the bug...
Read more >
Confluence logs filled with the error "Failed to process edge ...
The following error appears In the atlassian-confluence.log: WARN [scheduler_Worker-1] [search.lucene.queue.JournalIndexTaskQueue] lambda$ ...
Read more >
how to represent an graph in a tensor? - python - Stack Overflow
I have an graph in (igraph-python) n_vertices = 3 edges = [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3),...
Read more >
Solved Complete the following exercise of exception - Chegg
It contains one private member edgeIndex (int) that stores which edge (i.e., 1, ... This exception class is a trivial or empty class....
Read more >
Hands-on Graph Neural Networks with PyTorch & PyTorch ...
The graph connectivity (edge index) should be confined with the COO ... In fact, you can simply return an empty list and specify...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found