How to give input as 'Tensor, Tuple[Tensor, Tensor]'

FenglongSong: <p>Dear all,</p>
<p>I’m new to libtorch and I’m loading an LSTM model and doing forward evaluation. The model’s input is <code>Tensor, Tuple[Tensor, Tsneor]</code> since the following Python code works:</p>
<pre><code class="lang-python">import torch
import matplotlib.pyplot as plt
from torchinfo import summary

actuator_net_file = "resources/actuator_nets/anydrive_v3_lstm.pt"
actuator_network = torch.jit.load(actuator_net_file)
actuator_network.eval()

num_envs = 1
num_actions = 1
sea_input = torch.zeros(num_envs*num_actions, 1, 2, requires_grad=False)
sea_hidden_state = torch.zeros(2, num_envs*num_actions, 8, requires_grad=False)
sea_cell_state = torch.zeros(2, num_envs*num_actions, 8, requires_grad=False)

hc0 = (sea_hidden_state, sea_cell_state)
torques, (sea_hidden_state[:], sea_cell_state[:]) = actuator_network(sea_input, hc0)
</code></pre>
<p>I’m looking for the equivalence of <code>torques, (sea_hidden_state[:], sea_cell_state[:]) = actuator_network(sea_input, hc0) </code> in C++. My code is as following:</p>
<pre><code class="lang-cpp">#include &lt;torch/script.h&gt; // One-stop header.
#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;vector&gt;

int main(int argc, const char* argv[]) {
  std::string actuator_net_file = "/home/fenglongsong/Desktop/example-app/sea_lstm_jit3.pt";
  torch::jit::script::Module actuator_network;
  try {
    actuator_network = torch::jit::load(actuator_net_file);
    actuator_network.eval();
  }
  catch (const c10::Error&amp; e) {
    std::cerr &lt;&lt; "error loading the model\n";
    return -1;
  }

  std::cout &lt;&lt; "load model ok\n";

  const int num_envs = 1;
  const int num_actions = 1;
  auto u0 = torch::zeros({num_envs*num_actions, 1, 2});
  auto h0 = torch::zeros({2, num_envs*num_actions, 8});
  auto c0 = torch::zeros({2, num_envs*num_actions, 8});

  std::vector&lt;torch::jit::IValue&gt; inputs;
  inputs.push_back(u0);
  std::vector&lt;torch::jit::IValue&gt; hc;
  hc.push_back(h0);
  hc.push_back(c0);
  inputs.push_back(c10::ivalue::Tuple::create(hc));

  actuator_network(inputs).toTensor();
}
</code></pre>
<p>Compiling is no problem, but when running the executable I got the following error:</p>
<pre><code class="lang-auto">fenglongsong@alvaro-rsl ~/Desktop/example-app/build $ ./example-app .
load model ok
terminate called after throwing an instance of 'c10::Error'
  what():  Expected Tensor but got Tuple
Exception raised from reportToTensorTypeError at ../aten/src/ATen/core/ivalue.cpp:908 (most recent call first):
frame #0: c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;) + 0x6b (0x7f658d1817ab in /home/fenglongsong/Documents/ocs2_ws/src/libtorch/lib/libc10.so)
frame #1: c10::detail::torchCheckFail(char const*, char const*, unsigned int, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) + 0xce (0x7f658d17d15e in /home/fenglongsong/Documents/ocs2_ws/src/libtorch/lib/libc10.so)
frame #2: c10::IValue::reportToTensorTypeError() const + 0x64 (0x7f657712e304 in /home/fenglongsong/Documents/ocs2_ws/src/libtorch/lib/libtorch_cpu.so)
frame #3: c10::IValue::toTensor() &amp;&amp; + 0x4b (0x55d0c7d7701d in ./example-app)
frame #4: main + 0x452 (0x55d0c7d73f50 in ./example-app)
frame #5: __libc_start_main + 0xf3 (0x7f6575b87083 in /lib/x86_64-linux-gnu/libc.so.6)
frame #6: _start + 0x2e (0x55d0c7d737ce in ./example-app)

Aborted (core dumped)
</code></pre>
<p>Although the error message says “Expected Tensor but got Tuple”, but from the python script it’s clear the inputs should be “Tensor, Tuple[Tensor, Tensor]”. I wonder how to fix this. Any suggestion will be much appreciated!</p>

Andrew_Edmondson: <p>When you say inputs I don’t understand, you mean the values returned by the network? So your model is returning the tuple <code>( torques, (sea_hidden_state[:], sea_cell_state[:]))</code> ? C++ can’t directly return multiple values in the same way as python, it will return a tuple that you need to unpack with a structured binding (assuming you are using C++17).<br>
<a href="https://en.cppreference.com/w/cpp/utility/tuple" class="onebox" target="_blank" rel="noopener nofollow ugc">https://en.cppreference.com/w/cpp/utility/tuple</a></p>