MPI程序在MPI_Recv期间冻结

时间:2015-04-05 15:38:32

标签: c parallel-processing mpi

我是MPI并行编程的初学者。我已经写了这段小代码来绘制Mandelbrot fracta。想法是第一个奴隶将计算前半部分,将其粘贴在指针中,然后将其发送给等待接收指针的主节点。第二个节点也会发生同样的事情。最后,主节点应该在2个不同的变量中得到结果,并将它们写在一个文件中。

......
    if((itertab=malloc((sizeof(int)*sizebuffre))) == NULL) { 
        printf("ERREUR , errno : %d (%s) .\n",errno,strerror(errno)); 
        return EXIT_FAILURE; 
    } 
    int rank, size,start,end;

    MPI_Init (&argc, &argv); /* starts MPI */ 
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */ 
    MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
    MPI_Status st;

    /*allocation du tableau de pixel*/ 
    if (rank==1) { 
        xpixel = 0; 
        end = (nbpixelx/MACHINE_NUM); 
        Calcule(xpixel,end); 
        printf("rank 1 start : %d, end : %d\n",xpixel,end); 
        MPI_Send(&itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD); 
        free(itertab); 
        printf("work done : i am rank 1 \n"); 
    } 
    if (rank==2) {
        xpixel = (nbpixelx/MACHINE_NUM); 
        end = nbpixelx; 
        Calcule(xpixel,end); 
        printf("rank 2 start : %d, end : %d\n",xpixel,end); 
        MPI_Send(&itertab,sizebuffre,MPI_INT,0,6,MPI_COMM_WORLD); 
        printf("work done : i am rank 2 \n"); 
        free(itertab); 
    }

    if (rank==0) { 
        if((itertabA=malloc((sizeof(int)*sizebuffre))) == NULL) { 
            printf("ERREUR d'allocation de itertabA, errno : %d (%s) .\n",errno,strerror(errno)); 
            return EXIT_FAILURE; 
        } 
        if((itertabB=malloc((sizeof(int)*sizebuffre))) == NULL) { 
            printf("ERREUR d'allocation de itertabB, errno : %d (%s) .\n",errno,strerror(errno)); 
            return EXIT_FAILURE; 
        }
        printf("test before reciving result from first slave\n");
        MPI_Recv(itertabA,sizebuffre,MPI_INT,1,5,MPI_COMM_WORLD,&st); 
        printf("result recived  rank 1 \n"); 
        MPI_Recv(itertabB,sizebuffre,MPI_INT,2,6,MPI_COMM_WORLD,&st); 
        printf("result recived rank 2 \n");



    }

    MPI_Finalize(); 
    return EXIT_SUCCESS; 
}

问题是我的代码冻结了主人从第一个奴隶收到结果的行,但我不知道为什么?

我试图调试结果。我添加了一些printf来查看冻结的位置。这是结果:

test before reciving result from first slave
test in calcule function
trairment xpixel 0
trairment xpixel 1
trairment xpixel 2
...snip...
trairment xpixel 399
test after the end off calculating loop
rank 1 start : 0, end : 400
^C

1 个答案:

答案 0 :(得分:0)

您的MPI代码无法正常工作,因为您将错误的参数传递给MPI_Send。您的变量itertab已经是指向数据缓冲区的指针,因此您无需再次对其进行重新引用。

而不是:

MPI_Send(&itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);

做的:

MPI_Send(itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);

另一个问题是您在Calcule函数和输出循环中访问未分配的内存。在Calcule函数中,您正在写入itertab[xpixel*nbpixely+ypixel]=iter。对于进程2,这将失败,因为它仅分配itertab缓冲区的本地部分。您需要减去xpixel的偏移量。

在输出循环中,您正在使用全局索引读取itertabB。在这里,您还应该减去xpixel的偏移量,如下所示:

fprintf(file,"%f %f %d\n", x, y,itertabB[(xpixel-(nbpixelx/MACHINE_NUM))*nbpixely+ypixel]);