如何将长整数和/或无符号整数传递给MPI参数?

Mar*_*son 4 c++ mpi

假设我有一个非常大的数组,我希望用MPI(v1)发送或接收.为了索引这个数组,我使用无符号长整数.

现在,我看到的所有MPI函数调用都使用int类型作为它们的"count"参数,例如在这个例子中:

MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
Run Code Online (Sandbox Code Playgroud)

但是,如果在我的实现中,我需要能够发送/接收大于int可以容纳的最大数量的数组?当我尝试将无符号整数提供给"count"参数时,编译器自然会给出"无效转换"错误.我想过做一个演员,但后来我担心这会缩小我的变量,所以我有点不知所措.

Hri*_*iev 5

进行演员表不是解决方案,因为它会简单地截断长计数.这里要克服两个障碍 - 一个很容易,一个很难.

容易的障碍是intcount参数的类型.您只需创建一个较小的连续类型,然后将数据作为新数据类型的倍数发送即可通过它.示例代码如下:

// 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, ...);
Run Code Online (Sandbox Code Playgroud)

由于count参数MPI_Type_contiguousint,使用这种技术,你可以发送最多(2 31 -1)2 =(2 62 - 2 32 + 1)个元素.如果这还不够,您可以从dt100数据类型创建一个新的连续数据类型,例如:

// Create a contiguous datatype of 100 dt100's (effectively 100x100 elements)
MPI_Datatype dt10000;
MPI_Type_contiguous(100, dt100, &dt10000);
MPI_Type_commit(&dt10000);
Run Code Online (Sandbox Code Playgroud)

如果原始数据大小不是新数据类型大小的倍数,则可以创建结构数据类型,其第一个元素是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, ...);
Run Code Online (Sandbox Code Playgroud)

MPI_Aint是足够大的整数,可以保持大于intLP64系统上可以表示的偏移量.请注意,接收方必须构造相同的数据类型,并在MPI_Recv调用中类似地使用它.但是,接收任意非整数量的连续数据类型有点问题.

这是一个容易的障碍.当您的MPI实现不使用内部长计数时,就会出现这种情况.在这种情况下,MPI通常会崩溃或只发送部分数据或奇怪的可能发生的事情.这样的MPI实现即使没有构建特殊数据类型也可能会崩溃,只需发送类型的INT_MAX元素,MPI_INT因为总消息大小将是(2 31 - 1)*4 = 2 33 - 4.如果是这种情况,您唯一的逃避是手动拆分消息并在循环中发送/接收消息.