Convert a tensor with type caffe2::TypeMeta to std::vector

I have an tensor with type caffe2::TypeMeta, and I need to get its value as a regular std::vector object. I know how to convert a Torch::Tensor object with a regular type to a std::vector object, but the same procedure does not work for tensors with type caffe2::TypeMeta. I found an expensive way to do that, it needs to iterate over every single parameter on the caffe2:TypeMeta object which can be very expensive.

I faced these tensors with type caffe2:TypeMeta in the state of the optimizer, where I need to get the state value of different optimizer and modify them based on a given algorithm.

Below is the piece of the code which gets the tensors of caffe2:TypeMeta.
I appreciate any comment on this.


void get_state(torch::optim::Optimizer *optimizer){
    for (auto& group : optimizer->param_groups()) {
        for (auto &p : group.params()) {
            if (!p.grad().defined()) {
                continue;
            }

            auto grad = p.grad();
            TORCH_CHECK(!grad.is_sparse(),
                        "Adam does not support sparse gradients"/*, please consider SparseAdam instead*/);
            ska::flat_hash_map<std::string, std::unique_ptr<torch::optim::OptimizerParamState>>& state_ = optimizer->state();
            auto param_state = state_.find(c10::guts::to_string(p.unsafeGetTensorImpl()));

            auto& state = static_cast<torch::optim::AdamParamState&>(*state_[c10::guts::to_string(p.unsafeGetTensorImpl())]);
            auto& exp_avg = state.exp_avg();
            auto& exp_avg_sq = state.exp_avg_sq();
            auto& max_exp_avg_sq = state.max_exp_avg_sq();
            auto step_counter = state.step();

            // This works, but can be very expensive since I need to iterate over all the element for each of the tensors in the optimizer state
            if (exp_avg.dim() > 1) {
                auto tmp_v2 = exp_avg[10][3].item().toDouble();
                std::cout << tmp_v2 << std::endl;
                tmp_v2 = exp_avg_sq[10][3].item().toDouble();
                std::cout << tmp_v2 << std::endl;
            }
                else
            {
                auto tmp_v2 = exp_avg[10].item().toDouble();
                std::cout << tmp_v2 << std::endl;
                tmp_v2 = exp_avg_sq[10].item().toDouble();
                std::cout << tmp_v2 << std::endl;
            }
            state.exp_avg(torch::ones_like(exp_avg));

            if (exp_avg.dim() > 1) {
                auto tmp_v2 = exp_avg[10][3].item().toDouble();
                std::cout << tmp_v2 << std::endl;
                tmp_v2 = exp_avg_sq[10][3].item().toDouble();
                std::cout << tmp_v2 << std::endl;
            }
            else
            {
                auto tmp_v2 = exp_avg[10].item().toDouble();
                std::cout << tmp_v2 << std::endl;
                tmp_v2 = exp_avg_sq[10].item().toDouble();
                std::cout << tmp_v2 << std::endl;
            }

           // This does not work, it returns a memory segmentation fault error at the second line:
                auto g = torch::reshape(exp_avg, {-1,}).to(at::kDouble);
                auto v = std::vector<double>(g.data_ptr<double>(), g.data_ptr<double>() + g.numel());

        }
    }

}