使用CUBLAS进行多个矩阵向量调用

时间:2013-09-13 09:58:32

标签: c++ cuda cublas

我目前必须执行128个独立的顺序矩阵向量CUBLAS操作。所有矩阵和向量都不同。每个独立矩阵紧接在存储器中存储在下一个矩阵中,并且矢量同样连续地存储在存储器中(全部以行 - 主要形式)。

更多背景信息: 矩阵为(2048 X 8),向量为长度2048.输出均为独立。因为我有超级矩阵,所以我有以下内容:

matrix[(2048*128)x8]
vector[(2048*128)x1]
output[(8*128)x1]

使用 cublasSgemv 我首先在每个迷你矩阵上进行转置,然后将结果添加(而不是替换)到内存中:

cublasSgemv(*handle, CUBLAS_OP_T, Bdim, Adim, scale1, d_matrix + offset1, Bdim, d_vector + offset2, 1, scale2, out + offset3, 1);

我正在进行128次此类通话,我想在一次中进行此操作。

分析器显示这些多次调用会显着降低性能。进行多个矩阵向量运算的最佳方法是什么?有没有办法将它们组合成一个快速呼叫?

流是最好的方式还是有某种方法来调用相关的偏移量(索引到我的矩阵和向量数组)?唯一的其他有效选择似乎是使用CUSPASE调用并将所有矩阵粘在对角线上。

注意:我对于在这个特定问题中获取gemv调用中的转置或行/列主要排序是不正确的。

2 个答案:

答案 0 :(得分:1)

更新

事实上,如果你想在这种情况下加速你的代码,你必须特别注意r / c主要订购。

如修订后的问题所示,您使用行主矩阵。那么你有一个超矩阵A [(2048 * 128)x8]和一个超向量V [(2048 * 128)x1]。在这里我假设你想要一个col-major矩阵输出[8x128](可以看作是一个超向量[(8 * 128)x1]),其中每个col是转置的结果(miniA [2048x8])* miniV [2048x1]。

另一方面,CUBLAS假设矩阵存储在column-major中。因此,可能需要一些额外的矩阵转置例程来改变排序。

由于您需要128个独立的[8x1]结果,因此它应该能够在 4 cuda API调用中计算结果,这应该比原来的 128 更有效调用

1. Row-major A[(2048*128)x8] can be seen as colum-major AA[8x(2048*128)]
   B[8x(2048*128)] = AA[8x(2048*128)] * diag( V[[(2048*128)x1]] )  by 1 dgmm()

2. C[(2048*128)x8] = transpose( B[8x(2048*128)] )                  by 1 geam()

3. Col-major C[(2048*128)x8] can be seen as col-major CC[2048x(8*128)]
   O[1x(8*128)] = ones[1x2048] * CC[2048x(8*128)]                  by 1 gemv()

4. Row vector O[1x(8*128)] can be seen as col-major matrix OO[128x8]
   output[8x128] = transpose( OO[128x8] )                          by 1 geam()

这个主要输出[8x128]就是你想要的。

由于您需要adding而不是replacing,因此您可能需要再拨一次电话才能将原始值添加到output

答案 1 :(得分:1)

我已经快速启动了batchCUBLAS SDK示例。我已针对大小为1282048x8的矩阵考虑了8x1次独立运行。以下是NVIDIA GeForce GT 540M(计算能力2.1)和Kepler K20c(计算能力3.5)的结果。

对于NVIDIA GeForce GT 540M案例,针对“非流式”cuBLAS执行的“流式”和“批量”版本没有相关改进。

对于NVIDIA Kepler K20c,我已经获得了

sgemm 1.87 GFlops(非流媒体); 3.08 GFlops(流媒体); 6.58 GFlops(批量);

dgemm 1.00 GFlops(非流媒体); 1.43 GFlops(流媒体); 6.67 GFlops(批量);

流媒体和批处理案例似乎相关地改善了单流精度的非流式情况。

<强>免责声明

  1. 我不像你那样考虑换位;
  2. SDK示例考虑矩阵 - 矩阵乘法,而您需要矩阵向量乘法;可以为gemv进行流式传输,但不能进行批处理。
  3. 我希望这些部分结果可以为您提供一些有用的信息。