fortran - 以编程方式禁用 OpenMP 中的嵌套并行性
问题描述
我面临与此处描述的相同的请求,即我想在第一个子例程中并行化一个“内部”循环,该循环可能会或可能不会从另一个子例程中的“外部”并行化循环调用。在嵌套调用的情况下,我想禁用内部并行化,只保留外部并行化。上述链接中提供的解决方案似乎不起作用。这是一个说明性代码:
program test
!$ use omp_lib
!$ write(*,'(A,I0)') "Running OpenMP version ",openmp_version
write (*,'(A)') 'Direct call to basic:'
call basic(1)
write (*,'(A)') 'Iterative call to basic:'
call iterative()
end program test
!
subroutine basic(i)
!$ use omp_lib
integer(kind=4), intent(in) :: i
integer(kind=4) :: j,level
!$ level = OMP_GET_ACTIVE_LEVEL()
!$ write(*,'(A,I0)') " Basic parallelization level is ",level
!$OMP PARALLEL SHARED(i) PRIVATE(j) IF(level<1)
!$OMP DO
do j=1,3
write (*,'(A,2I3,A,I0)') " i,j = ",i,j," done by thread ",omp_get_thread_num()
enddo
!$OMP END DO
!$OMP END PARALLEL
end subroutine basic
!
subroutine iterative()
!$ use omp_lib
integer(kind=4) :: i
!$OMP PARALLEL PRIVATE(i)
!$OMP DO
do i=1,2
write (*,'(2(A,I0))') " Iterative executes iteration ",i," from thread ",omp_get_thread_num()
call basic(i)
enddo
!$OMP END DO
!$OMP END PARALLEL
end subroutine iterative
AFAIU,当调用“迭代”时,我面临嵌套的 OMP 循环。由于此处禁用了 OMP 嵌套,因此“内部”循环预计将由调用线程(并且仅调用线程)执行:这就是我想要的。
不幸的是,当我使用 gfortran 9.2.0 执行代码时,我得到:
> gfortran -fopenmp test.f90 -o test && ./test
Running OpenMP version 201511
Direct call to basic:
Basic parallelization level is 0
i,j = 1 2 done by thread 1
i,j = 1 3 done by thread 2
i,j = 1 1 done by thread 0
Iterative call to basic:
Iterative executes iteration 2 from thread 1
Basic parallelization level is 1
i,j = 2 1 done by thread 0
i,j = 2 2 done by thread 0
i,j = 2 3 done by thread 0
Iterative executes iteration 1 from thread 0
Basic parallelization level is 1
i,j = 1 1 done by thread 0
i,j = 1 2 done by thread 0
i,j = 1 3 done by thread 0
当直接调用“basic”时,它被正确并行化(线程 0、1 和 2)。当调用“迭代”时,它的主循环很好地并行化(线程 0 和 1)。然后我希望每个调用线程(0和1)执行每个“基本”循环。不幸的是,它们都由线程 0 执行!
如果我编辑代码以从“基本”子例程中删除“OMP PARALLEL IF(条件)”子句(但保留“OMP DO”),则“迭代”调用正常工作(但在调用“基本”时我失去了并行化“ 直接地)。换句话说,当“条件”为假时,“OMP PARALLEL IF(条件)”子句的行为就好像它完全不存在一样。
我对 ifort 18.0.3.222、OpenMP 201611 也有同样的问题。
怎么了?
解决方案
推荐阅读
- php - 使用 PHP 循环遍历 JSON 响应中特定元素的内容
- sql - POSTGRES - WHERE IN 中的每个 ID 限制 1 个 DESC
- css - material-ui 卡没有加载 CSS
- python - 在 python 脚本中调用 Ansible 即席命令/剧本
- r - R函数来识别条件在n列中的任何一个中满足x次的情况?
- angular - Angular 8 with Ivy 如何验证它的使用
- sql - SQL返回多于1的值查询
- node.js - ng new 想写入'/Users/USERNAME/.npm/_cacache/index-v5/aa/9a'
- c# - 尽管在逻辑上是第一个,但在 Razor 页面中最后渲染部分
- javascript - 在 React / Redux / MERN-stack 应用程序的开发版本中删除 console.logs