Reputation: 1163
I have a 3D tensor and would like to take the max values along the 0th dimension in Libtorch.
I know how to do this in Python (PyTorch) but I'm having trouble doing this in LibTorch.
In LibTorch my code is
auto target_q_T = torch::rand({5, 10, 1});
auto max_q = torch::max({target_q_T}, 0);
std::cout << max_q;
It returns this long, repeating error.
note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const char*)’
611 | operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
| ^~~~~~~~
/usr/include/c++/11/ostream:611:5: note: template argument deduction/substitution failed:
/home/iii/tor/m_gym/multiv_normal.cpp:432:18: note: cannot convert ‘max_q’ (type ‘std::tuple<at::Tensor, at::Tensor>’) to type ‘const char*’
432 | std::cout << max_q;
| ^~~~~
In file included from /usr/include/c++/11/istream:39,
from /usr/include/c++/11/sstream:38,
from /home/iii/tor/m_gym/libtorch/include/c10/macros/Macros.h:246,
from /home/iii/tor/m_gym/libtorch/include/c10/core/DeviceType.h:8,
from /home/iii/tor/m_gym/libtorch/include/c10/core/Device.h:3,
from /home/iii/tor/m_gym/libtorch/include/ATen/core/TensorBody.h:11,
from /home/iii/tor/m_gym/libtorch/include/ATen/core/Tensor.h:3,
from /home/iii/tor/m_gym/libtorch/include/ATen/Tensor.h:3,
from /home/iii/tor/m_gym/libtorch/include/torch/csrc/autograd/function_hook.h:3,
from /home/iii/tor/m_gym/libtorch/include/torch/csrc/autograd/cpp_hook.h:2,
from /home/iii/tor/m_gym/libtorch/include/torch/csrc/autograd/variable.h:6,
from /home/iii/tor/m_gym/libtorch/include/torch/csrc/autograd/autograd.h:3,
from /home/iii/tor/m_gym/libtorch/include/torch/csrc/api/include/torch/autograd.h:3,
from /home/iii/tor/m_gym/libtorch/include/torch/csrc/api/include/torch/all.h:7,
from /home/iii/tor/m_gym/libtorch/include/torch/csrc/api/include/torch/torch.h:3,
from /home/iii/tor/m_gym/multiv_normal.cpp:2:
/usr/include/c++/11/ostream:624:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed char*)’
624 | operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)
| ^~~~~~~~
This is how it works in Python.
target_q_np = torch.rand(5, 10, 1)
max_q = torch.max(target_q_np, 0)
max_q
torch.return_types.max(
values=tensor([[0.8517],
[0.7526],
[0.6546],
[0.9913],
[0.8521],
[0.9757],
[0.9080],
[0.9376],
[0.9901],
[0.7445]]),
indices=tensor([[4],
[2],
[3],
[4],
[1],
[0],
[2],
[4],
[4],
[4]]))
Upvotes: 0
Views: 2463
Reputation: 3573
If you read the compiler error, it basically tells you that you are trying to print a tuple of two tensors. That's because the C++ code works exactly like the python code and returns the max values and their respective indices (your python code prints exactly that). You need std get to extract the tensors from the tuple :
auto target_q_T = torch::rand({5, 10, 1});
auto max_q = torch::max({target_q_T}, 0);
std::cout << "max: " << std::get<0>(max_q)
<< "indices: " << std::get<1>(max_q)
<< std::endl;
In C++17 you should also be able to write
auto [max_t, idx_t] = torch::max({target_q_T}, 0);
std::cout << ... ;
Upvotes: 2
Reputation: 1163
I never found the equivent use of max
in LibTorch like there is in PyTorch so I did a workaround.
The max
in LibTorch will take the max from a 1D array so I loop over the indexed array and concatenate the results. Which, in effect returns the same thing as torch.max(target_q_np, 0).
My solution in LibTorch (C++). The array of max values is returned in reverse order as the original tensor, so I flip it.
auto target_q_T = torch::rand({5, 10, 1});
torch::Tensor zero_max;
for (int i=0; i<5; i++) {
zero_max = torch::cat({torch::max({target_q_T[i]}).unsqueeze(-1), zero_max}, 0);
}
zero_max = zero_max.flip(-1);
Upvotes: 0