如何让Eigen::TensorRef支持广播及其他张量操作?
Eigen 3.4中TensorRef无法包装延迟操作的问题
问题场景
使用Eigen 3.4与MSVC环境,此前成功使用Eigen::Ref,但尝试用Eigen::TensorRef包装延迟计算的张量操作(如TensorBroadcastingOp、TensorCwiseUnaryOp、TensorReductionOp)时编译失败。
示例代码:
Eigen::Tensor<double, 3> A(3, 1, 2); A.setValues({{{1, 2}}, {{3, 4}}, {{5, 6}}}); Eigen::array<int, 3> aBroadcast({1, 4, 1}); auto lazyBroadcastA = A.broadcast(aBroadcast); const Eigen::TensorRef<const Eigen::Tensor<double, 3>> ref(lazyBroadcastA);
编译错误信息:
'Dimensions': is not a member of 'Eigen::TensorBroadcastingOp<const std::array<int,3>,const Derived>' 'IsAligned': is not a member of 'Eigen::TensorBroadcastingOp<const std::array<int,3>,const Derived>' 'Layout': is not a member of 'Eigen::TensorBroadcastingOp<const std::array<int,3>,const Derived>'
原因说明
这不是操作错误,Eigen::TensorRef仅支持包装拥有连续内存布局的张量对象,比如Tensor、TensorMap这类直接持有或映射物理内存的类型。而TensorBroadcastingOp、TensorCwiseUnaryOp、TensorReductionOp属于延迟计算的表达式对象,它们并未实际存储计算结果,只是记录了计算逻辑,没有实现TensorRef要求的内存访问相关接口(如Dimensions、IsAligned、Layout),因此无法直接被TensorRef包装。
解决方法
需要先将延迟表达式的计算结果存储到实际的Tensor对象中,再用TensorRef包装该对象:
修改后的示例代码:
Eigen::Tensor<double, 3> A(3, 1, 2); A.setValues({{{1, 2}}, {{3, 4}}, {{5, 6}}}); Eigen::array<int, 3> aBroadcast({1, 4, 1}); auto lazyBroadcastA = A.broadcast(aBroadcast); // 先将延迟计算结果落地到实际Tensor Eigen::Tensor<double, 3> broadcastResult = lazyBroadcastA; // 再用TensorRef包装 const Eigen::TensorRef<const Eigen::Tensor<double, 3>> ref(broadcastResult);
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

