Search code examples
c++torchlibtorch

What is the most efficient way of converting a std::vector<std::tuple<>> to a torch::Tensor?


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?


Solution

  • 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.