Разгрузка OpenMP с частными массивами неизвестного размера во время компиляции
Я пытаюсь разгрузить несколько вложенных циклов for в fortran с помощью компилятора OpenMP, XL. 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. Очевидно, что это плохая практика, поскольку эти значения меняются от случая к случаю и являются параметрами времени выполнения.
Я безуспешно экспериментировал с переменными ENV, такими как OMP_HEAPSIZE и OMP_STACKSIZE.
Спасибо, что заглянули!
1 ответ
Оказывается, это причуда / ошибка компилятора с набором компиляторов 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