Torch c++ index_put doesn't inplace change the tensor

torch::Tensor a = torch::ones({10}, torch::TensorOptions().dtype(torch::kI64));
torch::Tensor b = torch::zeros({3}, torch::TensorOptions().dtype(torch::kI64));
torch::Tensor torchIdx_test = at::tensor({0,2,7}).toType(torch::kInt64);
a.index_put({torchIdx_test}, b);
std::cout << a<<std::endl;

but the result is not as expect

 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
[ CPULongType{10} ]

however

a = a.index_put({torchIdx_test}, b);

it will work as expectation

 0
 1
 0
 1
 1
 1
 1
 0
 1
 1
[ CPULongType{10} ]

I wonder is there any in-place operation? If not, is “=” operation will do real copy of memory?

Btw, I also tried operation like “a.index() = b”. it didn’t work either.

I believe this is because a tuple or something iterable of tensors is expected as according to the documentation:
https://pytorch.org/docs/stable/generated/torch.Tensor.index_put_.html#torch.Tensor.index_put_
e.g., in the Python side

import torch

a = torch.ones(10, dtype=torch.long)
b = torch.zeros(3, dtype=torch.long)
torchIdx_test = torch.tensor([0, 2, 7], dtype=torch.long)
print(a.index_put(torchIdx_test, b))

yields

TypeError: index_put(): argument 'indices' (position 1) must be tuple of Tensors, not Tensor

but

import torch

a = torch.ones(10, dtype=torch.long)
b = torch.zeros(3, dtype=torch.long)
torchIdx_test = torch.tensor([0, 2, 7], dtype=torch.long)
print(a.index_put((torchIdx_test,), b))

will work as expected.
If you want an in-place version, call index_put_:

import torch

a = torch.ones(10, dtype=torch.long)
b = torch.zeros(3, dtype=torch.long)
torchIdx_test = torch.tensor([0, 2, 7], dtype=torch.long)
a.index_put_((torchIdx_test,), b)
print(a)
tensor([0, 1, 0, 1, 1, 1, 1, 0, 1, 1])

Thanks for replay.
In c++, the input type of index is

const c10::List<c10::optional<at::Tensor>> & indices

List is like tuple as you said. So I call the initialization function using {}, e.g. {torchIdx_test}. But still didn’t work.

Sorry, I misunderstood the two examples given in the question. You would need to call index_put_ for the in-place version rather than index_put.

1 Like

index_put_ works, It solved my problem! really appreciate that!
And there is still something weird.
When I tried

a.index({torchIdx_test}) = b;
std::cout << a<<std::endl;

I got

 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
[ CPULongType{10} ]

but if I try

a.index({Slice(0,3)}) = b;
std::cout << a<<std::endl;

the result will be as expected

 0
 0
 0
 1
 1
 1
 1
 1
 1
 1
[ CPULongType{10} ]

Do you have any ideas?