首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用C- MPI_Send()和MPI_Recv()解决问题的MPI编程

用C- MPI_Send()和MPI_Recv()解决问题的MPI编程
EN

Stack Overflow用户
提问于 2014-12-02 21:38:06
回答 2查看 907关注 0票数 1

我目前正在使用MPI开发一个C程序,我遇到了一个关于MPI_Send()和MPI_Recv()函数的障碍,我希望你们都能帮我解决这个问题。我的目标是发送(使用MPI_Send())和接收(使用MPI_Recv()),地址"a“(定义如下),然后在从MPI_Recv()收到地址后显示该地址的内容,以确认我的发送和接收是否正常。我在下面概述了我的问题:

我有一个二维数组"a",它的工作方式如下:a包含我的目标地址*a包含我的目标值。

printf("a[0][0] Value = %3.2f, a[0][0] Address = %p\n", *a[0][0], a[0][0]);

调试确认a包含地址0x83d6260,存储在地址0x83d6260上的值为0.58。换句话说,"a = 0x83d6260“和"*a = 0.58”。

因此,我传递地址"a“作为MPI_Send()的第一个参数:-> MPI_Send(a[0][0], 1, MPI_FLOAT, i, 0, MPI_COMM_WORLD); // I将1作为第二个参数,因为我只想接收这一个地址

MPI_Send()执行并返回0,这是MPI_SUCCESS,这意味着它成功了,我的调试确认"0x83d6260“是传递的地址。

但是,当我试图使用MPI_Recv()接收地址时,我得到了分段错误:MPI_Recv(a[0][0], 1, MPI_FLOAT, iNumProcs-1, 0, MPI_COMM_WORLD, &status);

地址0x83d6260是使用MPI_Send()成功发送的,但我无法接收与MPI_Recv()相同的地址。我的问题是-为什么MPI_Recv()会导致段错误?我只想在MPI_Recv()调用之后立即打印包含在其中的值,但是程序会崩溃。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-02 22:25:43

MPI_Send(a[0][0], 1, MPI_FLOAT ...)将发送大小为sizeof(float)的内存,从

因此,发送的值是*(reinterpret_cast<float*>(a[0][0]))

因此,如果a[0][0]0x0x83d6260,而*a[0][0]0.58f,则MPI_Recv(&buff, 1, MPI_FLOAT...)将将buffer (需要分配的浮点数类型)设置为0.58

重要的是,不同的MPI程序不应该共享指针(即使它们运行在同一个节点上)。它们不共享虚拟内存分页和事件--如果您能够从其中一个级别访问该入口,则如果您试图在它们的上下文中访问相同的入口,则其他节点应该会给您一个分段错误。

编辑

此代码适用于我:

代码语言:javascript
运行
复制
#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;
}

结果如下:

代码语言:javascript
运行
复制
mpicc mpi.c && mpirun ./a.out -n 2
> rank 0 send done
> rank 1 recv done : 0.580000
票数 0
EN

Stack Overflow用户

发布于 2014-12-02 22:13:12

我认为问题在于,您试图将该值放入指针数组(这可能是导致分段错误的原因)。尝试创建一个新的缓冲区来接收以下值:

代码语言:javascript
运行
复制
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将取消引用指针,给出值,而不是地址。

您也没有提供足够的信息来判断您的源/目标值是否正确。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27259465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档