创建MPI_Datatype包含指针的结构 [英] Creating an MPI_Datatype for a structure containing pointers

查看:1428
本文介绍了创建MPI_Datatype包含指针的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的结构。

typedef struct
{
 int *Ai;
 double *Ax;
 int nz;
}column;

我想用 MPI_SEND MPI_Receive 来传递这个结构。如何创建一个 MPI_Datatype 这个结构呢?

I want to transfer this structure using MPI_Send and MPI_Receive. How do I create an MPI_Datatype for this structure?

推荐答案

MPI的设计与阵列的结构,而该结构数组工作。

MPI is designed to work with arrays of structures rather that with structures of arrays.

MPI_Hindexed 的@suszterpatt提出的是一个可怕的黑客。它将只允许发送被用来定义在MPI数据类型的结构类型,并且只有元件的一个元件。对于相同的结构类型的其它变量它主要是保证所计算的偏移量将是错误的。除了 Hindexed 类型使用一个和所有元素相同MPI数据类型,因此不允许您发送两个整数和双打。

The MPI_Hindexed that @suszterpatt proposed is a terrible hack. It will only allow you to send one element of the structure type and only the element that was used to define the MPI data type. For other variables of the same structure type it is mostly guaranteed that the computed offsets will be wrong. Besides Hindexed types use one and the same MPI data type for all elements and thus does not allow you to send both ints and doubles.

的明智的做法是把你的程序使用结构数组:

The wise thing to do is to transform your program to use arrays of structures:

 typedef struct
 {
    int i;
    double z;
 } point;

 typedef struct
 {
    point *A;
    int nz;
 } column;

现在,你可以创建一个MPI结构类型 point_type 有三个字段(两个数据字段和一个特殊),并用它来发送新西兰该类型给人元素 column.A 作为缓冲地址:

Now you can create an MPI structured type point_type with three fields (two data fields and one special) and use it to send nz elements of that type giving column.A as the buffer address:

 int lens[3];
 MPI_Aint disps[3];
 MPI_Datatype oldtypes[3], point_type;

 lens[0] = 1; disps[0] = 0; oldtypes[0] = MPI_INT;
 lens[1] = 1; disps[1] = &point.z - &point; oldtypes[1] = MPI_DOUBLE;
 lens[2] = 1; disps[2] = sizeof(point); oldtypes[2] = MPI_UB;
 MPI_Type_create_struct(3, lens, disps, oldtypes, &point_type);
 MPI_Type_commit(&point_type);

 MPI_Send(column.A, column.nz, point_type, ...);

在MPI结构类型的附加第三个字段设置上限的每个元素(有效的大小),并允许你发送即使编译器已经推出填充在结构上许多连续的结构元素。

The additional third field in the MPI structure type sets the upper bound of each element (effectively its size) and allows you to send many consecutive structure elements even if the compiler has introduced padding in the structure.

在接收端,你会偷看的消息, MPI_PROBE ,提取元素与 MPI_Get_count 与数 point_type 的类型(即径直到新西兰字段),分配 A 字段,并用它在 MPI_RECV 接收新西兰元素:

On the receiver side you would peek the message with MPI_Probe, extract the number of elements with MPI_Get_count with a type of point_type (that goes straight to the nz field), allocate the A field and use it in MPI_Recv to receive the nz elements:

 MPI_Status status;
 MPI_Probe(source, tag, comm, &status);
 MPI_Get_count(&status, point_type, &column.nz);
 if (nz == MPI_UNDEFINED)
   ... non-integral message was received, do something
 column.A = (point *)malloc(column.nz*sizeof(point));
 MPI_Recv(column.A, column.nz, point_type, source, tag, comm, MPI_STATUS_IGNORE);

如果是code的变化是不可能的,你仍然可以通过发送之前将您的结构的中间步骤,这个过程通常称为的(非)整编的。在你的情况做这样的事情(我假设你存储在这两个数组元素的个数在新西兰字段):

If that code change is impossible you can still go through the intermediate step of transforming your structure before sending it, a process usually called (un-)marshaling. In your case do something like this (I assume that you store the number of array elements in both Ai and Ax in the nz field):

 point *temp = (point *)malloc(nz*sizeof(point));
 for (int i = 0; i < column.nz; i++)
 {
   temp[i].i = column.Ai[i];
   temp[i].z = column.Az[i];
 }
 MPI_Send(temp, nz, point_type, ...);
 free(temp);

在接收端必须做相反:分配一个足够大的缓冲区,可容纳结构,它收到消息,然后做相反的转化

On the receiver side you must do the opposite: allocate a large enough buffer that can hold the structure, receive the message in it and then do the opposite transformation.

再一次,你不需要传输新西兰的实际价值,因为它可以使用该消息的长度可以容易地提取 MPI_Get_count

Once again, you do not need to transmit the actual value of nz since it can be easily extracted from the length of the message using MPI_Get_count.

这篇关于创建MPI_Datatype包含指针的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆