Matrix 理解块和块循环矩阵分布

Matrix 理解块和块循环矩阵分布,matrix,mpi,distributed-computing,scalapack,Matrix,Mpi,Distributed Computing,Scalapack,在处理矩阵的并行分解时,我熟悉块分布,其中我们有(比如)4个过程,每个过程都有各自的矩阵子区域: 例如,这里一行(procrows)中的进程数等于2,一列(proccols)中的进程数也等于2,如果原始矩阵大小为nxm,则子矩阵a_local的大小将为N/2xm/2 我正在阅读这篇使用“块循环”分布的文章,在这一部分: /* Begin Cblas context */ /* We assume that we have 4 processes and place them in a 2-by

在处理矩阵的并行分解时,我熟悉块分布,其中我们有(比如)4个过程,每个过程都有各自的矩阵子区域:

例如,这里一行(
procrows
)中的进程数等于2,一列(
proccols
)中的进程数也等于2,如果原始矩阵大小为
nxm
,则子矩阵
a_local
的大小将为
N/2xm/2

我正在阅读这篇使用“块循环”分布的文章,在这一部分:

/* Begin Cblas context */
/* We assume that we have 4 processes and place them in a 2-by-2 grid */
int ctxt, myid, myrow, mycol, numproc;
int procrows = 2, proccols = 2;
Cblacs_pinfo(&myid, &numproc);
Cblacs_get(0, 0, &ctxt);
Cblacs_gridinit(&ctxt, "Row-major", procrows, proccols);
它们有
proclows
proccol
是硬编码的,很好,但是对于读入的矩阵,有一个标题:

Nb和Mb将是[矩阵的]块的行数和列数

我不明白这一点;
Nb
Mb
不是完全由N、M、proclows和proccol决定的吗


编辑


通过运行该示例,我可以看到进程0上的子矩阵包含矩阵左上角的所有元素,就像上面的图片一样,这与Jonathan的答案相矛盾。但是,它可以与ScaLAPACK的Cholesky配合使用。

如您在问题中所述,矩阵的块分解是分布矩阵的一种非常有效的方法,但它不是唯一的方法

特别是,块数据分布(将矩阵分解为
proclows x process
子矩阵)有点不灵活。如果矩阵大小不能被一行或一列中的进程数整除——通常情况下,您无法控制矩阵的大小,并且只能通过procrows/proccols获得一些灵活性——那么最终可能会出现严重的负载平衡问题。此外,有时能够“过度分解”问题非常方便;把它分解成比你有任务更多的碎片。特别是对于MPI,由于每个任务都是一个进程,因此有时能够为每个进程提供多个子矩阵来操作是非常有用的,这样您就可以通过线程(大多数单进程线性代数库中都内置了线程)来处理这一额外的并行级别

要获得负载平衡的最大灵活性,并获得最高程度的进程间并行性,方法是纯粹的循环分布。在一维循环分布中,假设在4个处理器之间划分15个项目,处理器1将获得项目1,2将获得项目2,3将获得项目3,4将获得4,然后处理器1将获得项目5,依此类推;您可以在处理器之间循环项目

另一方面,在一维块分解中,处理器1将得到项目1-4,处理器2将得到项目5-9,依此类推

下面是一个有用的图形,每个颜色标记哪个处理器获得一个数据区域:

因此,循环分解在最大程度上有利于并行性和负载平衡,但在数据访问方面却很糟糕;为了进行线性代数运算,您希望访问的每一个相邻数据段都脱离了处理器。另一方面,块分解最大程度上有利于数据访问;您拥有尽可能大的连续数据块,因此您可以对漂亮的大子矩阵执行矩阵运算;但是它对于并行性来说是不灵活的,并且在负载平衡方面可能会有成本

块循环是两者之间的插值;您将矩阵过度分解为块,并循环地将这些块分布到各个进程中。这使您可以调整数据访问连续性和灵活性之间的权衡。如果块循环块大小为1,则具有循环分布;如果它们是
N/proclows
N/proccols
则具有块分布;但你也可以在两者之间选择任何东西

请注意,在2D中,原则上您可以沿行和列选择不同的分解,如果您的矩阵仅用于一种类型的计算,有时这会很有用;但更常见的情况是,分解在所有维度中都是相同的,因此,当人们说“块分解”或“块循环分解”时,它们通常意味着沿着所有维度


有关这方面的详细说明,请参见。

@VladimirF I执行的代码和子矩阵为4x4,据说该程序是通过设置
Nb=Mb=2
的cmd args调用的。谢谢你的评论,但至少在这一点上,这对我来说没有意义/嗯,@VladimirF,我不能把所有的信息都放在那里,所以我不知道要补充什么。那么,为什么它们是一样的呢?我的意思是,我想做动态的,以便在更小的矩阵中使用更少的进程。我是否应该使
proclows=Nb
?还有,你打算给出答案吗?@VladimirF我确实在问题中添加了更多信息,现在好了吗?请选择一个更好的标题。这不是关于CBLAC、BLAC、MPI或SCALAPACK的问题;这是一个关于矩阵的块循环分布的问题。一行中的进程数不同于(小于)一行中的块数是很常见的,事实上,这是通常的情况,尽管它们相等是合法的。Jonathan感谢您的回答!我在这里挣扎!最后一个链接很好。然而,我仍然感到困惑。该链接得出结论:“二维块循环分布方案是ScaLAPACK库中用于密集矩阵计算的数据布局。”。然而,从运行我链接到的示例来看,这个分布看起来就像您答案中的2D右上角一样,它与Cholesky的ScaLAPACK一起工作(我检查过)。更重要的是,IMHO仍然没有回答这个问题:“
Nb
Mb
不是完全由
N
M
proclows
proccols
决定的吗?”@gsamaras-不,Nb可以是1到N/proc之间的任何整数