2012-06-20 5 views
0

제 문제는 Fortran에서 mpi 체계를 사용할 때 어떻게 서브 루틴을 호출해야할지 모르겠다는 것입니다. TRC.f90이라는 작은 코드에 CONCENTRATION.f90이라는 서브 루틴이 있습니다. 코드를 작동 시키려면 어떻게 CONCENTRATION.f90을 변경해야합니까? 나는 서브 루틴 CONCENTRATION.f90에 대한 몇 가지 변경 한해야한다고 생각하기 때문에 코드는 현재 나에게 오류를 제공MPI로 병렬화 된 포트란에서 서브 루틴을 호출하는 방법은 무엇입니까?

SUBROUTINE CONCENTRATION(GRIDX, GRIDY, NUM_PROCS, MY_ID , PSI) 
implicit none 

INTEGER*8, INTENT(IN)    :: GRIDX, GRIDY 
INTEGER , INTENT(IN)    :: NUM_PROCS, MY_ID 
REAL*8 , DIMENSION(GRIDX,GRIDY), INTENT(OUT) :: PSI 
INTEGER*8       I, J 

DO I=1+MY_ID*GRIDX/NUM_PROCS, (MY_ID+1)*GRIDX/NUM_PROCS 
    DO J=1,GRIDY 
     PSI(I,J)=2.0 
    END DO 
END DO 

END SUBROUTINE CONCENTRATION 

:

PROGRAM TRY 
USE MPI 

integer status(mpi_status_size) 
INTEGER     I, J, K, II, IERR, MY_ID, NUM_PROCS, PSP 
INTEGER , PARAMETER    :: GRIDX =64, GRIDY=64 
REAL , DIMENSION(gridx,gridy) :: PSI 
PSI=0 
PRINT*, 'VARIABLE' 

CALL MPI_INIT(IERR) 
CALL MPI_COMM_RANK(MPI_COMM_WORLD,MY_ID,IERR) 
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NUM_PROCS,IERR) 

CALL CONCENTRATION(GRIDX, GRIDY, NUM_PROCS, MY_ID , PSI) 

IF (MY_ID .NE. 0) THEN 
    CALL mpi_send(PSI(1+MY_ID*GRIDX/NUM_PROCS:(MY_ID+1)*GRIDX/NUM_PROCS:1,1:GRIDY:1),& 
    (GRIDX/NUM_PROCS)*GRIDY,mpi_real, 0,10,mpi_comm_world,ierr) 
END IF 
IF (MY_ID .EQ. 0) THEN 
    DO II=1,NUM_PROCS-1 
     CALL mpi_recv(PSI(1+II*GRIDX/NUM_PROCS:(II+1)*GRIDX/NUM_PROCS:1,1:GRIDY:1),& 
     (GRIDX/NUM_PROCS)*GRIDY,mpi_real, & 
     II,10,mpi_comm_world,status,ierr) 
    END DO 
END IF 

CALL MPI_FINALIZE(IERR) 
END PROGRAM TRY 

I는 CONCENTRATION.f90라는 이름의 서브 루틴을 사용하고 있습니다. 또는 서브 루틴이라고 부르는 방식을 변경해야합니다.

변경 사항은 무엇입니까? 사전에 도움을 주셔서 감사합니다

+0

무엇이 오류입니까? – wallyk

+0

mpirun은 노드 Goodin의 PID 9249가있는 프로세스 순위 0이 신호 11 (세그먼트 오류)에서 나왔다는 것을 알았습니다. 그러나 mpi 구성표를 제거한 다음 gfortran 컴파일러를 적용하면 모든 것이 올바르게 작동합니다. – user1464558

+0

"MPI 체계"란 무엇을 의미합니까? –

답변

-1

유일한 변경은 concentrationreentrant으로 선언하는 것입니다. 이것은 Fortran 90의 기본값 일 수 있습니다. (경험치의 대부분은 F77이며 reentrant은 기본값이 아닙니다.)

+0

더 자세히 설명해 주시겠습니까? – user1464558

+2

재진입 성은 다중 쓰레드 환경에서 재귀 적이지도 않고 사용되지 않는 서브 루틴과 관련이 있습니까? –

2

프로그램이 유형 불일치로 인해 세분화됩니다. 메인 프로그램에서는 REAL의 배열로 PSI를 선언 한 :

REAL , DIMENSION(gridx,gridy) :: PSI 

CONCENTRATION 서브 루틴에 당신은 REAL*8의 또 다른 유형 사용하는 동안 (REAL*8 동안 4 바이트 기본 REAL으로

REAL*8 , DIMENSION(GRIDX,GRIDY), INTENT(OUT) :: PSI 

인을 또는 DOUBLE PRECISION 또는 REAL(KIND=8))는 8 바이트 길이입니다. 따라서 CONCENTRATION에 2 배 더 작은 배열이 있다고 가정하고 NUM_PROCS/2의 모든 순위는 PSI 배열의 끝을 지나서 쓰므로 segfault가 발생합니다. 한 프로세스 만 실행하면 순위 0조차도 segfault가됩니다.

또한 MPI 집단 작업에 대해서도 읽어야합니다. MPI_GATHERMPI_GATHERV 정확히 여기에 여러 송수신을 달성하기 위해 노력하고 있습니다.

+0

고마워요. 당신 말이 맞아요. 자, 코드가 잘 작동합니다. 그러나 놀랍게도 코드는 프로세서의 수만큼 '가변'을 인쇄합니다! 4 개의 프로세서를 사용하여 4 번 인쇄합니다. mpi_init() 전에 "print *, 'variable'"을 입력했기 때문에 이것은 놀랍습니다. – user1464558

+0

'mpirun'은'MPI_INIT'를 호출하기 전에도 I/O 리디렉션을 수행합니다. 'mpirun -np 4 hostname'을 실행하여 비 MPI 프로그램에서도 작동하는지보십시오. –