프로그램이 여러 수준에서 오류가 있습니다.
if(comm_rank=root){
이 comm_rank
root
에 비교가 아니라 comm_rank
에 root
를 할당하고 루프 만 root
제로가 아닌 경우 실행하고, 그 이외의 것입니다하지 않습니다 : 우선, 조건에 오류가있다 모든 계급이 처형 할 것이다.
둘째, 루트 프로세스는 데이터가 이미 있으므로 자체로 데이터를 보낼 필요가 없습니다. 그래도 보내고 받기를 원한다고해도 MPI_Send
과 MPI_Recv
은 동일한 버퍼 공간을 인식하므로 올바르지 않습니다. 일부 MPI 구현은 자체 상호 작용을 위해 직접 메모리 복사본을 사용합니다. 즉, 라이브러리는 memcpy()
을 사용하여 메시지를 전송할 수 있습니다. memcpy()
을 중복 버퍼 (동일한 버퍼 사용 포함)와 함께 사용하면 정의되지 않은 동작이 발생합니다.
선형 방송을 구현하는 가장 적절한 방법은 다음과 같습니다
void My_MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
{
int comm_rank, comm_size, i;
MPI_Comm_rank(comm, &comm_rank);
MPI_Comm_size(comm, &comm_size);
if (comm_rank == root)
{
for (i = 0; i < comm_size; i++)
{
if (i != comm_rank)
MPI_Send(buffer, count, datatype, i, 0, comm);
}
}
else
MPI_Recv(buffer, count, datatype, root, 0, comm, MPI_STATUS_IGNORE);
}
교착없이 자신에게 이야기하는 프로세스에 대한 일반적인 방법
은 다음과 같습니다
MPI_Isend
및 MPI_Recv
또는 이들의 조합의 조합을 사용하여 MPI_Send
및 MPI_Irecv
;
- 버퍼 된 송신 사용
MPI_Bsend
;
MPI_Sendrecv
또는 MPI_Sendrecv_replace
을 사용하십시오.
여러 보내는 경우에 잘 MPI_Irecv
및 MPI_Send
작품의 조합은 당신처럼 루프에서 수행됩니다. 예 :
MPI_Request req;
// Start a non-blocking receive
MPI_Irecv(buff2, count, datatype, root, 0, comm, &req);
// Send to everyone
for (i = 0; i < comm_size; i++)
MPI_Send(buff1, count, datatype, i, 0, comm);
// Complete the non-blocking receive
MPI_Wait(&req, MPI_STATUS_IGNORE);
송신 및 수신에 별도의 버퍼를 사용합니다. 아마도 같은 버퍼를 송신과 수신에 모두 사용할 수있게하는 점대 점 MPI 통신 호출은 집합 MPI 호출의 내부 모드뿐만 아니라 MPI_Sendrecv_replace
일 것입니다. 그러나 이들은 내부적으로 구현되어 같은 시간에 동일한 메모리 영역이 송수신 용으로 사용될 수 없습니다.
내 컴퓨터에서 정상적으로 작동합니다. 포인터/주소를 섞지 않았습니까? – Sleepyhead
@Sleepyhead, 큰 '카운트'로 시도해보십시오. 작은 메시지는 일반적으로 버퍼링되거나 열정적 인 프로토콜을 사용하여 전송됩니다. –