odlgroup / odl

Operator Discretization Library https://odlgroup.github.io/odl/
Mozilla Public License 2.0
375 stars 105 forks source link

odl.operator.operator.OpDomainError: unable to cast tensor to an element of the domain uniform_discr #1621

Open ys830 opened 2 years ago

ys830 commented 2 years ago

This is my source code for debug:

path = "/ys/mywork/2d_ct-master/data/2d_ct_data/test/1.tiff"
img = cv2.imread(path, -1)
img = torch.from_numpy(img).cuda()
reco_space = odl.uniform_discr(min_pt=[-1,-1], max_pt=[1,1], shape=img.shape, dtype='float32')
geometry = odl.tomo.parallel_beam_geometry(reco_space, num_angles=360)
projector = odl.tomo.RayTransform(reco_space,geometry, impl='astra_cuda')
proj =  projector(img)

I use ODL to generate parallel beam 2D ct projections, which is cascaded after my neural network, I met a problem:

Traceback (most recent call last):
  File "/root/.anaconda3/envs/raw/lib/python3.7/site-packages/odl/operator/operator.py", line 662, in __call__
    x = self.domain.element(x)
  File "/root/.anaconda3/envs/raw/lib/python3.7/site-packages/odl/discr/lp_discr.py", line 375, in element
    self, self.tspace.element(inp, order=order))
  File "/root/.anaconda3/envs/raw/lib/python3.7/site-packages/odl/space/npy_tensors.py", line 429, in element
    order=order)
  File "/root/.anaconda3/envs/raw/lib/python3.7/site-packages/torch/_tensor.py", line 645, in __array__
    return self.numpy().astype(dtype, copy=False)
TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "train.py", line 133, in <module>
    pre_proj = ct_project_train(pre) #[b,h,w]
  File "/root/.anaconda3/envs/raw/lib/python3.7/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "/ys/mywork/2d_ct-master/ct_project.py", line 123, in forward
    proj =  projector(x)
  File "/root/.anaconda3/envs/raw/lib/python3.7/site-packages/odl/operator/operator.py", line 666, in __call__
    'the domain {!r}'.format(x, self.domain))
odl.operator.operator.OpDomainError: unable to cast tensor([[0.4911, 0.4911, 0.4911,  ..., 0.4911, 0.4911, 0.4911],
        [0.4911, 0.4911, 0.4911,  ..., 0.4911, 0.4911, 0.4911],
        [0.4911, 0.4911, 0.4911,  ..., 0.4911, 0.4911, 0.4911],
        ...,
        [0.4911, 0.4911, 0.4911,  ..., 0.4911, 0.4911, 0.4911],
        [0.4911, 0.4911, 0.4911,  ..., 0.4911, 0.4911, 0.4911],
        [0.4911, 0.4911, 0.4911,  ..., 0.4911, 0.4911, 0.4911]],
       device='cuda:0', grad_fn=<SqueezeBackward1>) to an element of the domain uniform_discr([-1., -1.], [ 1.,  1.], (256, 256), dtype='float32')

It seems that because my input data is a tensor on the GPU, when I use .cpu(), it can run normally. How should I modify the code if I want to operate the tensor on the GPU?