如何将自定义 MPI_Datatype 发送到不同的进程?
How does one send custom MPI_Datatype over to a different process?
假设我在分配给程序的每个 MPI 进程上为不同大小的子数组创建自定义 MPI_Datatype
。现在我希望将这些子数组发送到主进程,然后 assemble 将它们逐块发送到更大的数组中。主进程不知道其他进程上的各个数据类型(由本地大小定义)。因此,天真地,我可能会尝试以下列方式将这些自定义数据类型发送到主进程。
MPI_Datatype localarr_type;
MPI_Type_create_subarray( NDIMS, array_size, local_size, box_corner, MPI_ORDER_C, MPI_FLOAT, &localarr_type );
MPI_Type_Commit(&localarr_type);
if (rank == master)
{
for (int id = 1; id < nprocs; ++id)
{
MPI_Recv( &localarr_type, 1, MPI_Datatype, id, tag1[id], comm_cart, MPI_STATUS_IGNORE );
MPI_Recv( big_array, 1, localarray_type, id, tag2[id], comm_cart, MPI_STATUS_IGNORE );
}
}
else
{
MPI_Send( &localarr_type, 1, MPI_Datatype, master, tag1[rank], comm_cart );
MPI_Send( local_box, 1, localarr_type, master, tag2[rank], comm_cart );
}
但是,这会导致编译错误,GNU 和 CLANG 编译器会显示以下错误消息,Intel 编译器会显示后一个错误消息。
/* GNU OR CLANG COMPILER */
error: unexpected type name 'MPI_Datatype': expected expression
/* INTEL COMPILER */
error: type name is not allowed
这意味着 (1) 我试图以错误的方式将自定义 MPI_Datatype
发送到另一个进程,或者 (2) 这根本不可能。我想知道它是哪个,如果是 (1),我想知道传达自定义 MPI_Datatype
的正确方式是什么。谢谢。
备注。
我知道无需沟通 MPI_Datatype
即可解决上述问题的其他方法。例如,可以传达本地数组大小并在主进程内的其他进程中手动重建 MPI_Datatype
,然后再将其用于子数组的后续通信。这不是我要找的。
我希望传达自定义 MPI_Datatype
本身(如上例所示),而不是数据类型的实例(这是可行的,如上例所示)上面的示例代码)。
首先:你不能发送那样的数据类型。值 MPI_Datatype
不是 MPI_Datatype
类型的值。 (虽然这是一个可爱的想法。)您可以发送构造它的参数,并在发送类型上重建它。
但是,您可能误解了 MPI 的本质。在您的代码中,工人和经理的数据类型相同,您有点假设每个人都拥有相同的数据 size/shape。这与经理收集所有东西不兼容。
如果您正在收集有关管理进程的数据(通常不是一个好主意:您真的确定需要吗?)然后提供的进程将数据放在一个小数组中,比如索引 0..99 .所以您可以将它们作为普通的连续缓冲区发送。 “经理”有一个更大的数组,并将所有贡献放在不相交的位置。所以管理员最多需要创建子数组类型来指示接收到的数据在大数组中的位置。
假设我在分配给程序的每个 MPI 进程上为不同大小的子数组创建自定义 MPI_Datatype
。现在我希望将这些子数组发送到主进程,然后 assemble 将它们逐块发送到更大的数组中。主进程不知道其他进程上的各个数据类型(由本地大小定义)。因此,天真地,我可能会尝试以下列方式将这些自定义数据类型发送到主进程。
MPI_Datatype localarr_type;
MPI_Type_create_subarray( NDIMS, array_size, local_size, box_corner, MPI_ORDER_C, MPI_FLOAT, &localarr_type );
MPI_Type_Commit(&localarr_type);
if (rank == master)
{
for (int id = 1; id < nprocs; ++id)
{
MPI_Recv( &localarr_type, 1, MPI_Datatype, id, tag1[id], comm_cart, MPI_STATUS_IGNORE );
MPI_Recv( big_array, 1, localarray_type, id, tag2[id], comm_cart, MPI_STATUS_IGNORE );
}
}
else
{
MPI_Send( &localarr_type, 1, MPI_Datatype, master, tag1[rank], comm_cart );
MPI_Send( local_box, 1, localarr_type, master, tag2[rank], comm_cart );
}
但是,这会导致编译错误,GNU 和 CLANG 编译器会显示以下错误消息,Intel 编译器会显示后一个错误消息。
/* GNU OR CLANG COMPILER */
error: unexpected type name 'MPI_Datatype': expected expression
/* INTEL COMPILER */
error: type name is not allowed
这意味着 (1) 我试图以错误的方式将自定义 MPI_Datatype
发送到另一个进程,或者 (2) 这根本不可能。我想知道它是哪个,如果是 (1),我想知道传达自定义 MPI_Datatype
的正确方式是什么。谢谢。
备注。
我知道无需沟通
MPI_Datatype
即可解决上述问题的其他方法。例如,可以传达本地数组大小并在主进程内的其他进程中手动重建MPI_Datatype
,然后再将其用于子数组的后续通信。这不是我要找的。我希望传达自定义
MPI_Datatype
本身(如上例所示),而不是数据类型的实例(这是可行的,如上例所示)上面的示例代码)。
首先:你不能发送那样的数据类型。值 MPI_Datatype
不是 MPI_Datatype
类型的值。 (虽然这是一个可爱的想法。)您可以发送构造它的参数,并在发送类型上重建它。
但是,您可能误解了 MPI 的本质。在您的代码中,工人和经理的数据类型相同,您有点假设每个人都拥有相同的数据 size/shape。这与经理收集所有东西不兼容。
如果您正在收集有关管理进程的数据(通常不是一个好主意:您真的确定需要吗?)然后提供的进程将数据放在一个小数组中,比如索引 0..99 .所以您可以将它们作为普通的连续缓冲区发送。 “经理”有一个更大的数组,并将所有贡献放在不相交的位置。所以管理员最多需要创建子数组类型来指示接收到的数据在大数组中的位置。