CUDA / CUBLAS:访问数组中的元素

时间:2013-09-02 12:17:49

标签: c++ vector matrix cuda cublas

作为前一个问题here的后续,我试图实现以下循环,这是一个矩阵向量乘法,其中向量是矩阵Q中的一列,基于循环迭代器:

编辑:Q不能预先填充,但填充了迭代器K的进度。

for (unsigned K=0;K<N;K++){   // Number of iterations loop
    //... do some stuff
    for (unsigned i=0; i<N; i++){
        float sum = 0;
        for (unsigned j=0; j<N; j++){
            sum += A[j][i]*Q[j][K];
        }
        v[i] = sum;
    }
    //... do some stuff
    // populate next column of Q
}

阵列的尺寸为:

A [N x N]

Q [N x(0.5N + 1)]

这个数组已被展平,以便与cublasSgemv()一起使用。我的问题是,是否可以使用cublasSgemv()告诉它从哪里开始访问d_Q,以及元素的增量是什么(因为它是行主要的C ++):

编辑:使用sizeof(float)乘以memoery访问增量。到目前为止,我仍然无法正常工作。

Niter = 0.5*N + 1;
for (unsigned K=0;K<N;K++){
    cublasSgemv(handle, CUBLAS_OP_T, N, N, &alpha, d_A, N, (d_Q + sizeof(float)*K*(Niter)), (Niter), &beta, d_v , 1);
}

我认为没有可能将d_Q编入索引,因为我没有得到任何结果

解决:@RobertCrovella的解决方案正是我所寻求的。感谢。

1 个答案:

答案 0 :(得分:2)

您可以按照提议的方式索引展平的Q矩阵。您对Sgemv的致电应如下:

cublasSgemv(handle, CUBLAS_OP_T, N, N, &alpha, d_A, N, (d_Q + K), (Niter), &beta, (d_v+(K*Niter)) , 1);

指向Q的指针应该指向相关列的第一个元素,并且因为你的矩阵是行主要的,所以这只是d_Q + K(使用指针算法,而不是字节算术)。 Niter是相关列的连续元素之间的步幅(元素,而不是字节)。请注意,您编写的代码将覆盖一个矩阵向量的结果与下一个相乘,因为您没有通过d_v索引输出向量。所以我在d_v添加了一些索引。

正如@JackOLantern指出的那样,通过调用Sgemm,也可以在没有循环的情况下一步完成:

cublasSgemm(handle, CUBLAS_OP_T, CUBLAS_OP_T N, Niter,  N, &alpha, d_A, N, d_Q, (Niter), &beta, d_v, N);

如果您的代码没有达到预期的效果,请提供完整的可编辑示例。