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:
- Created 4 years ago
- Comments:8 (2 by maintainers)
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
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
I fixed the bug in
torch-scatter
master. In the end, this is not a PyTorch Geometric bug but rather a PyTorch bug, whereview()
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!