Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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,可以使用从同一基本类型派生并具有相同总长度的不同MPI_数据类型发送和接收数据吗 考虑两个MPI进程A和BA有一个数组双A[n],B有一个数组双B[m]。这两个进程都知道A想要发送Bk双倍,它们以某种方式分布在A中(只有A知道这种分布)B(并且只有B)知道它想要如何在B中安排k的双倍。因此,两者都创建(通过MPI\u Type\u index和MPI\u Type\u commit)一个数据类型,该数据类型对于a对应于它想从a发送的元素,对于B对应于它想在B中保存这些元素的位置A调用

有了MPI,可以使用从同一基本类型派生并具有相同总长度的不同MPI_数据类型发送和接收数据吗

考虑两个MPI进程ABA有一个数组
双A[n]
B有一个数组
双B[m]
。这两个进程都知道A想要发送B
k
双倍,它们以某种方式分布在
A
中(只有A知道这种分布)B(并且只有B)知道它想要如何在
B
中安排
k
的双倍。因此,两者都创建(通过
MPI\u Type\u index
MPI\u Type\u commit
)一个数据类型,该数据类型对于a对应于它想从
a
发送的元素,对于B对应于它想在
B
中保存这些元素的位置A调用
MPI Isend(A,1,A\u数据类型,…)
B调用
MPI\u Irecv(B,1,B\u数据类型,…)


这行吗?如果是,这是解决当前问题的标准方法吗?如果没有,这种数据交换通常是如何进行的?

是的,它是有效的,并且是解决这个问题的标准方法

数据类型只是关于如何在发送方打包数据的指令,以及关于如何在接收方解包数据的指令


对于MPI-IO,这是一种非常有用且非常标准的方法。

匹配发送和接收操作的MPI类型必须一致。一致性是一种较弱的等价形式。这意味着这两个数据类型可能不相等,但它们的类型签名必须匹配

每个MPI数据类型是一个元组列表,格式为
(偏移量[i],基本类型[i])
,其中
offset[i]
是第
i
-项从数据缓冲区开始的偏移量(也可以是负数),
基本类型[i]
是项的语言数据类型。这些元组的列表称为类型映射。仅基本类型的列表就称为类型的签名

假设您声明了一个索引数据类型,每个数据类型有5个元素块:

//数据类型1
MPI_数据类型type1;
int b_lens[5]={1,1,1,1,1};
int b_offs[5]={1,2,3,5,7};
MPI_类型索引(5、b_镜头、b_关闭、MPI_双精度和类型1);
type1
具有以下类型映射:{(8,double),(16,double),(24,double),(40,double),(56,double)}和类型签名{double,double,double,double}

现在,使用相同数量的基本元素创建了不同的连续类型:

//数据类型2
MPI_数据类型类型2;
MPI_类型_连续(5、MPI_双精度和类型2);
type2
具有以下类型映射:{(0,double),(8,double),(16,double),(24,double),(32,double)}。此类型映射显然与
type1
的类型映射不同,因为偏移量不同。但是类型签名是相同的:{double,double,double,double}。因此
type1
type2
被认为是一致的

以下代码是完全有效的MPI程序:

双数组1[10];
双阵列2[5];
双阵列3[10];
if(秩==秩\发送方)
{
MPI_发送(阵列1,1,类型1,秩接收器,0,MPI_通信世界);
MPI_发送(阵列1,1,类型1,秩接收器,0,MPI_通信世界);
}
else if(秩==秩\接收器)
{
MPI_状态;
整数元素;
MPI_Recv(阵列2,1,类型2,等级发送方,0,MPI_通信世界,MPI_状态忽略);
MPI记录(阵列3、10、MPI加倍、等级发送方、0、MPI通信世界和状态);
MPI_Get_count(&status,MPI_DOUBLE,&num_elems);//num_elems将设置为5
}
MPI_Send
调用将在发送方拾取
array1
的第1、第2、第3、第5和第7个元素,
MPI_Recv
调用将它们放置在接收方相邻的5元素数组
array2
中。此外,原始数据类型为
MPI_DOUBLE
的10元素接收与发送消息的数据类型一致,但只填充缓冲区的前5个元素。调用数据类型为
MPI\u DOUBLE
MPI\u Get\u count
将返回
5

基本上,两种类型的一致性意味着相同数量、相同基本类型和相同顺序的数据项被打包到消息中,然后从消息中解包


MPI标准要求在正确的应用中具有这种一致性。但在现实中,许多MPI实现并不在消息中传输类型签名,因此一致性从未被强制执行。例如,Open MPI和MPICH都允许您在发送方使用
MPI\u DOUBLE
,在接收方使用
MPI\u LONG
(假设使用LP64系统)。这两种数据类型的字节大小相同,但将
double
转换为
long
毫无意义。有类似的运行时MPI正确性检查工具可以检测代码中的此类问题。

您想传输k个双精度值,其中k是A和B都知道的。问题在哪里?A想将
k
双精度值传输到B,这些值在两个进程的内存中都是非连续排列的。此外,这两个过程的
k
double
值的数据布局是不同的。布局是相关的,即A/B可以根据B/A的布局计算其布局,还是独立的?从你对问题的措辞来看,它们似乎没有什么关系。如果它们是不相关的,那么您的问题是您想要传输
k
值,这是一项非常简单的任务。非常感谢您的回答!根据您所说的,我假设MPI实现发送的实际消息没有(或者至少没有)