用于各种 b 的稀疏带状 Ax=b 的批量 CUDA 解决方案
batch CUDA solution of sparse banded Ax=b for various b's
我有一个稀疏带状矩阵 A,我想(直接)求解 Ax=b。我有大约 500 个向量 b,所以我想求解相应的 500 个 x。
我是 CUDA 的新手,所以我对可用的选项有点困惑。
cuSOLVER 有一个批量直接求解器 cuSolverSP,用于使用 QR here 的稀疏 A_i x_i = b_i。 (我对 LU 也很好,因为 A 的条件很好。)但是,据我所知,我无法利用我所有的 A_i 都相同的事实。
是否可以选择先在 CPU 或 GPU 上确定稀疏 LU (QR) 分解,然后在 GPU 上并行执行反向代换(分别为反向代换和矩阵乘法)?如果 cusolverSp< t >csrlsvlu() 用于一个 b_i,是否有标准方法可以为多个 b_i 批量执行此操作?
最后,由于我对此没有直觉,考虑到必要的开销,我是否应该期望这些选项中的任何一个在 GPU 上加速? x 的长度约为 10000-100000。谢谢
我目前正在做类似的事情。我决定基本上将 CUDA SDK 附带的共轭梯度和 0 级不完全 cholesky 预条件共轭梯度求解器实用程序示例包装到一个小的 class.
您可以在路径下的 CUDA_HOME 目录中找到它们:
samples/7_CUDALibraries/conjugateGradient
和 /Developer/NVIDIA/CUDA-samples/7_CUDALibraries/conjugateGradientPrecond
基本上,您会将矩阵加载到设备内存中一次(对于 ICCG,计算相应的调节器/矩阵分析),然后使用不同的 b 向量调用求解内核。
我不知道你期望你的矩阵能带结构是什么样的,但如果它是对称的并且是对角线主导的(沿着每行和每列的非对角线带与对角线符号相反并且它们的总和小于对角线条目)或正定(没有特征值为 0 的特征向量。)那么 CG 和 ICCG 应该是有用的。或者,如果您愿意对它们进行编码,则各种多重网格算法是另一种选择。
如果您的矩阵只是半正定矩阵(例如,至少有一个特征值为零的特征向量),您仍然可以使用 CG 或 ICCG,只要您确保:
1) 右侧(b 向量)正交于 null space(null space 表示特征值为零的特征向量)。
2) 您获得的解决方案与 null space.
正交
有趣的是,如果您确实有一个非平凡的空值 space,那么不同的数值求解器可以为相同的精确系统提供不同的答案。解决方案最终会因 null space 的线性组合而有所不同......在我最终抓住之前,这个问题已经导致我进行了很多工时的调试和挫折,所以意识到它是件好事。
最后,如果您的矩阵具有 Circulant Band structure,您可以考虑使用基于快速傅立叶变换 (FFT) 的求解器。基于 FFT 的数值求解器通常可以在适用的情况下产生卓越的性能。
如果您不介意使用开源库,您还可以查看 CUSP:
CUSP Quick Start Page
它有一套相当不错的求解器,包括一些预处理方法:
CUSP Preconditioner Examples
只要您的 GPU 有足够的板载内存,平滑聚合预调节器(代数多重网格的一种变体)似乎工作得很好。
is there a standard way to batch perform this operation for multiple b_i's?
一种选择是使用CUDA的cuSOLVER中的批量重构模块,但我不确定它是否标准。
cuSOLVER 中的批量重构模块提供了一种基于 LU 分解求解具有固定左侧稀疏矩阵(或具有固定稀疏模式但系数可变的矩阵)和可变右侧的批量线性系统的有效方法.在与其相关的官方文档(自 CUDA 10.1 起)中只能找到一些部分完成的代码片段。可以找到完整的示例 here.
我有一个稀疏带状矩阵 A,我想(直接)求解 Ax=b。我有大约 500 个向量 b,所以我想求解相应的 500 个 x。 我是 CUDA 的新手,所以我对可用的选项有点困惑。
cuSOLVER 有一个批量直接求解器 cuSolverSP,用于使用 QR here 的稀疏 A_i x_i = b_i。 (我对 LU 也很好,因为 A 的条件很好。)但是,据我所知,我无法利用我所有的 A_i 都相同的事实。
是否可以选择先在 CPU 或 GPU 上确定稀疏 LU (QR) 分解,然后在 GPU 上并行执行反向代换(分别为反向代换和矩阵乘法)?如果 cusolverSp< t >csrlsvlu() 用于一个 b_i,是否有标准方法可以为多个 b_i 批量执行此操作?
最后,由于我对此没有直觉,考虑到必要的开销,我是否应该期望这些选项中的任何一个在 GPU 上加速? x 的长度约为 10000-100000。谢谢
我目前正在做类似的事情。我决定基本上将 CUDA SDK 附带的共轭梯度和 0 级不完全 cholesky 预条件共轭梯度求解器实用程序示例包装到一个小的 class.
您可以在路径下的 CUDA_HOME 目录中找到它们:
samples/7_CUDALibraries/conjugateGradient
和 /Developer/NVIDIA/CUDA-samples/7_CUDALibraries/conjugateGradientPrecond
基本上,您会将矩阵加载到设备内存中一次(对于 ICCG,计算相应的调节器/矩阵分析),然后使用不同的 b 向量调用求解内核。
我不知道你期望你的矩阵能带结构是什么样的,但如果它是对称的并且是对角线主导的(沿着每行和每列的非对角线带与对角线符号相反并且它们的总和小于对角线条目)或正定(没有特征值为 0 的特征向量。)那么 CG 和 ICCG 应该是有用的。或者,如果您愿意对它们进行编码,则各种多重网格算法是另一种选择。
如果您的矩阵只是半正定矩阵(例如,至少有一个特征值为零的特征向量),您仍然可以使用 CG 或 ICCG,只要您确保: 1) 右侧(b 向量)正交于 null space(null space 表示特征值为零的特征向量)。 2) 您获得的解决方案与 null space.
正交有趣的是,如果您确实有一个非平凡的空值 space,那么不同的数值求解器可以为相同的精确系统提供不同的答案。解决方案最终会因 null space 的线性组合而有所不同......在我最终抓住之前,这个问题已经导致我进行了很多工时的调试和挫折,所以意识到它是件好事。
最后,如果您的矩阵具有 Circulant Band structure,您可以考虑使用基于快速傅立叶变换 (FFT) 的求解器。基于 FFT 的数值求解器通常可以在适用的情况下产生卓越的性能。
如果您不介意使用开源库,您还可以查看 CUSP: CUSP Quick Start Page
它有一套相当不错的求解器,包括一些预处理方法: CUSP Preconditioner Examples
只要您的 GPU 有足够的板载内存,平滑聚合预调节器(代数多重网格的一种变体)似乎工作得很好。
is there a standard way to batch perform this operation for multiple b_i's?
一种选择是使用CUDA的cuSOLVER中的批量重构模块,但我不确定它是否标准。
cuSOLVER 中的批量重构模块提供了一种基于 LU 分解求解具有固定左侧稀疏矩阵(或具有固定稀疏模式但系数可变的矩阵)和可变右侧的批量线性系统的有效方法.在与其相关的官方文档(自 CUDA 10.1 起)中只能找到一些部分完成的代码片段。可以找到完整的示例 here.