我希望在OpenMP线程上按列平均分割Eigen动态大小数组。
thread 0 | thread 1 | thread 2
[[0, 1, 2], [[0], | [[1], | [[2],
[3, 4, 5], becomes: [3], | [4], | [5],
[6, 7, 8]] [6]] | [7]] | [8]]
我可以使用block
方法来做到这一点,但我不确定Eigen是否会识别每个线程占用连续内存的子数组。
当我读取块类型的documentation时,有一个InnerPanel
模板参数,其中包含以下描述:
如果块映射到行major的一组行,则
InnerPanel
为真 矩阵或列主矩阵的列集(可选)。该 参数允许在编译时确定是否对齐访问 可以在块表达式上使用。
Eigen是否知道每个OpenMP线程的子阵列上的矢量化是可能的,因为每个子阵列实际上占用了连续的内存?
如果没有,如何让Eigen知道这个?
程序:
#include <Eigen/Eigen>
#include <iostream>
int main() {
// The dimensions of the matrix is not necessary 8 x 8.
// The dimension is only known at run time.
Eigen::MatrixXi x(8,8);
x.fill(0);
int n_parts = 3;
#pragma omp parallel for
for (int i = 0; i < n_parts; ++i) {
int st = i * x.cols() / n_parts;
int en = (i + 1) * x.cols() / n_parts;
x.block(0, st, x.rows(), en - st).fill(i);
}
std::cout << x << "\n";
}
结果(g++ test.cpp -I<path to eigen includes> -fopenmp -lgomp
):
0 0 1 1 1 2 2 2
0 0 1 1 1 2 2 2
0 0 1 1 1 2 2 2
0 0 1 1 1 2 2 2
0 0 1 1 1 2 2 2
0 0 1 1 1 2 2 2
0 0 1 1 1 2 2 2
0 0 1 1 1 2 2 2
答案 0 :(得分:1)
要确保块表达式确实占用连续内存,请改用middleCols
(或leftCols
或rightCols
):
#include <Eigen/Core>
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
void inspectBlock(const Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel>& block)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
int main() {
Eigen::MatrixXi x(8,8);
inspectBlock(x.block(0, 1, x.rows(), 2));
inspectBlock(x.middleCols(1, 2));
}
结果:
void inspectBlock(const Eigen::Block<ArgType, BlockRows, BlockCols, InnerPanel>&) [with XprType = Eigen::Matrix<int, -1, -1>; int BlockRows = -1; int BlockCols = -1; bool InnerPanel = false] void inspectBlock(const Eigen::Block<ArgType, BlockRows, BlockCols, InnerPanel>&) [with XprType = Eigen::Matrix<int, -1, -1>; int BlockRows = -1; int BlockCols = -1; bool InnerPanel = true]
注意:-1
是Eigen::Dynamic
的值,即在编译时不固定。
当然,如果你的矩阵是行专业,你可以改为分为topRows
,middleRows
或bottomRows
。