划分4D笛卡尔网格进行并行处理

Divide 4D cartesian grid for parallel processing

本文关键字:并行处理 网格 4D 笛卡尔 划分      更新时间:2023-10-16

我正试图为4D输入向量的给定网格上的所有点计算一些函数(实现为计算成本很高的迭代算法((网格是笛卡尔的,每个维度上有等距点,由线段[a, b]指定,该线段上等距点的数量/恒定步长-每个维度(总共4个((。我们可以从"真实世界"的值中抽象出来,并将网格视为具有给定维度的4D阵列([5, 4, 3, 7]-5x4x3x7笛卡尔网格(,并使用它们上的索引来引用一些切片/点。

我的计算算法将该向量(指定4D网格上的点(作为输入,并计算(可能在相当长的时间内(一些结果(它们是什么并不重要(。

我需要将程序并行化,以加快对所有网格顶点的漫长计算过程。因此,我想将输入网格划分为子网格,每个网格上的点数量尽可能接近,以平衡不同线程/进程上的工作负载。

最简单的解决方案是在一个选定的维度上划分网格,但问题是,这个独立维度上的切片数量可能少于"虚拟计算设备"的数量(使用中的不同线程/进程-我将它们称为VCD(。正在使用的VCD的数量是不恒定的,并且等于我们需要的子网格的数量。所以我需要使用更多的维度来进行"分割"——我认为使用2-3个维度(由于特定的输入——我们可以假设一些维度大于一些值(可以产生足够的切片来在VCD之间分割。

为了更好地解释,这里有一个例子。我们在每个维度上都有4D网格大小的[2, 2, 10, 7]矢量。子网格数为20。所以我们不能把其中一个维度分成20个部分,我们必须以某种方式把它们组合起来。在这种情况下,我们很幸运地注意到,2,3个维度正好给出2x10个点=20个VCD。因此,我们只需将网格划分为20 [2, 1, 1, 7]子网格(在2,3维上退化(,并将其传递给VCD。

当没有一个维度的产品被VCD的数量分割而没有余数时,这就变得更困难了,所以我们需要以某种方式分发它/我们需要使用更多的维度来分割。例如,VCD计数的[2, 3, 4, 5]=11

因此,问题是-如何将给定的笛卡尔4D网格拆分为N个子网格(网格上的点数大于N(,可能同时使用多个维度(可以假设互补条件,即某些维度(至少3个(产生的切片数大于N-dim[1] x dim[2] x dim[3]>N(

我接受任何语言的答案,但C风格的伪代码更可取。

EDIT:正如Nico Schertler所指出的,我意识到我根本不需要拆分网格。我知道序列化索引的诀窍(多亏了矩阵和堆实现(,但我被我的"多维"思维方式误导了。此外,我忘了指定网格上的计算是完全独立的。我最初必须解决的问题是"如何划分4D网格进行并行处理"——建立一个序列化索引,并在处理器之间基于它将点序列划分为段,这是一个明亮而简单的解决方案(但对我来说并不明显(。同样,这个答案也适用于N维网格。所以我学到的教训是——迭代(甚至并行(只需要一个维度,所以尝试序列化。

如果只是计算值(并且没有依赖项(,那么根本不需要在网格上工作。相反,将网格序列化为1D序列,并将该序列均匀地分布在处理器之间。

最简单的序列化是:

i = x + dim[1] * (y + dim[2] * (z + dim[3] * w))

逆变换为:

x = i % dim[1]
y = (i / dim[1]) % dim[2]
z = (i / dim[1] / dim[2]) % dim[3]
w = (i / dim[1] / dim[2] / dim[3])