在 RISC-V RVV 0.7.1 中屏蔽 CSR SpMV 的各个行

问题描述 投票:0回答:1

编辑:我已将我的问题重新表述为更有成效的内容,并将在下面提供答案。这个问题的旧版本仍在下面。

我正在 RVV 0.7.1 中为 CSR 格式实现优化的 SpMV 内核。在 C 语言中,SpMV 可以这样实现:

for (int i = 0; i < numRows; i++)
    for (int j = rowPtr[i]; j < rowPtr[i+1]; j++)
       y[i] += val[j] * x[colIdx[j]];

向量化最初很简单,通过加载

coldIdx
,使用它执行
x
的索引加载,加载
val
并将两者相乘。此后,必须在每一行中执行归约和 (
v{f}redsum.vs
),将其中的所有乘积相加并将它们存储在
y
的相应索引中。挑战在于从
rowPtr
创建掩码,以便只有属于给定行的元素对于每次缩减都是活动的。

我最初的想法(应该提供有关原始问题的上下文)是使用

rowPtr
中的索引将 1 放入向量寄存器的各个元素中,然后使用
viota
和元素移位来创建包含该行的寄存器每个元素属于。然而,这显然是不可行的。

如何制作所需的掩模?


老问题

我正在尝试使用 RISC-V 向量扩展(0.7.1)来创建基于索引数组的掩码寄存器。例如,采用以下索引数组

idx array
。目标是使用其中存在的索引将 1 放入相应的掩码元素中,如下面的
mask
所示:

idx array | 0 2 3 4 4 6 8
elem idx  | 0 1 2 3 4 5 6 7 8
mask      | 1 0 1 1 1 0 1 0 1

起初我错误地查看了

vrgather.vx
指令,但它并没有完全达到我想要的效果,因为它填充了所有元素。我希望代码也具有很高的性能,因此如果它可能主要由向量指令组成,那将是理想的。如果有人能指出我正确的方向,我将不胜感激。

vectorization sparse-matrix matrix-multiplication riscv
1个回答
0
投票

解决方案归功于camel-cdr!

采用以下

rowPtr
数组:

0 2 3 5 7

让我们考虑第三次迭代(

[3,5[
),它应该更具说明性。目标是达到以下掩码,启用元素 3 和 4:

00011000

第一步是使用

vid
将每个元素的索引写入向量。这样,我们就可以使用
vmseq
(如果相等则设置掩码)两次,其中
i
的元素为
i+1
rowPtr
,这将产生像这样的两个寄存器,元素
rowPtr[i]
 中有一个寄存器rowPtr[i+1]

idx | 01234567
i   | 00010000
i+1 | 00000100

之后我们可以在两者上使用

vmsbf.m
(先设置),这会设置第一个活动掩码位之前的所有位。通过对两者进行异或,我们得到最终所需的掩码:

sbf i   | 11100000
sbf i+1 | 11111000
xor     | 00011000

通过重复迭代

rowPtr
并重复此操作,可以为每个单独行的元素生成一个掩码。简而言之,我们可以将操作写为:

vmxor(vmsbf(vmseq(vid,rowPtr[i])), vmsbf(vmseq(vid,rowPtr[i+1])))

© www.soinside.com 2019 - 2024. All rights reserved.