我必须将压缩列存储中的稀疏矩阵与列向量相乘(我必须在open cl中对它进行并行化)。我在互联网上搜索了。这么多天但是找不到任何东西。(我被允许搜索互联网,因为我必须将其转换为并行)。但我只能找到压缩行存储的代码。
spmv_csr_serial(const int num_rows ,
const int * ptr ,
const int * indices ,
const float * data ,
const float * x,
float * y)
{
for(int row = 0; i < num_rows; i++){
float dot = 0;
int row_start = ptr[row];
int row_end = ptr[row+1];
for (int jj = row_start; jj < row_end; jj++)
dot += data[jj] * x[indices[jj]];
y[row] += dot;
}
}
压缩列存储没有行ptr。那么我如何将它与向量相乘?我只需要串行代码,我会自己将其转换为并行。
这是我的这个项目的OpenCL内核
enter code here
__kernel void mykernel(__global const int* val,__global const int* index,__global const int * ptr,__global const int* x,__global int* y)
{
int id=get_global_id(0);
int colstart=ptr[id];
int colend=ptr[id+1];
for(int j=colstart;j<colend;j++)
{
y[index[j]]=val[j]*x[index[j]];
}
}
此代码返回open cl kernel中的垃圾值。 这是我的序列号。
spmv_csr_serial(const int num_rows ,
const int * ptr ,
const int * indices ,
const float * data ,
const float * x,
float * y)
{
for(int row = 0; i < num_rows; i++){
float dot = 0;
int colstart = ptr[row];
int colend = ptr[row+1];
for(int j=colstart;j<colend;j++)
{
y[index[j]]=val[j]*x[index[j]];
}
}
}
密集矩阵向量乘法算法
For(int i=0;i<A.RowLength;i++)
{
For(int j=0;j<vector.length;j++)
{
Result[i]=Result[i]+A[i][j]*vector[j];
}
}
答案 0 :(得分:3)
通常,进行矩阵向量计算的算法如下
y = 0
for i = 0 : Nr - 1
for j = 0 : Nc - 1
y[i] += M[i,j] * x[j]
我们不是对所有列进行普通循环,而是遍历非零条目 只有:
y = 0
for i = 0 : Nr - 1
for j = 0 : numElementsInRow(i) - 1
y[i] += M[i, columnIndex(i,j)] * x[columnIndex(i,j)]
其中numElementsInRow(i)
返回i
行中非零的数量,columnIndex(i,j)
给出j
中的i
列索引第一行。
在您的实施中
上面,您的columnIndex(i,j)
映射由两个数组ptr
和indices
完成,即
columnIndex(i,j) == indices[ptr[i] + j]
和元素的数量由。给出
numElementsInRow(i) == ptr[i+1] - ptr[i]
。
无需为矩阵编制索引,因为您只存储压缩版本。
现在更改两个循环的顺序并循环遍历行中的非零:
y = 0
for j = 0 : Nc - 1
for i = 0 : numElementsInColumn(j) - 1
y[rowIndex(j,i)] += M[rowIndex(j,i), j] * x[j]
其余的与CRS格式相似。
答案 1 :(得分:1)
答案 2 :(得分:1)
CCS类似于CRS,只是转置。您没有行指针,但是您有一个类似的列指针。因此,您的顺序循环应该是
for(int col=0; col<num_cols; col++){
for(int j=ptr[col];j<ptr[col+1]; j++) {
y[indices[j]] += val[j]*x[col];
}
}
请记住在之前将y矢量归零。
您认为哪一个更快? CCS还是CRS?