C++ 基于SIMD的稀疏矩阵内迭代器特征迭代

C++ 基于SIMD的稀疏矩阵内迭代器特征迭代,c++,openmp,eigen,simd,C++,Openmp,Eigen,Simd,在稀疏矩阵的特征内部迭代器上应用simd: for(auto i = 0; i < smat.outerSize(); i++){ #pragma omp simd for(SMat::InnerIterator iter(smat,i); it; ++it){ it.valueRef() = value; } } 然后我在谷歌上搜索文档,只遇到一个短语,提到在添加稀疏矩阵时simd是隐式的(因此我知道这是可能的,并且在eigen的模板内部的某个地

在稀疏矩阵的特征内部迭代器上应用simd:

for(auto i = 0; i < smat.outerSize(); i++){
    #pragma omp simd
    for(SMat::InnerIterator iter(smat,i); it; ++it){
        it.valueRef() = value;
    }
}
然后我在谷歌上搜索文档,只遇到一个短语,提到在添加稀疏矩阵时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的
特征::SparseMatrix
中,触发或迭代内部向量的预期方式是什么?

在这种情况下,不可能应用
#pragma omp simd
。根据OpenMP规范(2.6规范循环形式),“在
simd
中,构造允许的唯一随机访问迭代器类型[…]是指针类型。”。所涉及的迭代器显然不是指针类型。可以将其更改为允许OpenMP simd循环,但这需要深入了解所涉及类型的实现和数据布局。

在这种情况下不可能应用
#pragma omp simd
。根据OpenMP规范(2.6规范循环形式),“在
simd
中,构造允许的唯一随机访问迭代器类型[…]是指针类型。”。所涉及的迭代器显然不是指针类型。可以将其更改为允许OpenMP simd循环,但这需要深入了解所涉及类型的实现和数据布局。

如果要更改每个条目,并且矩阵为压缩形式,可以使用成员函数:

smat.coeffs() = value;

迭代单个列会有点困难,但您可以通过查看
smat.outerIndexPtr()[col]
(col+1的开头是
col
的结尾)找到每个列的开头。

如果您想更改每个条目,并且您的矩阵是压缩形式的,您可以使用成员函数:

smat.coeffs() = value;

在单个列上进行迭代会有点困难,但是您可以通过查看
smat.outerIndexPtr()[col]
(col+1的开头是
col
的结尾)找到每个列的开头。

您的编译器支持哪个版本的OpenMP?无论如何,在OpenMP中,循环必须是所谓的规范形式,在您的例子中,它应该类似于(auto it=Eigen::SparseMatrix::InnerIterator(smat,i);it!=false;++it)。Eigen中的SIMD几乎完全使用编译器内部函数完成。您在哪里发现“添加稀疏矩阵时simd是隐式的”?(取决于实际添加的内容,尤其是添加两个具有不同非零模式的稀疏矩阵,这听起来很困难。
InnerIterator
目前确实没有文档记录。它可以与标准随机访问迭代器兼容(它缺少一些运算符,如
it diff
--it
it-=diff
)。供参考,源代码在此处:@chtz:
InnerIterator
,但这是一个教程,没有详细说明类型属性。@DanielLangr规范循环形式不允许
!=
作为运算符。您的编译器支持什么版本的OpenMP?无论如何,在OpenMP中,循环必须是所谓的规范循环rm,在您的例子中,它应该类似于(auto it=Eigen::SparseMatrix::InnerIterator(smat,i);it!=false;++it)。Eigen中的SIMD几乎完全是使用编译器内部函数完成的。您在哪里发现“在添加稀疏矩阵时SIMD是隐式的”?(取决于实际添加的内容,尤其是添加两个具有不同非零模式的稀疏矩阵,这听起来很困难。
InnerIterator
目前确实没有文档记录。它可以与标准随机访问迭代器兼容(它缺少一些运算符,如
it diff
--it
it-=diff
)。供参考,源代码如下:@chtz:
InnerIterator
,但这是一个教程,没有详细说明类型属性。@DanielLangr规范循环形式不允许将
!=
作为运算符。如果稀疏矩阵连续打包行数据,并且有一个单独的列表,其中包含n-zero元素消失后,InnerIterator可能只是在相当于
std::vector
的循环上循环。在这种情况下,它可以被重新格式化为OpenMP兼容的循环。表示有4个紧凑数组。其中一个是
Values
,它“存储非零的系数值。”是的,根据Eigen教程,这是存储布局的一种记录行为。以及为什么
InnerIterator
可以有效实现。因此,您只需要
和值[0]
和一个长度或结束指针,您就都设置好了,就像对于
std::vector
一样,如果稀疏矩阵连续地打包它们的行数据,并且有一个非零元素的位置的单独列表,InnerIterator可能只是在
std::vector
的等价物上循环被定义为OpenMP兼容循环。表示有4个紧凑阵列。其中一个是
,它“存储非零的系数值。”是的,根据Eigen教程,这是存储布局的记录行为。以及为什么
InnerIterator
可以高效实现。因此,您所需要的就是
&Values[0]
和一个长度或结束指针,并且您都已设置好,就像
std::vector