2013-07-11 2 views
1

OpenMP 및 Portland Group 컴파일러를 사용하여 포트란 프로그램에서 이름 목록을 읽는 동안 문제가 발생했습니다.PGI, OpenMP 및 namelist in Fortran

내가하려는 것은 간단합니다. 영역에서 read_namelist 서브 루틴을 호출합니다. 여기에서 이름 목록에서 읽으려는 매개 변수를 초기화 한 다음 이름 목록을 열고 읽거나 닫습니다. namelist에서 읽는 매개 변수는 threadprivate이며, 읽은 후에 다른 스레드로 퍼트립니다.

GNU 및 인텔 컴파일러에서 완벽하게 작동하지만 PGI에서는 실패하고 그 이유는 알 수 없습니다. 오류는 없지만 읽기 매개 변수는 이름 목록에서 읽은 매개 변수가 아닌 기본 매개 변수와 같습니다.

program read_input 
    !$ use OMP_LIB 
    use params 
    implicit none 

    integer :: rank=0, nthreads=1 

    !$OMP PARALLEL DEFAULT(PRIVATE) 
    !$ rank = OMP_GET_THREAD_NUM() 
    !$ nthreads = OMP_GET_NUM_THREADS() 
    !$OMP SINGLE 
    print*, 'There is ', nthreads, ' threads running' 

    call read_nml 
    !$OMP END SINGLE COPYPRIVATE(nx, ny, nz) 

    print*, 'Rank: ', rank 
    print*, 'nx, ny, nz: ', nx, ny, nz 
    !$OMP END PARALLEL 

contains 
    subroutine read_nml 
    use params 
    implicit none 
    namelist /input_params/ nx, ny, nz 

    call default_parameters 
    print*, 'nx, ny, nz (default): ', nx, ny, nz 

    open(unit=1, file='input', status='old') 
    read(1, input_params) 
    close(1) 
    print*, 'nx, ny, nz (read): ', nx, ny, nz 

    return 
    end subroutine read_nml 

    subroutine default_parameters 
    use params 
    implicit none 

    nx = 2; ny = 2; nz = 2 

    return 
    end subroutine default_parameters 
end program read_input 

모듈 params은 매우 간단에만 포함되어 있습니다 : 여기

은 내가 뭘하려고 오전의 예입니다

module params 
    integer :: nx, ny, nz 
    !$OMP THREADPRIVATE(nx, ny, nz) 
end module params 

pgfortran로 컴파일, 여기에 내가 얻을 출력 (스레드 2 개 포함) :

Start program: read_input 
There is    2 threads running 
nx, ny, nz (default):    2   2   2 
Rank:    0 
nx, ny, nz:    2   2   2 
Rank:    1 
nx, ny, nz:    2   2   2 

그리고 동일한 코드를 Intel (2 개 스레드 여전히) GNU 컴파일러는 :

Start program: read_input 
There is   2 threads running 
nx, ny, nz (default):   2   2   2 
nx, ny, nz (read):   10   10   10 
Rank:   0 
nx, ny, nz:   10   10   10 
Rank:   1 
nx, ny, nz:   10   10   10 

어떤 생각이나 힌트 이해할 수있을 것이다!

+0

오류 메시지가 무엇입니까? – milancurcic

+0

죄송합니다, 정확한 것을 잊었습니다. 내 문제를 명확히하기 위해 예제를 추가했습니다. – MBR

답변

0

정확한 이유는 없지만 적어도 코드를 사용하여 해결 방법을 찾았습니다.

네임리스트에서 읽은 매개 변수가 서브 루틴에서 비공개 인 경우 아무 문제없이 읽을 수 있습니다. 따라서 잘

subroutine read_nml(nx, ny, nz) 
    implicit none 
    integer :: nx, ny, nz    
    namelist /input_params/ nx, ny, nz 

    call default_parameters 
    print*, 'nx, ny, nz (default): ', nx, ny, nz 

    open(unit=1, file='input', status='old') 
    read(1, input_params) 
    close(1) 
    print*, 'nx, ny, nz (read): ', nx, ny, nz 

    return 
    end subroutine read_nml 

의해

call read_nml(nx, ny, nz) 

서브 루틴 read_nml 의해

call read_nml 

공사를 교체. 나는 다시 한번 속성의 상태 (개인) 문제라고 생각하지만, 인텔과 GNU 컴파일러가 문제없이 처리 한 이유는 모르지만 PGI 컴파일러는이를 처리 할 수 ​​없다. 사실, 이런 종류의 동작을 막기 위해 매개 변수가 내 모듈에서 스레드 개인적인 이유입니다. 누군가 내가 가지고있는 것보다 더 나은 대답을 줄 수 있다면, 나는 여전히 관심이있다!