I have a vector of tuples that I need to convert into a torch::Tensor. What I have come up with so far, is the vanilla approach which is as follows :
std::vector<torch::Tensor> anchors;
std::vector<std::tuple<float, float, float, float>> anchors_raw;
//...
for (auto& rows: anchors_raw)
{
auto& [cx, cy, s_kx, s_ky] = rows;
anchors.emplace_back(std::move(torch::stack({ std::move(torch::tensor(cx)),
std::move(torch::tensor(cy)),
std::move(torch::tensor(s_kx)),
std::move(torch::tensor(s_ky))
}, 0)));
}
outo output = std::move(torch::stack(std::move(anchor)).view({ -1,4 }));
//...
I'm using Torch 1.7. Is there any other possibly more efficient way of doing this?
I am not aware of any libtorch feature to do that easily. I would have suggested to use torch::from_blob, hoping for the data to be stored contiguously, but I have found this thread that says otherwise.
So if possible, my suggestion would be to replace your tuple<float, float...>by std::array<float, 4> (for which memory layout is contiguous), and do something like
std::vector<std::array<float,4>> anchors_raw;
// ...
auto options = torch::TensorOptions().dtype(at::kFloat);
auto anchors = torch::from_blob(&anchors_raw[0][0], {anchors_raw.size(), 4}, options).clone()
I cannot try it at the moment so I hope it compiles and run fine, but I believe it should work, all float values should be stored contiguously in the vector and the arrays, so from_blobwill work.
As always, the call to clone is required if anchors_raw is at risk of going out of scope before you're done with anchors. If you're sure anchors_raw will outlive anchors, you can remove the call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With