繁体   English   中英

C语言中的MPI编程-MPI_Send()和MPI_Recv()地址问题

[英]MPI Programming in C - MPI_Send() and MPI_Recv() Address Trouble

我目前正在使用MPI进行C程序开发,并且遇到了有关MPI_Send()和MPI_Recv()函数的障碍,希望大家能为我提供帮助。 我的目标是发送(使用MPI_Send())和接收(使用MPI_Recv())的地址“ a [0] [0]”(在下面定义),然后在显示完之后显示该地址的内容从MPI_Recv()接收到它,以确认我的发送和接收工作正常。 我在下面概述了我的问题:

我有一个二维数组“ a”,其工作方式如下:a [0] [0]包含我的目标地址* a [0] [0]包含我的目标值

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

因此,我运行我的程序,并且为a分配了内存。 调试确认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()调用后立即打印a [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会取消引用指针,为您提供值,而不是地址。

您也没有给我们足够的信息来说明您的源/目标值是否正确。

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

因此,基本上发送的值为*(reinterpret_cast<float*>(a[0][0]))

因此,如果a[0][0]0x0x83d6260并且*a[0][0]0.58fMPI_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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM