PETSc 的 MatMPIAIJSetPreallocation 函数中的 d_nz 和 o_nz 是什么?

计算科学 宠物
2021-12-19 22:24:15

我正在使用 PETSc 的示例代码的ex2.c工作。在第 65 行,代码指定:

MatMPIAIJSetPreallocation(A,5,PETSC_NULL,5,PETSC_NULL);  

我查阅了 MatMPIAIJSetPreallocation() 的文档,并了解它的目的是以并行压缩的稀疏行格式为矩阵分配内存。也就是说,仅为每行中预期的最大非零数分配内存。根据this documentation,第二个论点是

d_nz - 局部子矩阵的对角线部分每行的非零数

我不太确定“本地子矩阵的对角线部分”是什么意思。此外,为什么每行的对角线 (d_nz) 和非对角线 (o_nz) 部分都需要 5 个值?据我了解,正在解决的 5 点模板拉普拉斯问题有一个线性方程组,每行最多需要 5 个非零条目。此处指定的 d_nz 和 o_nz 值似乎向我表明已为每行分配了 10 个值。我确定我在解释 d_nz 和 o_nz 时遗漏了一些东西。

2个回答

分布式向量空间和矩阵存储格式

PETSc 向量分布在通信器中,每个进程拥有一个连续的行块。最常见的情况是所有部件的尺寸相同,但这不是必需的。的任何分区N进入P连续标记的部分的连续部分(有些可能是空的)是有效的。该类Mat表示两个有限维向量空间之间的线性变换,A:XY. 空间XY可能不同(甚至不同的大小),尽管 Krylov 方法和大多数线性求解器都要求X=Y. 有一些例程可以查看当前进程的所有权范围:

PETScMPI*AIJ矩阵使用的存储格式根据范围空间的所有权分配条目Y. 在这个模型中,一般有一些域的条目X影响拥有的部分Y. 准确地说,让XiX成为域空间的一部分X由进程拥有(MPI 等级)i同样对于YiY. rank 拥有的矩阵的“对角块”i正是效果XiYi. 进行乘法运算时,向量中的部分Xi在本地可用,无需任何通信。“非对角块”表示效果XXiYi, 不能在没有通信条目的情况下应用。操作yAx计算为

  1. 开始交流进程外条目xxioff.
  2. 应用矩阵的对角块yiAidiagxi.
  3. 完成进程外条目的通信。
  4. 添加非对角块的动作yiyi+Aioffxioff

在几何上,非对角线部分对应于“鬼点”对子域的影响。

预分配

由于对角线部分Aidiag分开存放Aioff,我们需要单独的预分配信息来避免动态数据结构。这可以通过提供一个参数来指示任何行中的最大非零数 ( *_nz) 或通过提供一个指示每行中非零数的数组 ( *_nnz) 来完成。请注意,对应于“内部”点的行在非对角线部分通常没有非零条目。

至于ex2.c,矩阵的每行确实不超过 5 个非零,其中至少有一个(对角线条目)必须落在对角线块中。因此,它本来可以安全通过o_nz=4请注意,此极端情况o_nz=4仅在此示例中针对单点子域实现。

如果您拆分矩阵,以便将其跨 MPI 程序中的进程存储(例如,矩阵是N×N,我们有M处理器),我的理解是 PETSc 以这样一种方式存储它,即每个处理器都存储一个表示对角块的矩阵(大小N/M×N/M) 和一个代表其他条目的N/M存储在本地处理器上的矩阵行。这样做是因为每个处理器都存储N/M向量的条目,并且执行 matvec 操作是最简单的,如果您可以使用本地存储的矩阵部分对矩阵的对角块执行 matvec,然后使用本地存储的剩余矩阵条目修复其余部分,然后从其他处理器导入的向量条目。

鉴于这种存储方案,我相信您预先分配的对角线和非对角线矩阵条目对应于对角线N/M×N/M矩阵和N/M×NN/M剩余块。