2017-11-20 8 views
0

저는 포트란과 함께 mpi를 배우고 있습니다. 나는 다음과 같은 간단한 코드를 작성했다.mpi_recv mpi_send에서 보낸 데이터의 절반 만 수신합니까? 매우 혼란 스럽네요

program arraypractice 
use mpi 
    integer pid, np, ierr, arraysize, i,msg, status(mpi_status_size)  
    integer dcount 
    real*8 f(10), f1(10) 

    call mpi_init(ierr) 
    call mpi_comm_size(mpi_comm_world, np, ierr) 
    call mpi_comm_rank(mpi_comm_world, pid, ierr) 

    if(pid==0) then 
      do i = 1, 10 
      f(i)=float(i) 
      enddo 
    endif 

     msg = 1 

    if(pid==0) then 
     call mpi_send(f(1),6,mpi_real,1,msg,mpi_comm_world,ierr) 
    endif 

    if(pid==1) then 
     call mpi_recv(f1(1),6,mpi_real,0,msg,mpi_comm_world,status,ierr) 

     call mpi_get_count(status,mpi_real,dcount,ierr) 
     print *,dcount 
     do i= 1, 6 
      print *,f1(i) 
     enddo 
    endif 

    call mpi_finalize(ierr) 
end 

나는 아치 리눅스 내 I5 듀얼 코어 노트북에 명령 "의 a.out에 mpirun -n 2"를 사용하여 실행 한 후 "mpif90"명령을 사용하여 코드를 컴파일하고있다. 내 결과는 다음과 같습니다.

  6 
    1.0000000000000000  
    2.0000000000000000  
    3.0000000000000000  
    0.0000000000000000  
    0.0000000000000000  
    0.0000000000000000 

마지막 3 개의 숫자가 업데이트되지 않는 이유에 대해 완전히 혼란 스럽습니다. mpi_recv가 mpi_send가 보내는 데이터의 절반 만 수신 할 때마다. 나는 출력이

  6 
    1.0000000000000000  
    2.0000000000000000  
    3.0000000000000000  
    4.0000000000000000  
    5.0000000000000000  
    6.0000000000000000 

어떤 도움이 정말 감사하겠습니다 될 것으로 기대한다.

답변

2

배열 요소의 유형과 사용자가 MPI 호출에 제공 한 데이터 유형간에 유형 불일치가 있습니다. real*8은 64 비트 배정도 숫자를 나타내며 MPI_REAL은 (일반적으로) 32 비트 단 정밀도 유형 real에 해당합니다. 따라서 MPI는 데이터의 첫 번째 절반 만 보냅니다.

중 하나는 단 정밀도를 사용하거나 MPI_DOUBLE_PRECISION 또는 MPI_REAL8MPI_REAL을 대체 할 real*8*8 제거. 두 번째 MPI 데이터 유형 (MPI_REAL8)은 선택 사항이며 일부 MPI 라이브러리에서 사용하지 못할 수도 있습니다.

+0

감사합니다. 그것은 나를 위해 문제를 해결했다. –

+2

또한 실제 * 8은 표준 포트란이 아니며 Fortran 표준이 아니 었습니다. 나는 당신이 친절한 메커니즘에 대해 알 것을 강력히 권합니다. –

-2

또한 MPI는 Fortran 77 및 C에서만 작동한다는 점에 유의해야합니다. Fortran 90 (또는 이상) 또는 C++에서 작동한다는 보장은 없습니다. MPI는 일반 라이브러리와 같지 않습니다. 메모리 레이아웃을 직접적으로 망쳐 놓고 MPI 호출과 관련이없는 로컬 변수를 덮어 쓸 수 있습니다. 예를 들어 로컬 변수가 integer i이므로 MPI 내에서 충돌이 발생했습니다. 이 변수는 MPI에 대한 호출에서 아무런 역할을하지 못했습니다. 내가 integer, save :: i (스택에 없으므로)에서 모든 것을 작동 시켰습니다!

+0

올바르지 않습니다. http://mpi-forum.org/docs/mpi-3.0/mpi30-report.pdf 섹션 2.6.2 "Fortran"이라는 용어가 사용되면 Fortran 90 또는 그 이후 버전을 의미합니다. C++ 지원도 게시되었지만 이제는 더 이상 사용되지 않습니다. –

+0

이것은 완전히 잘못되었습니다. 프로그램이 스택 레이아웃으로 인해 동작을 변경하면 스택 손상의 명백한 징후입니다. 모든 서브 루틴 및 함수 인수, 특히 유형 및 종류의 정확성을 점검하십시오. 이것은 일반적인 유형의 오류이며 MPI 내부 기능과는 아무런 관련이 없으며 코드의 정확성 만 있습니다. 분명히 mpi 모듈은 Fortran 77에 모듈이 없기 때문에 Fortran 90 용 모듈이어야합니다. 분명히 mpi_f08 모듈은 Fortran 2008 용 모듈입니다. MPI는 Fortran 2008조차도 지원합니다. –