2

我正在使用 openmp 并行运行以下 fortran 代码,但只有一个处理器在工作。我在代码中添加了一些执行例程,如OMP_SET_NUM_THREADSOMP_GET_NUM_THREADS以遵循并行处理。这是代码的相关部分:

integer a,b,omp_get_num_procs,omp_get_max_threads,
& omp_get_num_threads
open( unit=10 , file='threads' , status='new' )
a=4
call omp_set_num_threads(a)
write(10,*) 'num_proc=',omp_get_num_procs()
write(10,*) 'max_threads=',omp_get_max_threads()
write(10,*) 'num_threads=',omp_get_num_threads()

open( unit=7 , file='result' , status='new' )
!$OMP PARALLEL NUM_THREADS(4)
!$OMP DO DEFAULT(PRIVATE) Shared(rho1,rho2,Vnuc)
 do i = 1 , nx
    do j = 1 , ny
      do k = 1 , nz
         b = omp_get_num_threads()
         write(*,*) 'Hello'
         Write(10,*) 'Hello'
         Write(10,*) b
         write(10,100) omp_in_parallel()
100   format(l2)
...
    enddo
  enddo
enddo
!$OMP END DO
!$OMP END PARALLEL

或者替代我添加的标题中的 omp 参数的一一定义

include 'omp_lib.h'

结果如下:

 num_proc=           8
 max_threads=           4
 num_threads=           1
 Hello
       1
 T
 Hello
       1
 F
 Hello
       1
 F
 Hello
       1
 F
 Hello
       1
 F

它继续这样。它正在运行,但仅使用一个处理器。谁能帮我?

4

2 回答 2

3

Fortran 默认使用隐式类型,这意味着以 开头的未声明变量/函数(a-h,o-z)是真实的。您的解决方案是添加正确类型的运行时例程,例如:

integer omp_get_num_threads

或者,更好的是,implicit none在开头添加以停用隐式类型,然后包含头文件:

implicit none
include 'omp_lib.h'

编辑:

并行区域之外的线程数是 1 很好,但是,在并行区域中它确实应该是 4。您可能正在混合固定格式和自由格式,前者需要 omp 指令(例如C$OMP)在一行的开头(在第 1 列),如下所示:

      program test
      include 'omp_lib.h'
      write(*,*) 'num_proc =    ',omp_get_num_procs()
      write(*,*) 'max_threads = ',omp_get_max_threads()
      write(*,*) 'num_threads = ',omp_get_num_threads()
C$OMP PARALLEL DO
      do i=1,4
        write(*,*) 'num_threads = ',omp_get_num_threads()
      end do
      end

如果您使用的是自由格式,那么您可以!$OMP在一行中的任何位置使用。棘手的是,大多数编译器!即使在固定格式的源代码中也允许注释语句,但是 openmp 指令仅在注释位于开头时才起作用。

于 2013-11-06T09:32:45.763 回答
2

失踪者旁边

use omp_lib

您是否使用 OpenMP 标志编译了您的程序?如果没有,对于 gfortran 它是例如

-fopenmp

编辑:这可能是测试您的问题的最简单的程序:

program prog
  use omp_lib
  implicit none

  integer :: i, tnr

  call omp_set_num_threads( 4 ) !number of threats used in the parallel environment

  !$omp parallel private( i )
    !$omp do
      do i = 1, 20
        tnr = omp_get_thread_num()  ! get threat number
        write( *, * ) 'Thread', tnr, ':',  i
      end do
    !$omp end do
  !$omp end parallel
end program prog

请使用例如 gfortran 编译它,例如:

gfortran -fopenmp prog.f90 -o prog

它应该打印你的行,如:

 Thread           3 :          11

这里,3 是威胁数。如果您的处理器有多个内核并且您完全安装了编译器,那么这应该可以工作。

于 2013-11-06T13:41:58.610 回答