# Construct new tensor on correct device based on input

**URL:** <https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469>\
**Category:** Uncategorized\
**Created:** [February 13, 2017, 2:54am UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469 "2017-02-13T02:54:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ypxie](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/y/43a26b/32.png) [@ypxie](https://discuss.pytorch.org/u/ypxie)\
**Post date:** [February 13, 2017, 2:54am UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/1 "2017-02-13T02:54:51Z")

</div>

I know `input.new()` will create a new tensor of the same dtype to `input`.

But what I want to do is to create a new tensor on the same device to input, but has different data types.  
for example, input is `torch.cuda.FloatTensor`  
but I wanna something like `torch.cuda.LongTensor`

Is there any way to do it without `if_else` wrt `use_cuda` ?

---

<div class="post-metadata">

**Author:** ![apaszke](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/apaszke/32/21_2.png) [@apaszke](https://discuss.pytorch.org/u/apaszke)\
**Post date:** [February 13, 2017, 12:40pm UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/2 "2017-02-13T12:40:33Z")

</div>

`input.new().long()` should do it. Type casts retain the device, and if you give no arguments to `new` the tensor isn’t going to have any memory allocated, so the cast is nearly free.

---

<div class="post-metadata">

**Author:** ![wouter](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/wouter/32/30625_2.png) [@wouter](https://discuss.pytorch.org/u/wouter)\
**Post date:** [January 8, 2018, 1:01pm UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/3 "2018-01-08T13:01:38Z")

</div>

Hi! I’m sorry to reply to an old post but I thought replying here would be better than starting a new topic.

What if you do give arguments to `new`, for instance to create 0’s or from a numpy list of data? I found some ways but I’m not sure what’s the best way to do it.

So let’s say we have given `X`:

```
device = 1
X = torch.rand(10).cuda(device) # or X = torch.rand(10)

```

How to make code below agnostic to whether X is on CPU/GPU and which device?

```
# Fill with numpy data
data = np.array([1, 2, 3]) # For example indices calculated by custom Python procedure
X.new().long().new(data) # Works on CPU, error on GPU?
X.new().long().new(*data.shape).copy_(torch.from_numpy(data)) # Works but verbose
X.new(data.astype(float)).long() # Inefficient, lossy?
# X.new(data) # Error

# Or fill with zeros
X.new(10).long().zero_() # Works, but inefficient?
X.new().long().new(10).zero_() # Works, but verbose?
```

---

<div class="post-metadata">

**Author:** ![smth](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/smth/32/13_2.png) [@smth](https://discuss.pytorch.org/u/smth)\
**Post date:** [January 8, 2018, 2:17pm UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/4 "2018-01-08T14:17:59Z")

</div>

@wouter your post is unrelated to the parent topic (parent topic is about GPU tensors)

---

<div class="post-metadata">

**Author:** ![wouter](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/wouter/32/30625_2.png) [@wouter](https://discuss.pytorch.org/u/wouter)\
**Post date:** [January 10, 2018, 8:58am UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/5 "2018-01-10T08:58:57Z")

</div>

@smth I’m sorry if it was not clear. Actually I meant that `X` can be on any device, then how to construct a Tensor with numpy data or 0’s on that same device. I edited my post, please let me know if I should open a new topic for this.

---

<div class="post-metadata">

**Author:** ![bgobbi](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/b/fbc32d/32.png) [@bgobbi](https://discuss.pytorch.org/u/bgobbi)\
**Post date:** [August 16, 2018, 1:38pm UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/6 "2018-08-16T13:38:26Z")

</div>

The new() method is deprecated.

> <https://github.com/pytorch/pytorch/issues/3920>

What is the new alternative for this use case?

---

<div class="post-metadata">

**Author:** ![shlomia](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/shlomia/32/25585_2.png) [@shlomia](https://discuss.pytorch.org/u/shlomia)\
**Post date:** [June 23, 2020, 6:49am UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/7 "2020-06-23T06:49:39Z")

</div>

new\_tensor = new\_tensor.to(input.device)  
will change new tensor to be cuda if needed.

---

<div class="post-metadata">

**Author:** ![Noam\_Salomonski](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/noam_salomonski/32/9359_2.png) [@Noam\_Salomonski](https://discuss.pytorch.org/u/Noam_Salomonski)\
**Post date:** [January 19, 2021, 3:33pm UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/8 "2021-01-19T15:33:35Z")

</div>

> new\_tensor = new\_tensor.to(input.device)  
> will change new tensor to be cuda if needed.

This creates very ugly (and slow) code such as

```
    if std.is_cuda:
        eps = torch.FloatTensor(std.size()).cuda().normal_()
    else:
        eps = torch.FloatTensor(std.size()).normal_()

```

instead of the much better  
`eps = std.new().normal_()`

Isn’t there a better way?

---

<div class="post-metadata">

**Author:** ![Noam\_Salomonski](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/noam_salomonski/32/9359_2.png) [@Noam\_Salomonski](https://discuss.pytorch.org/u/Noam_Salomonski)\
**Post date:** [October 16, 2022, 9:22am UTC](https://discuss.pytorch.org/t/construct-new-tensor-on-correct-device-based-on-input/469/9 "2022-10-16T09:22:34Z")

</div>

[answer to my question](https://stackoverflow.com/a/65794995/913098)
