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’])
output_tuple = NT(x * 2, x / 2)
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'])
output_tuple = MyTuple(x * 2, x / 2)
traced = torch.jit.trace(f, (torch.ones(2, 2)))
x: Tensor) -> Tuple[Tensor, Tensor]:
_0 = (torch.mul(x, CONSTANTS.c0), torch.div(x, CONSTANTS.c0))
In C++ you can access the tuple like this
torch::IValue output = my_module->forward(...);
std::vector<torch::IValue>& tuple_elements = output->toTuple().elements();
Thanks @driazati , this almost got me there! I got compilation errors when I used your snippet and had to change it to either:
- make the
lvalue reference constant:
const std::vector<torch::IValue> & tuple_elements = ...
- 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
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