2016-04-03 101 views
5

我试图从进程0发送数据到进程1.当缓冲区大小小于64kb时,该程序成功,但如果缓冲区变得更大,则挂起。 下面的代码应该重现这个问题(应该挂),但应该会成功,如果n被修改为小于8000MPI发送和接收挂起的缓冲区大小大于64kb

int main(int argc, char *argv[]){ 
    int world_size, world_rank, 
     count; 
    MPI_Status status; 


    MPI_Init(NULL, NULL); 

    MPI_Comm_size(MPI_COMM_WORLD, &world_size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
    if(world_size < 2){ 
    printf("Please add another process\n"); 
    exit(1); 
    } 

    int n = 8200; 
    double *d = malloc(sizeof(double)*n); 
    double *c = malloc(sizeof(double)*n); 
    printf("malloc results %p %p\n", d, c); 

    if(world_rank == 0){ 
    printf("sending\n"); 
    MPI_Send(c, n, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD); 
    printf("sent\n"); 
    } 
    if(world_rank == 1){ 
    printf("recv\n"); 
    MPI_Recv(d, n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status); 

    MPI_Get_count(&status, MPI_DOUBLE, &count); 
    printf("recved, count:%d source:%d tag:%d error:%d\n", count, status.MPI_SOURCE, status.MPI_TAG, status.MPI_ERROR); 
    } 

    MPI_Finalize(); 

} 

Output n = 8200; 
malloc results 0x1cb05f0 0x1cc0640 
recv 
malloc results 0x117d5f0 0x118d640 
sending 

Output n = 8000; 
malloc results 0x183c5f0 0x184c000 
recv 
malloc results 0x1ea75f0 0x1eb7000 
sending 
sent 
recved, count:8000 source:0 tag:0 error:0 

我发现这个question,这question是相似的,但我相信这个问题有与创造僵局。我不希望在这里出现类似的问题,因为每个进程只执行一次发送或接收。

编辑:增加了状态检查。

编辑2:看来问题是我安装了OpenMPI,但是在安装MKL时还安装了来自英特尔的MPI实施。我的代码正在使用OpenMPI头文件和库进行编译,但使用Intel的mpirun运行。当我确保使用来自OpenMPI的mpirun可执行文件运行时,所有工作都按预期运行。

+1

代码看起来很好,事实上在我的OpenMPI安装中运行得很好。请提供有关您的安装的更多信息。您是否能够使用该安装运行任何足够复杂的MPI代码?请在此处提供信息。输出以及尝试调试挂起的进程将有所帮助。 – Zulan

+0

我同意@Zulan,但我会问Ruvu检查'status'。 – gsamaras

+0

另请参见:请检查'malloc'的结果**值! – Zulan

回答

3

的问题是具有安装了英特尔MPI和的openmpi。 我看到/ usr/include/mpi。h的通过的openmpi拥有,但mpicc和的mpirun来自英特尔的实现:

$ which mpicc 
/opt/intel/composerxe/linux/mpi/intel64/bin/mpicc 
$ which mpirun 
/opt/intel/composerxe/linux/mpi/intel64/bin/mpirun 

我能够运行

/usr/bin/mpicc 

/usr/bin/mpirun 

,以确保我用来解决问题的openmpi。

感谢@Zulan和@gsamaras的建议检查我的安装。

+0

欢迎Ruvu!好的事情你也努力去解决这个问题,+2。 – gsamaras

+0

我强烈建议您检查[环境模块](https://en.wikipedia.org/wiki/Environment_Modules_(software))。它允许您保留同一软件的多个版本和安装。稍后,您可以决定要使用的版本,而不必担心是否正确设置了PATH。 –

1

代码很好!我只是检查与版本3.1.3(mpiexec --version):

linux16:/home/users/grad1459>mpicc -std=c99 -O1 -o px px.c -lm 
linux16:/home/users/grad1459>mpiexec -n 2 ./px 
malloc results 0x92572e8 0x9267330 
sending 
sent 
malloc results 0x9dc92e8 0x9dd9330 
recv 
recved, count:8200 source:0 tag:0 error:1839744 

结果,问题就来进行安装。通过以下疑难解答选项运行:

  1. 检查的malloc的结果*
  2. 检查status

我敢打赌的malloc()返回值是NULL,因为你如果您要求更多内存,它会失败。这可能是因为系统拒绝给予这种记忆。


我部分是正确的,问题就来安装,但作为OP说:

看来问题是我已经安装的openmpi也安装了英特尔MPI的实现当我安装MKL时。我的代码正在使用OpenMPI头文件和库进行编译,但使用Intel的mpirun运行。当我确保使用来自OpenMPI的mpirun可执行文件运行时,所有工作都按预期运行。

* checking that `malloc` succeeded in C