An mwe is as follows:
import torch
import torch.nn as nn
class model(nn.Module):
def __init__(self):
super(model,self).__init__()
self.mat = torch.randn(2,2)
def forward(self,x):
print('self.mat.device is',self.mat.device)
x = torch.mv(self.mat,x)
return x
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
m = model()
m.to(device)
x = torch.tensor([2.,1.])
x = x.to(device)
m(x)
The output is
self.mat.device is cpu
and right after that comes
Traceback (most recent call last):
File "Z:\cudatest.py", line 21, in <module>
print(m(x))
File "E:\Python37\lib\site-packages\torch\nn\modules\module.py", line 532, in __call__
result = self.forward(*input, **kwargs)
File "Z:\cudatest.py", line 11, in forward
x = torch.mv(self.mat,x)
RuntimeError: Expected object of device type cuda but got device type cpu for argument #1 'self' in call to _th_mv
The code works fine if I set device = torch.device('cpu'). It seems that the problem is model.mat is not moved to GPU even after m.to(device) is called. Why doesn't whis work? How can I fix this? Please note the following:
Even though this particular example can be fixed by using
self.mat = nn.Linear(2,2)andx = self.mat(x)instead, in my original program, I need a temporary tensor to store some data inforward()that is also used in some arithmetics. How can I construct such a tensor and send it to GPU when callingm.to(device)It is not known in advance whether the computer has GPU or not. Therefore, writing
self.mat = self.mat.cuda()is not a good solution for my case.