PGI Accelerator и OpenACC

Компиляция Запуск

Компиляторы PGI (pgcc/pgCC/pgf77/pgfortran) позволяют создавать приложения для запуска на GPU (см. [1-3]). Поддержка стандарта OpenACC [4] добавлена в 2012 году с версии 12.6 (см. [5]; в частности, о переходе на OpenACC в [6]). Приложения могут быть запущены на узлах с графическими ускорителями кластера "Уран" (umt).

Настроиться на компиляторы PGI можно с помощью команды mpiset (на текущую рабочую версию)

mpiset 7

или, загрузив модуль с нужной версией, с помощью команды module. Например, в начале сеанса

module switch mpi/default mvapich2/pgi_12.10

Для компиляции тогда можно использовать, например, команду pgcc или mpicc

mpicc -o exam_pgi exam.c  -ta=nvidia -Minfo=accel -fast

где опция -ta=nvidia подключает компиляцию на GPU, а необязательная опция -Minfo=accel служит для выдачи дополнительной информации о генерации кода для GPU (accelerator kernel). Для версий компилятора с поддержкой OpenACC можно вместо опции -ta=nvidia использовать опцию -acc.

Опция -ta=nvidia,time (где time - подопция) используется для выдачи времени, потраченного на инициализацию GPU (init), перемещение данных (data) и вычисления на GPU (kernels).

Использование же -ta=nvidia,host задаст генерацию единого кода для host (CPU) и GPU: при наличии GPU программа будет выполняться на GPU, иначе на host. Например,

mpicc -o exam_gh exam.c  -ta=nvidia,host -Minfo

Можно узнать, выполняется ли программа на GPU, если установить переменную окружения ACC_NOTIFY в 1

export ACC_NOTIFY=1 

и запустить программу. При каждом вызове функции GPU (kernel) будет выдаваться сообщение вида

launch kernel  file=... 

что полезно при разработке и отладке программы.

Примеры C и Fortran программ есть на umt, например в каталоге

/opt/pgi/linux86-64/11.1/EXAMPLES/accelerator

и рассматриваются в [2].

Замечания.

  1. Помните, что в С, по умолчанию, все константы с плавающей точкой имеют тип double. Поэтому в [2, First Program] для вычислений с одинарной точностью используется 2.0f вместо 2.0.
  2. Для безопасного распараллеливания в С программах (см. [2]) объявления указателей, ссылающихся на распределенную с помощью malloc() память, содержат квалификатор restrict. Такие указатели ссылаются на непересекающиеся области памяти.

Запуск приложения на счет с использованием GPU можно осуществить с помощью команды

srun --gres=gpu:1 exam_pgi

Опция -C k40m (или -C m2090) позволяет указать желаемый тип GPU (см. Кластер "Уран"), например,

srun --gres=gpu:1 -C k40m exam_pgi

С помощью программы pgaccelinfo [2, Setting Up] можно получить информацию о технических характеристиках GPU конкретного узла, указав опцию -w, например

srun -w tesla52 --gres=gpu:1 pgaccelinfo

Возможно совместное использование OpenMP и GPU.

Общие замечания.

  1. Использование GPU может дать значительное ускорение для задач, где активно задействованы стандартные математические функции (sin, cos, …, см. [1]). При этом надо иметь в виду, что точность вычислений на GPU не та же самая, что на CPU (в частности, и для тригонометрических функций).
    Рекомендуется (см., например, [2, 3]):
  2. До первого запуска kernel осуществлять начальную инициализацию GPU с помощью вызова функции acc_init(acc_device_nvidia).
  3. Копировать массивы целиком (память host <---> память GPU).
    Компилятор стремится минимизировать объём перемещаемых данных, не заботясь о количестве команд пересылки данных. Во многих случаях издержки на инициирование/завершение команд пересылки оказываются больше, чем экономия на времени самой пересылки, и более эффективно посылать один большой непрерывный кусок.
  4. Если посчитанные GPU данные не используются в дальнейшем на host, то следует явно указать компилятору, что соответствующие переменные не надо передавать обратно. Компилятор обычно возвращает на host все модифицированные данные.
  5. Постараться избавиться от диагностики вида ‘Non-stride-1 accesses for array 'X'’, изменив или структуру массива, или порядок заголовков циклов, или параметры преобразования циклов (loop schedule). Эта диагностика означает, что для соответствующего массива не обеспечен непрерывный доступ к данным и может возникнуть задержка при выполнении групп нитей (threads in groups), которые NVIDIA называет warps. Упрощённо можно думать, что warp выполняется в SIMD или векторном виде с доступом к памяти порциями определённого размера.

Ссылки на документацию

  1. GPU Programming with the PGI Accelerator Programming Model by Michael Wolfe / PGI GPU Programming Tutorial. Mar 2011
  2. The PGI Accelerator Programming Model on NVIDIA GPUs. Part 1 by Michael Wolfe / June 2009
  3. The PGI Accelerator Programming Model on NVIDIA GPUs. Part 2 Performance Tuning by Michael Wolfe / August 2009
  4. The OpenACC™ Application Programming Interface. Version 1.0. November, 2011
  5. PGI Accelerator Compilers with OpenACC Directives
  6. PGI Accelerator Compilers with OpenACC by Michael Wolfe / March 2012, revised in August 2012