我正在执行压缩的稀疏原始矩阵矢量乘法(CSR SPMV):这涉及将数组A分成多个chunks,然后通过引用将该块传递给一个函数,但是仅传递函数的第一部分数组(A [0]从数组开头开始的第一个块)被修改。但是,从第二个循环A [0 + chunkIndex]开始,当函数读取子数组时,尽管索引正确,但它会跳转并读取超出总数组地址范围的其他地址。
供参考:
SPMV 内核是:
void serial_matvec(size_t TS, double *A, int *JA, int *IA, double *X, double *Y)
{
double sum;
for (int i = 0; i < TS; ++i)
{
sum = 0.0;
for (int j = IA[i]; j < IA[i + 1]; ++j)
{
sum += A[j] * X[JA[j]]; // the error is here , the function reads diffrent
// address of A, and JA, so the access
// will be out-of-bound
}
Y[i] = sum;
}
}
并且这样称呼:
int chunkIndex = 0;
for(size_t k = 0; k < rows/TS; ++k)
{
chunkIndex = IA[k * TS];
serial_matvec(TS, &A[chunkIndex], &JA[chunkIndex], &IA[k*TS], &X[0], &Y[k*TS]);
}
假设我处理((8x8)矩阵,并且我处理每个块2行,所以循环k将是r ows / TS = 4个循环,< [chunkIndex和传递给该函数的数组将如下所示:
chunkIndex:0->循环k = 0,&A [0],&JA [0]chunkIndex:->循环k = 2,&A [32],&JA [32]chunkIndex:->循环k = 1,&A [16],&JA [16]
// [错误,函数读取了不同的地址]
// [错误,函数读取了不同的地址]
chunkIndex:->循环k = 3,&A [48],&JA [48]// [错误,函数读取了不同的地址]
当我运行代码时,只有第一个块正确执行,其他三个块内存被破坏,并且数组指针跳入超出数组大小的边界。我已经手动检查了所有参数的所有索引,它们都是正确的,但是当我打印地址时,它们是不同的。 (现在将其调试3天)
我使用了valgrind
,并报告:
和在sum + = A [j] * X [JA [j]];行]中使用[[大小8的未初始化值的使用]]我用大小8的无效读取
-g -fsanitize=address
编译并得到我试图在函数外部手动访问这些块,它们是正确的,那么是什么会导致像这样破坏堆内存?堆缓冲区溢出
代码是here,这是我所能做的最低要求。
我正在执行压缩的稀疏原始矩阵向量乘法(CSR SPMV):这涉及将数组A划分为多个块,然后将该块通过引用传递给函数,但是仅...
chunk
)