2015-04-05 18 views
1

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

...... 
    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 
+0

欢迎来到StackOverflow!总的来说,你的问题并不差(特别是对于非母语初学者),但是在你的问题中,我已经改进了一些可以用来改进未来问题的东西。查看编辑内容,以便下次学习。 – 2015-04-07 14:48:10

回答

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。由于它只分配itertab缓冲区的本地部分,因此这将在进程2中失败。您需要减去xpixel的偏移量。

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

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

感谢您的快速响应,我真的很赞赏。 对于第一个问题,很明显,我有我的错误,但我没有看到你的意思后续问题,在calclue函数中,事情应该是这样的? itertab [(xpixel-(nbpixelx/MACHINE_NUM))* nbpixely + ypixel] = iter; – kakamo 2015-04-05 17:32:45

+0

是的,类似的东西。这是需要的,因为您的itertab缓冲区只有全局大小的1/2(即总大小),但您尝试使用全局索引对其进行索引。 – Patrick 2015-04-05 19:48:48

+0

但我认为如果这是一个未分配内存的问题,它应该显示一个像分段错误一样的错误,而不仅仅是冻结? – kakamo 2015-04-10 08:29:35