Инструкция по сборке и компиляции ПО, Python-пакетов и расширений с поддержкой различных типов GPU
👉Вернуться к списку инструкций
Базовые положения:
- ПО и компиляторы подключаются с использованием программного пакета Lmod. Основные команды: module available, module load, module purge
- В состав кластера входят узлы с различными типами GPU. Каждый тип GPU имеет собственный код CUDA compute capability: V100 (sm_70), A100 (sm_80), H100/H200 (sm_90). Эти коды используются для указания целевых архитектур при сборке.
- На логин-узле можно производить сборку и компиляцию даже без установленного GPU. Если ПО требует наличия nvidia-smi или выполняет тесты на GPU - выполняйте сборку на вычислительном узле с GPU.
- Флаги автоматической оптимизации под текущий процессор, например -xHOST у Intel или -march=native у GCC, позволяют получить более производительный исполняемый файл, но снижают его переносимость. Программа, скомпилированная с такими флагами на одном типе узлов, может не запуститься на другом типе узлов и завершиться ошибкой Illegal instruction. Если программа должна запускаться на разных типах узлов, рекомендуется использовать переносимые архитектурные флаги. Для GCC можно использовать, например, -march=x86-64-v3 -mtune=generic.
- Небольшие программы можно компилировать на login-узле. Сборку крупных пакетов, требующих много процессорного времени, памяти или продолжительной компиляции, рекомендуется выполнять через Slurm на вычислительном узле. Это позволяет не нагружать login-узел и одновременно собирать программу в окружении, близком к тому, в котором она будет запускаться. При этом следует помнить: если во время сборки используются флаги автоматического определения архитектуры, например -march=native, итоговый исполняемый файл будет оптимизирован под процессор именно того узла, на котором выполнялась компиляция.
CPU-only и GPU сборки
Если программа собирается с поддержкой GPU, такой исполняемый файл может требовать доступного GPU уже на этапе запуска. Даже если конкретный тестовый расчёт не использует ускоритель явно, программа может завершиться ошибкой инициализации CUDA на CPU-only узле. Поэтому рекомендуется разделять CPU-only и GPU-сборки программы:
- CPU-only сборка — для запуска на узлах без GPU;
- GPU-сборка — для запуска на узлах с GPU и соответствующими драйверами.
Для GPU-сборок в Slurm-скрипте следует явно запрашивать GPU, например: #SBATCH --gres=gpu:1 и при необходимости указывать подходящий тип узлов через constraints.
Выбор компилятора и компиляция программ
Выбор компилятора осуществляется с помощью загрузки соответствующего модуля:
module load gcc/14.3.0 openmpi/5.0.10-GCC-14.3.0-CUDA-12.9.1 cuda/12.9.1
или
module load intel/oneAPI_2025_env
Для компиляции параллельных MPI-приложений с помощью компиляторов Intel Parallel Studio используйте команды mpiicx, mpiicpx, mpiifx:
- C: mpiicx [опции] -o program.out file1.c file2.c
- C++: mpiicpx [опции] -o program.out file1.cpp file2.cpp
- Fortran: mpiifx [опции] -o program.out file1.f90 file2.f90
Подробную информацию по использованию компиляторов Intel можно получить на официальном сайте Intel.
Для компиляции параллельных MPI-приложений с помощью GNU Compiler Collection + OpenMPI используйте команды mpiicx, mpiicpx, mpiifx:
- C: mpiicx [опции] -o program.out file1.c file2.c
- C++: mpiicpx [опции] -o program.out file1.cpp file2.cpp
- Fortran: mpiifx [опции] -o program.out file1.f90 file2.f90
Подробную информацию по использованию компиляторов GNU Compiler Collection и OpenMPI можно получить на официальном сайте.
При компиляции рекомендуется указывать особые флаги оптимизаций, позволяющие ускорить выполнение программы. Флаг оптимизации -O2 активирует векторизацию и базовую оптимизацию циклов. Данный флаг в большинстве случаев обеспечивает наилучшее быстродействие работы программы.
При использовании программ с большим количеством вычислений с плавающей точкой или обрабатывающих объёмные наборы данных рекомендуется использовать флаг -O3, активирующий более агрессивное преобразование циклов и условных выражений. Более подробную информацию по флагам оптимизации можно получить на сайте Intel Parallel Studio и GNU Compiler Collection.
При компиляции с использованием компиляторов Intel также рекомендуется указывать флаг -xHOST. Он позволяет компилятору использовать максимальный набор инструкций, доступных для процессоров на суперкомпьютере.
Пример использования флагов оптимизации при компиляции MPI-программ:
mpiicpc -xHOST -O2 /opt/ohpc/pub/examples/mpi/hello.c -o ./program_name
mpicxx -O2 /opt/ohpc/pub/examples/mpi/hello.c -o ./program_name
Для компиляции обычных (не параллельных) программ с помощью Intel Parallel Studio используйте следующие команды:
- C: icx [опции] -o program.out file1.c file2.c
- C++: icpx [опции] -o program.out file1.cpp file2.cpp
- Fortran: ifx [опции] -o program.out file1.f90 file2.f90
Для компиляции обычных (не параллельных) программ с помощью GNU Compiler Collection используйте следующие команды:
- C: gcc [опции] -o program.out file1.c file2.c
- C++: g++ [опции] -o program.out file1.cpp file2.cpp
- Fortran: gfortran [опции] -o program.out file1.f90 file2.f90
Компиляция С/C++/MPI/CUDA
Подключите необходимые модули, например:
module purge
module load gcc/14.3.0 openmpi/5.0.10-GCC-14.3.0-CUDA-12.9.1 cuda/12.9.1
При необходимости подключите дополнительные модули EasyBuild: module load EasyBuild/modules
Важно: CUDA Tookit в зависимости от версиии имеет ограничения на диапазон допустимых версий компиляторов. Подробнее можно узнать здесь и в документации CUDA.
Если код должен работать на любом типе узла с V100/A100/H100, собирайте бинарный файл с поддержкой нескольких архитектур.
Например, для cmake 3.18+:
cmake -DCMAKE_CUDA_ARCHITECTURES="70;80;90" -DCMAKE_BUILD_TYPE=Release ..
сmake --build . -j
Для nvcc:
nvcc -O3 my.cu -o app \
-gencode arch=compute_70,code=sm_70 \
-gencode arch=compute_80,code=sm_80 \
-gencode arch=compute_90,code=sm_90
Важно: в зависимости от ПО ключи могут отличаться.
Компиляция Python-пакетов и cpp-расширений PyTorch
Для компиляции Python-пакетов и cpp-расширений PyTorch полезно выполнять сборку с поддержкой нескольких архитектур GPU.
В случае ручной сборки используется переменная окружения
export TORCH_CUDA_ARCH_LIST="7.0;8.0;9.0+PTX"
При использовании cmake укажите параметр в setup.py/pyproject.toml:
set(CMAKE_CUDA_ARCHITECTURES "70;80;90")
Выбор версии CUDA Toolkit
На логин-сервере и вычислительных узлах доступно несколько версий CUDA Toolkit. Все они расположены в каталоге /usr/local
Для выбора определённой версии вы можете использовать Lmod-модули CUDA/x.x, либо указывать путь вручную в переменных окружения:
export CUDA_HOME=/usr/local/cuda-12.9
export PATH=$CUDA_HOME/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH
Эти переменные можно использовать следующим образом в cmake:
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CUDA_COMPILER=$CUDA_HOME/bin/nvcc \
-DCUDAToolkit_ROOT=$CUDA_HOME \
-DCMAKE_CUDA_ARCHITECTURES="70;80;90"
cmake --build build -j
И похожим образом в nvcc:
nvcc -O3 src/my_kernel.cu -o bin/app \
-I$CUDA_HOME/include -L$CUDA_HOME/lib64 -lcudart \
-Wl,-rpath,$CUDA_HOME/lib64 \
-gencode arch=compute_70,code=sm_70 \
-gencode arch=compute_80,code=sm_80 \
-gencode arch=compute_90,code=sm_90
Использование заглушек библиотек при компиляции
При сборке определённого ПО необходима линковка с API драйвера NVIDIA (-lcuda, cu*) и/или библиотекой NVML (-lnvidia-ml) - эти библиотеки поставляются и работают только с установленным драйвером NVIDIA.
На логин-сервере в этом случае потребуется указать путь до заглушек библиотек (стабов), например:
LSTUBS=/usr/local/cuda/lib64/stubs
nvcc ... \
-L$LSTUBS -lcuda -lnvidia-ml \
-L$CUDA_HOME/lib64 -lcudart \
-Wl,-rpath,$CUDA_HOME/lib64
Либо указать путь в LIBRARY_PATH: export LIBRARY_PATH=/usr/local/cuda/lib64/stubs:$LIBRARY_PATH
Важно: стабы - это "пустышки" библиотек для этапа линковки. На вычислительных узлах при запуске ПО должны использоваться настоящие библиотеки драйвера. Не добавляйте путь до стабов в LD_LIBRARY_PATH или rpath
Частые ошибки:
- nvcc: command not found - не загрузили модуль CUDA, либо не добавили путь до CUDA в переменные окружения.
- libcudart.so: cannot open shared object file - ПО во время запуска не может найти путь до библиотек CUDA. Укажите параметр -Wl,-rpath,$CUDA_HOME/lib64 на этапе сборке, либо перед запуском экспортируйте LD_LIBRARY_PATH
- CUDA error: no kernel image is available for execution on the device - при сборке не была указана архитектура GPU, на которой выполняется запуск. Выполните сборку с указанием всех возможных архитектур GPU кластера.
Нашли опечатку?
Выделите её, нажмите Ctrl+Enter и отправьте нам уведомление. Спасибо за участие!
Сервис предназначен только для отправки сообщений об орфографических и пунктуационных ошибках.