Вернуть am Eigen :: Tensor slice из функции - PullRequest
0 голосов
/ 03 июня 2019

Я хотел бы написать функции, которые возвращают фрагменты Eigen :: Tensor. В реальном коде getSlice () принимает несколько целых чисел, и вычисляются экстент и смещение. Я хотел бы, чтобы мои функции возвращали представление в массив, чтобы я мог получить доступ к массиву для чтения и записи без копирования.

Я могу создать переменную, которая является частью моего массива, и изменить данные. Но когда я возвращаю тот же фрагмент из функции, значения не изменяются. Я предполагаю, что функция генерирует новый массив в качестве возвращаемого значения. Как мне вернуть нужный мне срез? Или я должен сделать это по-другому?

#include <iostream>
#include <Eigen/Dense>
#include <unsupported/Eigen/CXX11/Tensor>

Eigen::Tensor<float,3> getSlice(Eigen::Tensor<float,3>& a,
                Eigen::array<long,3>& offset,
                Eigen::array<long,3>& extent)
{
   return a.slice(offset,extent);
}

int main()
{
   Eigen::Tensor<float,3> et = Eigen::Tensor<float,3>(3,5,4);
   et.setConstant(1.1);
   std::cout << et << std::endl;

   Eigen::array<long,3> offset = {0,0,0};
   Eigen::array<long,3> extent = {2,2,1};

   et.slice(offset,extent).setConstant(2.2);
   std::cout << "Set slice constant" << std::endl;
   std::cout << et << std::endl;

   auto sl = et.slice(offset,extent);
   sl.setConstant(3.3);
   std::cout << "Set slice constant from slice instance." << std::endl;
   std::cout << et << std::endl;

   getSlice(et,offset,extent).setConstant(4.4);
   std::cout << "Set slice constant from function." << std::endl;
   std::cout << et << std::endl;
}

Вывод программы:

$ ./ta

1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1

Задать постоянную среза

2.2 2.2 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 2,2 2,2 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1

Установить константу среза из экземпляра среза.

3.3 3.3 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 3,3 3,3 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1

Установить константу среза из функции.

3.3 3.3 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 3,3 3,3 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1

1 Ответ

1 голос
/ 04 июня 2019

Ваше наблюдение о том, что ваша реализация getSlice возвращает новый объект Tensor (с копией исходных данных), является правильным. В вашем случае самое простое решение состоит в том, чтобы изменить тип возвращаемого значения на auto (хотя, как правило, вы должны быть осторожны с auto и Eigen):

inline auto getSlice(Eigen::Tensor<float,3>& a,
                Eigen::array<long,3>& offset,
                Eigen::array<long,3>& extent)
{
   return a.slice(offset,extent);
}

Live-демо: https://godbolt.org/z/tLWYUz

...