2017-10-30 4 views
0

각 줄에 포함 된 데이터를 기반으로 더 작은 크기의 여러 파일에 쓸 필요가있는 큰 데이터 파일이 있습니다. 이 문제를 해결하기 위해 병렬 포트란 코드를 작성하려고합니다. Fortran OpenMP에서`Fortran 런타임 오류 : 파일이 이미 다른 장치에서 열림`

은 큰 파일

1 
    1 
    2 
    3 
    1 
    4 

의 본질이며, 그래서 다른로, 하나 개의 파일에 2 's의 모든 1들 쓰고 싶어요.

내가 준수하고 여기 어떻게 그 문제를 해결하는 어떤 문제가 있는지 설명해주십시오 수있는 오류

At line 12 of file partest.f95 (unit = 11) 
    Fortran runtime error: File already opened in another unit. 

을 제공 실행하면 내가

 program partest 
    use omp_lib 
    character*13 fn 
    !$OMP PARALLEL private(fn) 
    !$OMP DO 
    do i=1,1000 
     ii=10+omp_get_thread_num() 
     jj=20+omp_get_thread_num() 
     open(unit=ii,file='data.dat',status='old') 
     write(fn,'(a,i4.4,a)') "file",i,'.dat' 
     open(unit=jj,file=fn,status='unknown') 
     do il=1,50000 
      read(ii,*) j 
      if (j .eq. i) then 
      write(jj,*) j 
      end if 
     end do 
     close(unit=ii) 
     close(unit=jj) 
    end do 
    !$OMP END DO 
    !$OMP END PARALLEL 
    stop 
    end 

을 시도하는 코드입니다. 작업을 수행하는 일련 번호는 내가 (말 4 개 프로세서에서 실행 경우) 다중 출력 파일을 동시에 여러 프로세서에 의해 생성되도록이 코드 평행하고 싶습니다

program partest 
    character*13 fn 
    do i=1,1000 
     open(unit=10,file='data.dat',status='old') 
     write(fn,'(a,i4.4,a)') "file",i,'.dat' 
     open(unit=11,file=fn,status='unknown') 
     do il=1,50000 
      read(10,*) j 
      if (j .eq. i) then 
      write(11,*) j 
      end if 
     end do 
     close(unit=10) 
     close(unit=11) 
    end do 
    stop 
    end 

입니다. 데이터 (입력) 파일을 다른 프로세서에 관계없이 각 프로세서가 독립적으로 읽을 수 있기를 바랍니다. 감사.

+0

환영합니다. 귀하의 코드는 MPI가 아니라 OpenMP입니다. OpenMP와 MPI는 두 가지 ** 완전히 다른 ** 것들입니다. 환영받은 [투어]를 읽고 [질문]을 읽으십시오. –

+1

오류를 수정 한 후에도 이런 식으로 병렬 읽기 및 쓰기를 수행 할 필요가 없습니다. 아주 특별하고 값 비싼 병렬 하드웨어와 파일 시스템을 가지고 있지 않다면, 프로그램을 더 빨리 만들지 않을 것입니다. –

+0

업데이트에 관해서, 내 대답을 읽었습니까? 이해 했니? 너 뭔가 빠졌어? 뭐? 이러한 변수를 비공개로 만들려면 절대적으로 필요합니다. –

답변

1

private이 되려면 여러 변수가 필요합니다. 여러 스레드가 동시에 동일한 변수를 쓰고 읽을 때 현재 경쟁 조건이 있습니다. 이 변수는 ii, jj, j입니다. 어쩌면 더.

오류 메시지는 같은 장치 번호가 두 번있는 파일을 열 때 발생합니다.

는 대신 unit=의 포트란 2008 newunit= 지정을 사용할 수 있습니다 그리고 당신은

ii=10+omp_get_thread_num() 
    jj=20+omp_get_thread_num() 

하지만 여전히 iijjprivate해야 문제가있는 계산을 제거 할 수 있습니다.

내가 주석을 달았으므로 코드를 이와 같이 평행하게 만들 가치는 없습니다. 더 빠를 것입니다. 자세한 질문은 아래의 주석을 참조하십시오.

+0

'ii = i'와'jj = i + 1000'을 시도하십시오. –

+0

'newunit'이 더 좋다고 생각합니다. OP의 컴파일러가 threadsafe를 구현하는지 잘 모르겠지만. 그러나 Clerman과 Spector의 책에 따르면 그것은 괜찮을 것이다. 나는 100 % 확실하지 않다. –

+0

'newunit'이 가능하다면 동의합니다. 그러면 첫 번째 선택이되어야합니다. 그렇지 않으면 변형은'jj = ii + omp_get_num_threads()'입니다. 어떤 경우에도 이러한 vrariables는 반드시 개인용이어야합니다. –