2012-12-06 4 views
0

필자는 정말 기괴한 일을하는 MPI와 병렬 처리하는 포트란 코드를 가지고 있습니다. mpi는 변수를 변경하지 않습니다.

call mpi_bcast(nstartg,1,mpi_integer,0,mpi_comm_world,ierr) 

변수 nstartg

프로그램에서 다시 변경되지 않습니다 : 첫째, 보스 과정에서 모든 노동자들에게 방송 변수 nstartg이있다. 나중에, 나는 보스 프로세스가 근로자에 ​​배열 edgeeproc 요소를 보내 : me 제로가 아닌 경우 매칭

if (me==0) then 
    do n=1,ntasks-1 
     (determine the starting point estart and the number eproc 
     of values to send) 
     call mpi_send(edge(estart),eproc,mpi_integer,n,n,mpi_comm_world,ierr) 
    enddo 
endif 

문을받을 수 있습니다. (난 다른 가독성을 위해 다른 코드를 생략 했으므로 scatterv를 사용하지 않는 것이 좋은 이유가 있습니다.) nstartg은 실제 값을 유지하는 대신 n으로 변경됩니다. 예를 들어, 프로세스 1에서 mpi_recv, nstartg = 1 다음에 프로세스 2에서 2와 같게됩니다. 제가

call mpi_send(edge(estart),eproc,mpi_integer,n,n+1234567,mpi_comm_world,ierr) 

위의 코드를 변경하고, 매칭 호에 따라 태그를 변경하는 경우 또한, 다음 공정 (1)에, mpi_recv하려면 nstartg = 1,234,568; 프로세스 2에서 nstartg = 1234569 등

지구상에서 무슨 일이 벌어지고 있습니까? 변경된 것은 mpi_send/recv가 메시지를 식별하는 데 사용하는 태그입니다. 태그가 겹쳐지지 않도록 태그가 고유해야합니다.이 태그는 아무 것도 변경해서는 안되며, 전혀 관련이없는 변수를 변경합니다.

보스 프로세스에서 nstartg은 변경되지 않으므로 다시 방송하여이 문제를 해결할 수 있지만 실제 솔루션은 아닙니다. 마지막으로, 전기 울타리를 사용하여이 코드를 컴파일하고 실행하면 버퍼 오버 플로우가 발생하지 않았으며 -fbounds-check가 나에게 아무 것도 던지지 않았 음을 언급해야합니다.

+1

이 동작을 재현하는 코드의 가장 간결한 버전을 게시 할 수 있습니까? – milancurcic

+0

eproc에서 제공하는 정수의 개수가 맞습니까? – haraldkl

답변

5

가장 가능한 원인은 정말 구현에 특정 크기와 배열로 선언해야 할 때 사용할 수 MPI_RECV의 실제 status 인수로 INTEGER 스칼라을 통과한다는 것이다 MPI_STATUS_SIZE 상수 :

INTEGER, DIMENSION(MPI_STATUS_SIZE) :: status 

또는

메시지 태그가 수신 동작에 의해 상태 필드 중 하나에 기록된다
INTEGER status(MPI_STATUS_SIZE) 

는 (구현 특정 인덱스로 사용할상수 및 필드 값은 status(MPI_TAG)으로 액세스 할 수 있습니다. status이 단순히 스칼라 INTEGER 인 경우 다른 여러 로컬 변수를 덮어 쓰게됩니다. 귀하의 경우에는 단순히 nstartg가 스택에 status 바로 위에 오도록 발생합니다.

수신 상태에 신경 쓰지 않는다면 특수 상수 MPI_STATUS_IGNORE을 대신 전달할 수 있습니다.

+0

'mpi_status_ignore'를 사용하여 고쳐주었습니다. – korrok