0

I have a variable A which is a long list of torch list as follows:

A

[[tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')],
 [tensor(0.9800, device='cuda:0'), tensor(0.0300, device='cuda:0')]..........

I want to convert them to np.array and have used A= np.array(A) and received an error of TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first. Then I used A= np.array(A).cpu() and got

AttributeError: 'list' object has no attribute 'cpu'

How can I do that?

yaodao vang
  • 168
  • 10

1 Answers1

0

You have to call cpu() on tensor so the data first moves from gpu to to cpu and then you can convert it to numpy array. See Convert PyTorch CUDA tensor to NumPy array

Pytorch stores your data in tensors and when using GPU, the data is in GPU memory, not in your RAM. Thus to convert a tensor A to numpy array, the data needs to be transferred to cpu first via A.cpu() and then call .numpy().

Note - If tensor is already in CPU, calling .cpu() is a no-op method. See official docs.

Example:-

import torch

# Create a sample tensor
my_tensor = torch.rand(4).cuda()
print(my_tensor)
# tensor([0.9679, 0.0314, 0.7108, 0.3633], device='cuda:0')

# Convert tensor to list of tensor
tensor_list = [my_tensor]
print(tensor_list)
#[tensor([0.9679, 0.0314, 0.7108, 0.3633], device='cuda:0')]

# Convert list of tensor to list of numpy array
numpy_list = []
for _tensor in tensor_list:
    numpy_list.append(_tensor.detach().cpu().numpy())

# [array([0.9678591 , 0.03141624, 0.7108203 , 0.36325622], dtype=float32)]
print(numpy_list)

The above code shows how to take list of tensor in gpu and convert to list of numpy array.

saurabheights
  • 3,967
  • 2
  • 31
  • 50
  • I have already tried that and that gave `AttributeError: 'list' object has no attribute 'detach'` @saurabheights the type of A is list and it is like this `[[tensor(1., device='cuda:0'), tensor(0., device='cuda:0')], [tensor(1., device='cuda:0'), tensor(0., device='cuda:0')]]` but longer – yaodao vang Apr 16 '23 at 09:22
  • You have to call `.detach()` on each tensor, but you are calling `.detach` on list of tensor. List does not have `detach/cpu/numpy` methods, thats why you are facing attribute error. Edited. – saurabheights Apr 16 '23 at 09:25
  • By call `.detach() `on each tensor @saurabheights do you mean `A..detach() ` that also gives `AttributeError: 'list' object has no attribute 'detach'`. I read your example but that doesn't resemble my question. The `A` is a list of two tensor near each other. Each row is like `[[tensor(1., device='cuda:0'), tensor(0., device='cuda:0')]` not `[tensor([0, 0, 0], device='cuda:0')]` – yaodao vang Apr 16 '23 at 09:41
  • @yaodaovang - Please read the example I provided properly. My list has one tensor of size 4, whereas you have list of many tensors of size 1. However, this is not your issue. You are calling A.detach() where A is your list. You should be calling A[0].detach() for first tensor, A[1].detach() for second tensor and so on. Thats why you are getting error `'list' object has no attribute 'detach'`. – saurabheights Apr 16 '23 at 10:15