sus*_*att 12
您需要使用Broadcast,因为您希望将相同消息的副本发送到每个进程.Scatter会分解消息并在进程之间分配块.
至于如何发送数据:HIndexed数据类型适合您.
假设您的2d数组定义如下:
int N; // number of arrays (first dimension)
int sizes[N]; // number of elements in each array (second dimensions)
int* arrays[N]; // pointers to the start of each array
Run Code Online (Sandbox Code Playgroud)
首先,您必须计算每个数组的起始地址的位移,相对于数据类型的起始地址,它可以是第一个数组的起始地址,以方便:
MPI_Aint base;
MPI_Address(arrays[0], &base);
MPI_Aint* displacements = new int[N];
for (int i=0; i<N; ++i)
{
MPI_Address(arrays[i], &displacements[i]);
displacements[i] -= base;
}
Run Code Online (Sandbox Code Playgroud)
那么你的类型的定义是:
MPI_Datatype newType;
MPI_Type_hindexed(N, sizes, displacements, MPI_INTEGER, &newType);
MPI_Type_commit(&newType);
Run Code Online (Sandbox Code Playgroud)
此定义将创建一个数据类型,其中包含一个接一个地打包的所有数组.完成此操作后,您只需将数据作为此类型的单个对象发送:
MPI_Bcast(arrays, 1, newType, root, comm); // 'root' and 'comm' is whatever you need
Run Code Online (Sandbox Code Playgroud)
但是,你还没有完成.接收进程需要知道您要发送的数组的大小:如果在编译时无法获得该知识,则必须首先发送包含该数据的单独消息(简单的整数数组).如果N
,sizes
并且arrays
在接收进程上定义类似,并且分配了足够的空间来填充数组,那么所有接收进程需要做的是定义相同的数据类型(与发送者完全相同的代码),然后接收发送者的消息作为该类型的单个实例:
MPI_Bcast(arrays, 1, newType, root, comm); // 'root' and 'comm' must have the same value as in the sender's code
Run Code Online (Sandbox Code Playgroud)
瞧!所有进程现在都有一个数组副本.
当然,如果将2d数组的第二维固定为某个值,事情会变得容易多了M
.在这种情况下,最简单的解决方案是将其存储在单个int[N*M]
数组中:C++将保证它是所有连续的内存,因此您可以在不定义自定义数据类型的情况下广播它,如下所示:
MPI_Bcast(arrays, N*M, MPI_INTEGER, root, comm);
Run Code Online (Sandbox Code Playgroud)
注意:您可能会使用Indexed类型而不是HIndexed.不同之处在于,在Indexed中,displacements
数组以元素数量给出,而在HIndexed中,它是字节数(H代表异类).如果您要使用Indexed,那么给出的值displacements
必须除以sizeof(int)
.但是,我不确定在堆上的任意位置定义的整数数组是否保证在C++中"排列"到整数限制,并且在任何情况下,HIndexed版本都有(略微)较少的代码并产生相同的结果.
如果您要发送连续的数据块(我认为 C 数组是连续的,但我是一名 Fortran 程序员,不太确定),您不需要声明新的 MPI 数据类型,尽管有一些原因可能会导致您这样做想要。分散用于将数组分布到多个进程中;您可以使用 scatter 将数组的每一行发送到不同的进程。因此,对于连续整数数组的示例,最简单的选择是广播,如下所示(考虑到我糟糕的 C 技能):
MPI_Bcast(&buf, numRows*numCols, MPI_INT, root, MPI_COMM_WORLD)
Run Code Online (Sandbox Code Playgroud)
在哪里
&buf
是数组中第一个元素的地址
numRows*numCols
当然,是二维数组中元素的数量
MPI_INT
是(可能)您将使用的内在数据类型
root
是广播数组的进程的等级
MPI_COMM_WORLD
是通常的默认通信器,如果需要可以更改
并且不要忘记广播是一个集体操作,所有进程都进行相同的调用。
如果您的数组不连续,请再次发布一些示例数组大小,我们将弄清楚如何定义 MPI 数据类型。
归档时间: |
|
查看次数: |
10661 次 |
最近记录: |