Eigen中如何用Map类型将非连续行浅拷贝至emb_look_up?
问题解答:Eigen中实现非连续行的零拷贝(浅引用)
直接使用Eigen::Map无法实现非连续行的浅拷贝,因为Map要求映射的内存区域是连续的,而row_idx指定的非连续行在global_matrix中的内存地址是分散的,无法通过单个Map对象统一映射。
替代方案:使用Eigen的IndexedView(零拷贝视图)
从Eigen 3.4版本开始,引入了IndexedView特性,可以直接创建原矩阵非连续行/列的视图,完全不需要拷贝数据(相当于“浅引用”),同时支持后续的矩阵运算。
修改后的代码如下:
#include <Eigen/Dense> #include <vector> void func(Eigen::MatrixXf& global_matrix, Eigen::MatrixXf* hidden_vec, std::vector<int>& row_idx) { // 创建非连续行的视图,仅引用原矩阵数据,无拷贝 auto emb_look_up = global_matrix(row_idx, Eigen::all); // 直接使用视图完成矩阵乘法,noalias()避免不必要的临时矩阵 hidden_vec->noalias() = Eigen::Matrix<float, 1, 32>::Ones() * emb_look_up; }
关键说明
global_matrix(row_idx, Eigen::all)会生成一个IndexedView对象,它只是对原矩阵中指定行的引用,不会分配新内存或拷贝数据,完全符合“浅拷贝”的需求。- 后续的矩阵乘法可以直接使用这个视图,Eigen的表达式模板会自动优化计算流程,效率比先深拷贝再运算更高。
- 如果使用的是Eigen 3.4之前的版本,建议升级到最新版本来使用
IndexedView;若无法升级,可以考虑将row_idx转换为Eigen::VectorXi,并通过循环结合Eigen::Ref来逐个引用行,但这种方式在矩阵运算时无法直接作为整体参与,灵活性和效率不如IndexedView。
内容的提问来源于stack exchange,提问作者chabg qiu
相关产品推荐
相关产品推荐

