Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将长整数和/或无符号整数传递给MPI参数?_C++_Mpi - Fatal编程技术网

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

C++ 如何将长整数和/或无符号整数传递给MPI参数?,c++,mpi,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) 但是,如果在我的实现中,我需要能够发送/接收大于int所能容纳的最大数的数组,该怎

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

现在,我看到的所有MPI函数调用都使用int类型作为其“count”参数,例如在本例中:

MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

但是,如果在我的实现中,我需要能够发送/接收大于int所能容纳的最大数的数组,该怎么办?当我试图向“count”参数提供一个无符号整数时,编译器自然会给我一个“invalid conversion”错误。我想做一个强制转换,但是我担心这会缩小我的变量,所以我有点不知所措。

一个快速的解决方案是对发送方的未签名计数器执行强制转换,然后对接收方执行反向强制转换。但是,我认为更好的解决方案是创建一个包含指针和计数的结构,使用正确的类型,并按照的建议创建自己的自定义数据类型,以便使用MPI_type_create_struct传递。

执行强制转换不是解决方案,因为它将简单地截断长计数。这里有两个障碍需要克服——一个容易的和一个困难的

容易遇到的障碍是count参数的
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, ...);
// 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_Type_continuous
的count参数是
int
,因此使用此技术最多可以发送(231-1)2=(262-232+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);
如果原始数据大小不是新数据类型大小的倍数,则可以创建一个结构数据类型,其第一个元素是
int(data\u size/cont\u type\u length)数组
连续数据类型的元素,其第二个元素是原始数据类型的
数据大小%cont\u type\u长度的数组。示例如下:

// 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, ...);
// 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
是一个足够大的整数,可以容纳大于LP64系统上
int
所能表示的偏移量。请注意,接收方必须构造相同的数据类型,并在
MPI\u Recv
调用中类似地使用它。不过,接收任意数量的连续数据类型有点问题


这是一个容易的障碍。当MPI实现不使用内部长计数时,就不那么容易了。在这种情况下,MPI通常会崩溃,或者只发送部分数据,或者可能会发生一些奇怪的事情。这样的MPI实现即使不构建特殊的数据类型也可能崩溃,只需发送
INT\u MAX
类型
MPI\u INT
的元素,因为总消息大小为(231-1)*4=233-4。如果是这种情况,您唯一的逃避方法就是手动拆分消息并在循环中发送/接收它。

您可能只需要将数据包拆分为多个较小的数据包。请看,我看不出您的两个想法将如何产生正确的数据传输量。消息的大小不是一个不透明的值。谢谢您的回答,但我也不太明白如何使用结构来实现这一点。主要问题是,结构还需要一个“count”变量。所以,是的,我可以将需要的整个数组范围打包到一个结构中,然后只发送“一”个结构。但在创建结构时,我面临同样的问题,即MPI不接受整数参数。你能帮我理解一下你的想法吗?@MarkAnderson当你发送结构时,计数是你发送的结构的数量。在您的情况下,它将是一个单一结构,因此计数为1。@BenVoigt
count
参数没有指定直接发送的数据量,它是缓冲区中包含的元素数。请看,正在发送的数据类型的大小是一个单独的参数。@maxywb,我知道。但是在创建结构本身时,必须给出结构内部元素的计数。因此,这只会使问题倒退一步。问题不在于数据类型的大小,而在于缓冲区中包含的元素数量,因为我的缓冲区可能包含大量元素。仅就“现在是2014年”发表评论,以Intel MPI为例,消息大小仍然限制在2GB,即使元素数量符合4字节整数(和)。我不知道其他实现。这只是晚上自动写入的效果。最近,我们集群上的一些软件出现了问题,当用户从Open MPI切换到Intel MPI时,开始出现问题,而消息大小是罪魁祸首。