2015-10-21 82 views
2

我正在学习MPI代码。我正在尝试使用不同大小的块进行流水线环播。但是,当我运行我的代码时,它会在Process 0尝试发送第二个数据块时遇到死锁,而我不知道为什么。任何帮助,将不胜感激。简单MPI流水线环广播代码死锁

注意:这是一个更大的代码的一部分。它在Process 0中填充一个带有字符的缓冲区。在使用print语句进行一些简单的调试之后,我相信第9行(用***标记)出错了,因为这是程序停滞的地方。数据的第二块不会从进程发送0

int offset; 
MPI_Status status; 

if (rank == 0) { 
    offset = 0; 
    while (offset < NUM_BYTES) { 
     MPI_Send(&chunk_size, 1, MPI_INT, rank + 1, 3, MPI_COMM_WORLD); 
     MPI_Send(&offset, 1, MPI_INT, rank + 1, 2, MPI_COMM_WORLD); 
     MPI_Send(&buffer[offset], chunk_size, MPI_BYTE, rank + 1, 1, MPI_COMM_WORLD); *** 
     offset = offset + chunk_size; 
     if ((offset + chunk_size) >= NUM_BYTES) { 
      chunk_size = (NUM_BYTES - offset); 
     } 
    } 
} 
else { 
    MPI_Recv(&chunk_size, 1, MPI_INT, rank - 1, 3, MPI_COMM_WORLD, &status); 
    MPI_Recv(&offset, 1, MPI_INT, rank - 1, 2, MPI_COMM_WORLD, &status); 
    MPI_Recv(&buffer[offset], chunk_size, MPI_BYTE, rank - 1, 1, MPI_COMM_WORLD, &status); 
    if (rank != num_procs - 1) { 
     MPI_Send(&chunk_size, 1, MPI_INT, rank + 1, 3, MPI_COMM_WORLD); 
     MPI_Send(&offset, 1, MPI_INT, rank + 1, 2, MPI_COMM_WORLD); 
     MPI_Send(&buffer[offset], chunk_size, MPI_BYTE, rank + 1, 1, MPI_COMM_WORLD); 
    } 
} 
+2

只需要说一句:由于MPI保留了给定通信器内两个进程之间发送的具有相同标签的消息的时间顺序,因此实际上并不需要发送偏移量。只需保留一个计数器并每次使用所收到的数据量增加计数器。而且,发送块大小是多余的,因为您可以简单地使用'MPI_Probe'来探测消息,'MPI_Get_count'可以获得[探测到的]消息中元素的数量。 –

回答

3

的代码看起来不错(虽然不是很有效,因为所有通信都是序列化),但你有一个很大的小姐:只有流程#0循环通信,从而它将发送多次,而所有其他进程只会期望一组通信。在else部分中添加相同的while循环,这应该起作用。

+0

谢谢!我能够通过添加您建议的while循环来修复我的问题,并且通过调整它来检查((offset + chunk_size) iltp38