我试图在c++中创建一个Eigen::Tensor
对象的 Package 器。其想法是基于提供的数组在Tensor上创建一个chipped视图,该视图指定要chip的行沿着或-1
表示跳过此维度的chipping操作:
Eigen::Tensor<double, 3> tensor(4, 3, 2);
std::vector<int> indices = {3, -1, 1};
字符串
想要的结果就像
auto view = tensor.chip(1, 2).chip(3, 0)
型
获取最后一个维度中的第一行和第一个维度中的第三行。(参见Eigen::Tensor文档中的documentation of chip)
我最初的方法是简单地使用一个循环:
template<typename T, int N>
auto createChippedAndSlicedView(Eigen::Tensor<T, N>& tensor, const Indices<N>& indices) {
auto view = tensor;
for (int i = N - 1; i >= 0; --i) {
if (indices.chip_indices[i] != -1) {
view = view.chip(indices.chip_indices[i], i);
}
}
return view;
}
型
但这并不起作用,因为我们在每次迭代中都要改变我们试图分配给view
的维度,然后我试图递归地实现它:
#include <Eigen/Dense>
#include <unsupported/Eigen/CXX11/Tensor>
#include <iostream>
#include <vector>
template<typename TensorType>
auto chipTensorRecursive(TensorType &tensor, const std::vector<int> &indices, size_t dim) {
if (dim >= indices.size()) {
return tensor;
}
if (indices[dim] == -1) {
return chipTensorRecursive(tensor, indices, dim + 1);
} else {
auto chippedTensor = tensor.chip(indices[dim], dim);
return chipTensorRecursive(chippedTensor, indices, dim + 1);
}
}
template<typename TensorType>
auto chipTensor(TensorType &tensor, const std::vector<int> &indices) {
return chipTensorRecursive(tensor, indices, 0);
}
int main() {
Eigen::Tensor<double, 3> tensor(4, 3, 2);
std::vector<int> indices = {1, -1, 1};
tensor.setValues({{{ 0, 1}, { 2, 3}, { 4, 5}},
{{ 6, 7}, { 8, 9}, {10, 11}},
{{12, 13}, {14, 15}, {16, 17}},
{{18, 19}, {20, 21}, {22, 23}}});
auto result = chipTensor(tensor, indices);
std::cout << "Result: " << result << std::endl;
return 0;
}
型
但这会产生内部特征误差
In file included from /usr/include/eigen3/unsupported/Eigen/CXX11/Tensor:72,
from test.cpp:2:
/usr/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h: In instantiation of ‘struct Eigen::internal::Initializer<Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::Tensor<double, 3> > > > >, -893>’:
/usr/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h:29:53: recursively required from ‘struct Eigen::internal::Initializer<Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::Tensor<double, 3> > > > >, -2>’
/usr/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h:29:53: required from ‘struct Eigen::internal::Initializer<Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::Tensor<double, 3> > > > >, -1>’
/usr/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h:1006:34: required from ‘class Eigen::TensorBase<Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::Tensor<double, 3> > > > >, 1>’
/usr/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h:80:7: required from ‘class Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::TensorChippingOp<-1, Eigen::Tensor<double, 3> > > > >’
test.cpp:19:35: recursively required from ‘auto chipTensorRecursive(TensorType&, const std::vector<int>&, size_t) [with TensorType = Eigen::TensorChippingOp<-1, Eigen::Tensor<double, 3> >]’
test.cpp:19:35: required from ‘auto chipTensorRecursive(TensorType&, const std::vector<int>&, size_t) [with TensorType = Eigen::Tensor<double, 3>]’
test.cpp:25:31: required from ‘auto chipTensor(TensorType&, const std::vector<int>&) [with TensorType = Eigen::Tensor<double, 3>]’
test.cpp:42:29: required from here
/usr/include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h:29:53: fatal error: template instantiation depth exceeds maximum of 900 (use ‘-ftemplate-depth=’ to increase the maximum)
29 | typename Initializer<Derived, N - 1>::InitList> InitList;
| ^~~~~~~~
compilation terminated.
型
说明它已经达到了可以创建的模板的最大限制。根据我的理解,编译器应该尝试为每个维度创建一个chipTensorRecursive
模板方法的示例,直到最大指定的维度,在这个例子中是三个。为什么会有这么多的示例被创建?这会被认为是解决上述问题的干净方法吗?The code can be run in the compiler explorer here
1条答案
按热度按时间wkyowqbh1#
问题的出现是因为在这个实现中N没有可靠地递减,这导致编译器创建了我们的recursiveChip函数的无限多个示例。减少输入数组,使其只包含要chip的维度,解决了这个问题:
字符串