我目前正在使用MPI开发一个C程序,我遇到了关于MPI_Send()和MPI_Recv()函数的障碍,希望大家都能帮到我。我的目标是发送(使用MPI_Send()),并接收(使用MPI_Recv())地址“a [0] [0]”(定义如下),然后在我发布后显示该地址的内容从MPI_Recv()收到它,以确认我的发送和接收工作正常。我在下面概述了我的问题:
我有一个二维数组,“a”,就像这样: a [0] [0]包含我的目标ADDRESS * a [0] [0]包含我的目标VALUE
即。 printf("a[0][0] Value = %3.2f, a[0][0] Address = %p\n", *a[0][0], a[0][0]);
所以,我运行我的程序并为内存分配了一个。 Debug确认a [0] [0]包含地址0x83d6260,存储在地址0x83d6260的值为0.58。换句话说,“a [0] [0] = 0x83d6260”和“* a [0] [0] = 0.58”。
因此,我将地址“a [0] [0]”作为MPI_Send()的第一个参数传递:
- > MPI_Send(a[0][0], 1, MPI_FLOAT, i, 0, MPI_COMM_WORLD);
//我把1作为第二个参数因为我只想接收这个地址
MPI_Send()执行并返回0,这是MPI_SUCCESS,这意味着它成功了,我的Debug确认“0x83d6260”是传递的地址。
但是,当我尝试使用MPI_Recv()接收地址时,我得到了分段错误:
MPI_Recv(a[0][0], 1, MPI_FLOAT, iNumProcs-1, 0, MPI_COMM_WORLD, &status);
使用MPI_Send()成功发送地址0x83d6260,但我无法使用MPI_Recv()接收相同的地址。我的问题是 - 为什么MPI_Recv()导致段错误?我想在MPI_Recv()调用之后立即打印[0] [0]中包含的值,但程序崩溃。
答案 0 :(得分:0)
我认为问题在于你试图将值放入指针数组(这可能导致段错误)。尝试创建一个新的缓冲区来接收值:
MPI_Send(a[0][0], 1, MPI_FLOAT, i, 0, MPI_COMM_WORLD);
....
double buff;
MPI_Recv(&buff, 1, MPI_FLOAT, iNumProcs-1, 0, MPI_COMM_WORLD, &status);
如果我没记错的话,MPI_Send / Recv会取消引用指针给你的值,而不是地址。
您还没有向我们提供足够的信息来判断您的来源/目的地值是否正确。
答案 1 :(得分:0)
MPI_Send(a[0][0], 1, MPI_FLOAT ...)
将从[0] [0]开始发送大小为sizeof(float)
的内存
所以基本上发送的值是*(reinterpret_cast<float*>(a[0][0]))
因此,如果a[0][0]
为0x0x83d6260
且*a[0][0]
为0.58f
,则MPI_Recv(&buff, 1, MPI_FLOAT...)
将设置buffer
(类型为float,需要为分配到0.58
重要的是,不同的MPI程序永远不应该共享指针(即使它们在同一节点上运行)。如果您能够从排名中的一个访问地址,则他们不共享虚拟内存分页和事件,如果您尝试在其上下文中访问相同的地址,则其他人应该给您一个段错误
此代码适用于我:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc, char* argv[])
{
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
switch(rank)
{
case 0:
{
float*** a;
a = malloc(sizeof(float**));
a[0] = malloc(sizeof(float* ));
a[0][0] = malloc(sizeof(float ));
*a[0][0] = 0.58;
MPI_Send(a[0][0], 1, MPI_FLOAT, 1, 0, MPI_COMM_WORLD);
printf("rank 0 send done\n");
free(a[0][0]);
free(a[0] );
free(a );
break;
}
case 1:
{
float buffer;
MPI_Recv(&buffer, 1, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("rank 1 recv done : %f\n", buffer);
break;
}
}
MPI_Finalize();
return 0;
}
结果是:
mpicc mpi.c && mpirun ./a.out -n 2
> rank 0 send done
> rank 1 recv done : 0.580000