首页 > 解决方案 > 在编译时使用未知大小的私有数组卸载 OpenMP

问题描述

我正在尝试使用 OpenMP、XL 编译器套件卸载 fortran 中的几个嵌套 for 循环。90% 的例程是直截了当的,但少数循环涉及私有一维数组,这些数组在编译时大小未知,但总是在 ~O(10) 上,这在线程堆栈内存方面非常易于管理。这是一个示例循环

implicit none
real, dimension(1:nseq) :: yy    !nseq is a global variable, usually 1-10, 

!$omp target teams distribute parallel do collapse(3) schedule (static,1) &
!$omp& private(i, j, k) &
!$omp& private( yy )&
!omp& shared( ne )
do k=1,30
do j=1,30
do i=1,30

 yy = dummy_array(i,j,k,6:ne)  ! nseq is equal to ne-6... ne is a global variable
                               ! dummy_array is an allocatable array that exists persistently on 
                               ! the GPU
  ...    
  do stuff with yy
  ...
end do
end do
end do

使用这种标准方法,我会遇到很多内存问题,在“内存不足错误”和“遇到非法内存访问”之间变化

如果我进去硬编码,我知道 nseq 的值将提前,即

implicit none
real, dimension(1:10) :: yy

然后我完全没有问题,所以我实际上并没有在 GPU 上耗尽内存。这显然是不好的做法,因为这些值会因情况而异,并且是运行时参数。

我已经尝试过诸如 OMP_HEAPSIZE 和 OMP_STACKSIZE 之类的 ENV 变量,但没有成功。

谢谢参观!

标签: fortranopenmpoffloadingxl-fortran

解决方案


事实证明,这是我使用的 IBM XL 编译器套件的编译器怪癖/错误。

一种不太理想但有效的解决方法是手动将临时数组私有化,即

real, dimension(30,30,30,1:nseq) :: yy

!$omp target teams distribute parallel do collapse(3) schedule (static,1) &
!$omp& private(i, j, k) &
!$omp& private( yy )&
!omp& shared( ne )
do k=1,30
do j=1,30
do i=1,30

 yy(i,j,k,:) = dummy_array(i,j,k,6:ne)  

  ...    
  do stuff with yy
  ...
end do
end do
end do

推荐阅读