Вы здесь

О запуске приложений с OpenMP, PGI Accelerator и OpenACC

О компиляторах

Пользователям доступны компиляторы GNU, Intel и PGI, поддерживающие языки C, C++ и Fortran.
Смена компилятора осуществляется командой module или mpiset, например, для работы с PGI на umt можно выполнить
    mpiset 7

После такой установки команды вида mpicc, mpif77 и т.п. можно использовать вместо имен компиляторов, даже если программа не использует MPI.

Об опциях компилятора можно узнать с помощью команд man или info, например,
    man pgcc
    info pgСС


Приложения с OpenMP (Компиляция Запуск)

Приложения с OpenMP можно запускать на кластере "Уран" (umt).

Приложения с OpenMP могут быть запущены как на обычных вычислительных узлах umt, так и на узлах с графическими ускорителями и большим объёмом оперативной памяти.

OpenMP подключается опцией, соответствующей установленному компиляторy (http://openmp.org/wp/openmp-compilers/):

 gcc/gfortran                  -fopenmp           GNU
 icc/ifort                     -openmp            Intel (по умолчанию на umt)
 pgcc/pgCC/pgf77/pgfortran     -mp                PGI

Так, компиляция файла exam.c на umt компилятором Intel (с учетом умолчания) выполняется командой
    icc -openmp exam.c -o exam_i

или командой
    mpicc -openmp exam.c -o exam_i


Число параллельных нитей задается с помощью переменной окружения OMP_NUM_THREADS. Как правило, она устанавливается перед запуском программы из командной строки командой вида
    export OMP_NUM_THREADS=8

Если число нитей больше числа выделенных процессу ядер, то, по крайней мере, одно ядро будет исполнять более одной нити, что целесообразно, например, в случае, когда часть нитей имеет меньшую вычислительную активность.

Запуск приложения. Пользователю необходимо указать число ядер (cpus) для каждого из процессов (task) с помощью опции
--cpus-per-task=ncpus
( см., например, команду man srun).

При этом система предоставляет узел для процесса, если на нем имеется указанное число свободных ядер.
Максимальное число ядер, равное 36, содержат узлы раздела apollo (см. Кластер "Уран").

Пусть задано
    export OMP_NUM_THREADS=12

Тогда в результате выполнения команды интерактивного запуска
    srun --cpus-per-task=6 exam_i > exam_i.out

одному (n=1 по умолчанию) процессу (задаче) пользователя будет выделено 6 ядер на узле и при вычислениях будет задействовано 12 нитей; результаты вычислений будут записаны в указанный пользователем файл exam_i.out

Внимание! Опция --mem=<MB> задает запуск на узле с большей памятью.
Например, команда
    srun --mem=40G --cpus-per-task=12 exam_i > exam_i.out

запустит задачу на узле с оперативной памятью не меньшей, чем 48 ГБ (о типах узлов см. Кластер "Уран").
В пакетном режиме соответствующий запуск может выглядеть так:
    sbatch --mem=40G --cpus-per-task=12 mybat_i

где файл mybat_i содержит строки
#!/bin/sh
srun exam_i > exam_i.out

Если файл mybat_i не содержит перенаправления вывода, т.е. имеет вид
#!/bin/sh
srun exam_i

то результаты вычислений по умолчанию будут записаны в файл slurm-<id>.out (<id> - уникальный номер или уникальный идентификатор задачи, см. Запуск задач на кластере в системе SLURM).

В командах, представленных выше, в качестве примера программы можно использовать файл pi_omp.c.

Замечание. Возможен запуск гибридных MPI/OpenMP приложений с помощью опции --ntasks-per-node=<ntasks>, например,
    sbatch -N 2 --cpus-per-task=12 --ntasks-per-node=1 my_bat_i

(подробнее см. man sbatch).


Приложения для GPU с PGI Accelerator и OpenACC (Компиляция Запуск)

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

Настроиться на компиляторы PGI можно с помощью команды mpiset
(на текущую рабочую версию 11.1)
    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

Для задач с большими массивами (> 3 ГБ) следует использовать опцию -C bigmem, которая обеспечит выделение узла с видеокартами Tesla M2090 с памятью Global Memory 6 ГБ (о типах узлов см. Кластер "Уран"). Например,
    srun --gres=gpu:1 -C bigmem exam_pgi

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

Общие замечания.
1. Использование GPU может дать значительное ускорение для задач, где активно задействованы стандартные математические функции (sin, cos, …, см. [1]). При этом надо иметь в виду, что точность вычислений на GPU не та же самая, что на хосте (в частности, и для тригонометрических функций).
  Рекомендуется (см., например, [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 или векторном виде с доступом к памяти порциями определённого размера.

Информацию о технических характеристиках GPU выдает программа pgaccelinfo (см., например, в [2, Setting Up] ; среда PGI предполагается установленной)
    srun --gres=gpu:1 pgaccelinfo

Опция вида -w 'tesla16' позволяет выдать эту информацию для конкретного (в данном случае 16) узла
     srun -w 'tesla16' --gres=gpu:1 pgaccelinfo


Ссылки на документацию
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