在编译时使用未知大小的私有数组进行 OpenMP 卸载

OpenMP Offloading with Private Arrays of Unknown Size at Compile Time

我正在尝试使用 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

使用这种标准方法,我遇到了很多内存问题,在 "out of memory errors" 和 "an illegal memory access was encountered"

之间变化

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

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

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

我尝试过 OMP_HEAPSIZE 和 OMP_STACKSIZE 等 ENV 变量,但没有成功。

感谢观看!

这原来是一个编译器 quirk/bug,带有我使用的 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