Как эффективно (без зацикливания) получать данные из тензора, предсказанного torchscript в C ?

#c #neural-network #pytorch #tensor #torchscript

Вопрос:

Я вызываю torchscript (нейронную сеть, сериализованную из Python) из программы на C :

   // define inputs
  int batch = 3; // batch size
  int n_inp = 2; // number of inputs
  double I[batch][n_inp] = {{1.0, 1.0}, {2.0, 3.0}, {4.0, 5.0}}; // some random input
  std::cout << "inputs" "n";  // print inputs
  for (int i = 0; i < batch;   i)
  {    
    std::cout << "n";
    for (int j = 0; j < n_inp;   j)
    {
      std::cout << I[i][j] << "n";
    }
  }
  
  // prepare inputs for feeding to neural network
  std::vector<torch::jit::IValue> inputs;
  inputs.push_back(torch::from_blob(I, {batch, n_inp}, at::kDouble));

  // deserialize and load scriptmodule
  torch::jit::script::Module module;
  module = torch::jit::load("Net-0.pt");

  // do forward pass
  auto outputs = module.forward(inputs).toTensor();

 

Обычно для получения данных с выходных данных выполняется следующая (по элементам) операция:

   // get data from outputs
  std::cout << "outputs" << "n";
  int n_out = 1;
  double outputs_data[batch][n_out];
  for (int i = 0; i < batch; i  ) 
  {
    for (int j = 0; j < n_out; j  )
    {
      outputs_data[i][j] = outputs[i][j].item<double>();
      std::cout << outputs_data[i][j] << "n";
    }
  }

 

Однако использование такого цикла .item крайне неэффективно (в реальном коде у меня будут миллионы точек, предсказанных на каждом временном шаге). Я хочу получать данные outputs напрямую (без зацикливания на элементах). Я пытался:

   int n_out = 1;
  double outputs_data[batch][n_out];
  outputs_data = outputs.data_ptr<double>();
 

Однако это приводит к ошибке:

 error: incompatible types in assignment of ‘double*’ to ‘double [batch][n_out]’
   outputs_data = outputs.data_ptr<double>();
                                           ^
 

Обратите внимание, что этот тип outputs_data фиксирован double и не может быть изменен.

Ответ №1:

Необходимо сделать глубокую копию следующим образом:

 double outputs_data[batch];
std::memcpy(outputs_data, outputs.data_ptr<dfloat>(), sizeof(double)*batch);