我有一个稀疏的带状矩阵A,我想(直接)解决Ax = b。我有大约500个向量b,所以我想解决相应的500 x。 我是CUDA的新手,所以我对我有哪些选择感到困惑。
cuSOLVER使用QR here为稀疏A_i x_i = b_i提供批量直接求解器cuSolverSP。 (因为A条件很好,所以我对LU也没问题。)但是,据我所知,我无法利用所有A_i都相同的事实。
另一种选择是首先确定CPU或GPU上的稀疏LU(QR)因子分解,然后并行执行GPU上的后转换(分别为backsub和matrix mult)吗?如果cusolverSp< t >csrlsvlu()用于一个b_i,是否有一种标准方法可以为多个b_i批量执行此操作?
最后,由于我对此没有直觉,考虑到必要的开销,我是否应该期望在这些选项中的GPU加速? x的长度约为10000-100000。感谢。
答案 0 :(得分:1)
我目前正在做类似的事情。我决定基本上将CUDA SDK附带的共轭梯度和0级不完全cholesky预条件共轭梯度求解器实用样本包装成一个小类。
您可以在路径下的CUDA_HOME目录中找到它们:
(rdd1
.cartesian( rdd2 )
.filter( lambda (k, v): k[0]==v[0] )
.map( lambda (k, v): (k[0], (k[1], v[1])) ))
和samples/7_CUDALibraries/conjugateGradient
基本上,您可以将矩阵加载到设备存储器中一次(对于ICCG,计算相应的调节器/矩阵分析),然后使用不同的b向量调用求解内核。
我不知道你期望你的矩阵带结构看起来像什么,但是如果它是对称的并且是对角占优的(沿着每行和每列的对角线带是对角线的符号并且它们的总和小于对角线条目)或正定(没有特征值为0的特征向量),那么CG和ICCG应该是有用的。或者,如果您愿意对它们进行编码,那么各种多重网格算法是另一种选择。
如果你的矩阵只是正半正定(例如,至少有一个特征值为零的特征向量),你仍然可以使用CG或ICCG逃脱,只要你确保: 1)右侧(b向量)与零空间正交(零空间意味着特征值为零的特征向量)。 2)您获得的解决方案与零空间正交。
有趣的是,如果你确实有一个非平凡的零空间,那么不同的数字解算器可以为同一个确切的系统提供不同的答案。解决方案最终会因零空间的线性组合而有所不同......这个问题在我最终陷入困境之前导致了许多工时的调试和挫折,所以很高兴能够意识到这一点。
最后,如果您的矩阵有Circulant Band structure,您可以考虑使用基于快速傅里叶变换(FFT)的求解器。基于FFT的数值求解器通常可以在适用的情况下产生优异的性能。
答案 1 :(得分:1)
是否有一种标准的方法来批量执行多个b_i的操作?
一种选择是在CUDA的cuSOLVER中使用批处理重构模块,但是我不确定它是否为标准。
cuSOLVER中的分批重构模块提供了一种有效的方法,用于基于LU分解来求解具有固定的左侧稀疏矩阵(或具有固定稀疏模式但系数变化的矩阵)和右侧的可变线性系统的批次。在官方文档(自CUDA 10.1起)中只能找到与之相关的部分完成的代码片段。可以找到完整的示例here。
答案 2 :(得分:0)
如果您不介意使用开源库,还可以查看CUSP: CUSP Quick Start Page
它有一套相当不错的求解器,包括一些预处理方法: CUSP Preconditioner Examples
平滑聚合预处理器(代数多重网格的一种变体)似乎只要你的GPU有足够的板载内存就可以正常工作。