Какая директива OpenACC укажет компилятору выполнить инструкцию только на устройстве?

Я изучаю OpenACC с помощью Fortran (с набором инструментов от Nvidia) и делаю это, портируя свою реализацию решателя Conjugate Gradient (CG) на графические процессоры.

Ясно, что я пытаюсь сохранить как можно больше данных на устройстве (памяти графического процессора) с помощью следующих команд:

27   ! Copy matrix (a_sparse), vectors (ax - b) and scalars (alpha - pap) to GPU                                     
28   !$acc enter data copyin(a_sparse)                                             
29   !$acc enter data copyin(a_sparse % row(:))                                    
30   !$acc enter data copyin(a_sparse % col(:))                                    
31   !$acc enter data copyin(a_sparse % val(:))                                    
32   !$acc enter data copyin(ax(:), ap(:), x(:), p(:), r(:), b(:))                                   
33   !$acc enter data copyin(alpha, beta, rho, rho_old, pap)                       

С этого момента все операции, составляющие алгоритм решения решающей программы CG, выполняются с помощью предложения present. Для операции vector отрывок выглядит так:

49   !$acc  parallel loop      &                                                   
50   !$acc& present(r, b, ax)                                                      
51   do i = 1, n                                                                   
52     r(i) = b(i) - ax(i)                                                         
53   end do                                                                        

Я делаю то же самое с скалярами, например:

87     !$acc kernels present(alpha, rho, pap)                                      
88     alpha = rho / pap                                                           
89     !$acc end kernels                                                           

Все скалярные переменные находятся на устройстве. В строках 87-89 я пытаюсь выполнить команду alpha = rho / pap только на устройстве, избегая передачи данных с или на хост, но профилировщик nsight-sys показывает мне следующее:

введите описание изображения здесь

К моему удивлению, похоже, что в строке 87 происходит передача данных, как до (красный квадрат Enter Data), так и после (красный квадрат Exit Data) вычислительной конструкции (синий Cg.f90: 87 квадрат).

Может ли кто-нибудь сказать мне, что происходит? Строки 87-89 выполняются на устройстве? Более того, почему нет соответствующих команд CUDA для этих полей Enter Data и Exit Data? Если да, то почему кажется, что между хостом и устройством происходит передача данных? Если нет, существует ли команда OpenACC, которая заставит компилятор выполнить строку программирования, которая не обязательно является циклом, только на устройстве?

Я заметил то же самое для операций с массивами, таких как те, которые я написал выше в строках 49-53, там тоже есть некоторая передача данных, но я мог бы отнести это к переменной n, которая должна быть передана на устройство.


person Bojan Niceno    schedule 04.10.2020    source источник


Ответы (1)


Это могло несколько вещей. Fortran указывает, что правая часть операции синтаксиса массива должна быть полностью оценена перед назначением левой стороне, поэтому компилятор может выделить временный массив для хранения результата оценки. Хотя часто компилятор может оптимизировать потребность во временном режиме, поэтому это может быть или не быть проблемой. Попробуйте сделать этот цикл явным, а не использовать синтаксис массива, чтобы увидеть, решает ли он проблему.

Вторая возможность заключается в том, что компилятору нужно скопировать дескрипторы массива, поскольку он не может определить, изменились они или нет. Хотя я ожидал увидеть некоторое движение данных, а не только регионы входа / выхода.

Третья возможность заключается в том, что это просто проверка на текущий момент, которая по-прежнему вызывает вызовы времени выполнения входа / выхода. Вместо копирования данных вызов ищет указатель устройства, который позже передается вызову ядра, и счетчик ссылок увеличивается / уменьшается.

person Mat Colgrove    schedule 05.10.2020