进行强制转换并不是解决方案,因为它只会截断长计数。这里有两个障碍需要克服——一个简单,一个困难。
最容易的障碍是int
输入计数参数。您可以简单地通过创建较小尺寸的连续类型然后将数据作为新数据类型的倍数发送来克服它。示例代码如下:
// Data to send
int data[1000];
// Create a contiguous datatype of 100 ints
MPI_Datatype dt100;
MPI_Type_contiguous(100, MPI_INT, &dt100);
MPI_Type_commit(&dt100);
// Send the data as 10 elements of the new type
MPI_Send(data, 10, dt100, ...);
Since the count argument of MPI_Type_contiguous
is int
, with this technique you can send up to (231-1)2 = (262 - 232 + 1) elements. If this is not enough, you can create a new contiguous datatype from the dt100
datatype, e.g.:
// Create a contiguous datatype of 100 dt100's (effectively 100x100 elements)
MPI_Datatype dt10000;
MPI_Type_contiguous(100, dt100, &dt10000);
MPI_Type_commit(&dt10000);
如果原始数据大小不是新数据类型大小的倍数,则可以创建一个结构数据类型,其第一个元素是数组int(data_size / cont_type_length)
连续数据类型的元素,其第二个元素是数组datasize % cont_type_length
原始数据类型的元素。示例如下:
// Data to send
int data[260];
// Create a structure type
MPI_Datatype dt260;
int blklens[2];
MPI_Datatype oldtypes[2];
MPI_Aint offsets[2];
blklens[0] = 2; // That's int(260 / 100)
offsets[0] = 0;
oldtypes[0] = dt100;
blklens[1] = 60; // That's 260 % 100
offsets[1] = blklens[0] * 100L * sizeof(int); // Offsets are in BYTES!
oldtypes[1] = MPI_INT;
MPI_Type_create_struct(2, blklens, offsets, oldtypes, &dt260);
MPI_Type_commit(&dt260);
// Send the data
MPI_Send(data, 1, dt260, ...);
MPI_Aint
是足够大的整数,可以容纳大于的偏移量int
可以在 LP64 系统上表示。请注意,接收方必须构造相同的数据类型并在接收方中类似地使用它MPI_Recv
称呼。不过,接收任意非整数数量的连续数据类型有点问题。
That's the easy obstacle. The not so easy one comes when your MPI implementation does not use internally long counts. In that case MPI would usually crash or only send part of the data or something weird might happen. Such an MPI implementation could be crashed even without constructing a special datatype by simply sending INT_MAX
elements of type MPI_INT
as the total message size would be (231 - 1) * 4 = 233 - 4. If that is the case, your only escape is manually splitting the message and sending/receiving it in a loop.