Я изучаю 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
, которая должна быть передана на устройство.