Namedtuple in C++ interface


I have traced and saved a model that gives as output a python namedtuple. How do I go about accessing the fields of this output in the C++ api?

For eg -
from collections import named_tuple
NT = namedtuple(‘NT’, [‘output1’, ‘output2’])
def f(x):
output_tuple = NT(x * 2, x / 2)
return output_tuple

I am able to trace and save the above function using torch.jit.trace and would like to index into this output using the keyword arguments for NT in C++.


namedtuple does not work out of the box yet (though it is on our roadmap). In your example it is de-sugared to a regular tuple. You can see what’s going on under the hood with the .code property of the traced code. For example

from collections import namedtuple
MyTuple = namedtuple('MyTuple', ['output1', 'output2'])
def f(x):
    output_tuple = MyTuple(x * 2, x / 2)
    return output_tuple
traced = torch.jit.trace(f, (torch.ones(2, 2)))


def forward(self,
    x: Tensor) -> Tuple[Tensor, Tensor]:
  _0 = (torch.mul(x, CONSTANTS.c0), torch.div(x, CONSTANTS.c0))
  return _0

In C++ you can access the tuple like this

torch::IValue output = my_module->forward(...);
std::vector<torch::IValue>& tuple_elements = output->toTuple().elements();
1 Like

Thanks @driazati , this almost got me there! I got compilation errors when I used your snippet and had to change it to either:

  1. make the lvalue reference constant:
const std::vector<torch::IValue> & tuple_elements = ...
  1. or remove the reference and use a normal vector with copy construction:
std::vector<torch::IValue> tuple_elements = ...

Furthermore, the rest of the line should be changed as well:

... = output.toTuple()->elements()

output is a torch::IValue/c10::IValue, not a pointer, so pointer access does not work. However, .toTuple() returns a c10::intrusive_ptr< ...> and you can access its member functions with ->.