【发布时间】:2018-11-15 10:14:51
【问题描述】:
在稀疏矩阵的特征内迭代器上应用simd:
for(auto i = 0; i < smat.outerSize(); i++){
#pragma omp simd
for(SMat::InnerIterator iter(smat,i); it; ++it){
it.valueRef() = value;
}
}
这不起作用,因为 for 循环中括号初始化的错误与 simd 不兼容。接下来我试试:
SMat::InnerIterator iter(smat,i);
#pragma omp simd
for(;it;++it){ // error, declaration or initialization expected
for(it;it;++it){ // error, declaration or initialization expected
然后我用谷歌搜索文档,只遇到一个短语提到 simd 在添加稀疏矩阵时是隐式的(所以我知道这是可能的,并且在 eigen 的模板化肠子中的某个地方,有一个 simd 循环内向量;但我不知道怎么做)。
接下来,我检查并发现Eigen 在整个代码中只有三个对omp 的调用。这是否意味着 Eigen 仅依赖于编译器标志来激活 simd?
最后,我尝试将循环更改为规范形式(根据下面的评论),并得到一个不同的错误:
for(auto it = typename SMat::InnerIterator(smat,i); it; ++it)
// error: '#pragma omp simd' used with class iteration variable 'it'
使用 simd 触发或迭代 Eigen::SparseMatrix<double> 中的内部向量的预期方式是什么?
【问题讨论】:
-
您的编译器支持什么版本的 OpenMP?无论如何,在 OpenMP 中,循环必须采用所谓的规范形式,在您的情况下应该类似于
for (auto it = Eigen::SparseMatrix<double>::InnerIterator(smat, i); it != false; ++it)。 -
Eigen 中的 SIMD 几乎完全使用编译器内在函数完成。您在哪里找到“添加稀疏矩阵时 simd 是隐式的”? (取决于您实际添加的内容,但尤其是添加两个具有不同非零模式的稀疏矩阵,这听起来很困难。
-
InnerIterator目前确实没有记录。它可以与标准的随机访问迭代器兼容(它缺少一些运算符,如it-diff、--it、it-=diff)。供参考,来源在这里:bitbucket.org/eigen/eigen/src/0fdf0e56237f92e5/Eigen/src/… -
@chtz:
InnerIterator在eigen.tuxfamily.org/dox/group__TutorialSparse.html 中被提及,但这是一个教程,并没有详细说明类型属性。 -
@DanielLangr 规范循环形式 not 允许
!=作为运算符。