Установка и использование архитектуры CUDA
CUDA — программно-аппаратная архитектура параллельных вычислений, разработанная компанией Nvidia, позволяющая увеличить производительность различных вычислений за счет использования графических процессоров (GPU). В «Форсайт. Аналитическая платформа» реализована специальная библиотека, позволяющая использовать архитектуру CUDA для расчета агрегированных данных в различных инструментах платформы.
Примечание . Поддержка использования архитектуры CUDA реализована только для 64-х разрядной Windows-версии «Форсайт. Аналитическая платформа».
Установка и настройка
Для произведения расчетов с использованием CUDA:
- Проверьте, поддерживает ли установленная видеокарта архитектуру CUDA. Информация о поддержке CUDA доступна в прилагаемой к видеокарте документации или на сайте разработчика. Если предполагается работа в настольном приложении «Форсайт. Аналитическая платформа», то необходимо проверить видеокарту компьютера-клиента. При работе в веб-приложении проверьте видеокарту компьютера, на котором установлен BI-сервер.
- Установите дополнительное программное обеспечение — CUDA Toolkit 7.0.
- В реестре операционной системы в ветке [ HKEY_CURRENT_USER\Software\Foresight\Foresight Analytics Platform\9.0\9.0\Stat\ ] добавьте флаг EnableCalcWithGPU (тип параметра — DWORD (32 бита)) и укажите в нем значение «1».
После успешного выполнения указанных шагов «Форсайт. Аналитическая платформа» автоматически будет использовать архитектуру CUDA. CUDA будет применяться в следующих случаях:
- Агрегация в кубах (только для основного механизма агрегации);
- Агрегация данных по фиксированным измерениям в аналитических запросах.
Технология CUDA: что это и как используется
Что такое CUDA? CUDA (Compute Unified Device Architecture) – это архитектура, которая позволяет использовать графический процессор (GPU) для повышения производительности параллельных вычислений. Она представляет собой набор инструментов и библиотек для работы с графическим процессором, основанных на технологии GPGPU.
GPGPU (General-purpose graphics processing units) – это технология, которая позволяет использовать графический процессор, предназначенный для компьютерной графики, при выполнении общих вычислений, производимых центральным процессором. Это стало возможным благодаря шейдерным блокам, с помощью которых программируются окончательные параметры объекта с высокой арифметической точностью.
Технология была разработана компанией Nvidia для решения сложных вычислительных задач, которые ранее выполнялись только на центральном процессоре (CPU). Она позволила повысить производительность компьютеров, ноутбуков, суперкомпьютеров, вычислительных станций.
Виды процессоров
Так как технология CUDA связана с использованием процессоров, рассмотрим какие виды процессоров бывают.
CPU (Центральный процессор) — это микропроцессор, выполняющий основные операции и управляющий работой компьютера или другого цифрового устройства. Он является «мозгом» компьютера: обрабатывает информацию, выполняет инструкции, математические и логические операции, координирует работу различных компонентов и устройств, и обеспечивает взаимодействие со внешними устройствами.
Центральный процессор работает непрерывно, обрабатывая все задачи по порядку, которые ему поступают. Чем выше производительность CPU, тем быстрее обрабатываются процессы, выполняемые на компьютере.
GPU или графический процессор, предназначен для обработки графических и видео-образов на компьютере. Графический процессор является частью видеокарты, которая отвечает за вывод изображения на монитор.
Одним из главных преимуществ GPU является способность обрабатывать большое количество данных параллельно, что позволяет графическим приложениям быстрее и эффективнее работать с сложными трехмерными моделями и обработкой видео.
Программная архитектура CUDA
.jpg)
Основной принцип работы CUDA состоит в том, что она дает доступ к вычислительной способности графического процессора, который обладает высокой эффективностью при решении многопотоковых задач.
CUDA имеет архитектуру, включающую в себя:
- ядро,
- драйвер,
- язык программирования C/C++,
- специальные библиотеки математических функций и утилит.
Ядро CUDA – это программируемый процессор, способный выполнять вычисления одновременно с миллионами параллельных потоков. Ядро состоит из специального набора команд, называемого ассемблером CUDA.
Драйвер – это программа, которая обеспечивает взаимодействие между операционной системой и GPU NVIDIA. С его помощью происходит создание и управление потоками ядер, чтение и запись данных в память GPU, а также связь с другими устройствами на системной шине.
C/C++ – это язык программирования, разработанный для работы с GPU NVIDIA. CUDA расширяет язык новыми ключевыми словами, функциями и библиотеками для использования GPU в процессе выполнения вычислительных задач.
В библиотеках находится коллекция алгоритмов CUDA и утилит для выполнения ядерных вычислений, использования функций математических вычислений, работы с трехмерной графикой, а также реализации машинного обучения и глубокого обучения.
При работе с технологией CUDA сначала происходит определение необходимых операций и алгоритмов, которые должны быть выполнены на графическом процессоре. Затем, с помощью языка программирования, пишется код, который будет выполнять все необходимые вычислительные задачи на GPU. После запускается программа, она загружается на GPU и выполняется на всех доступных ядрах последовательно или параллельно. Результаты вычислений возвращаются в оперативную память компьютера для дальнейшей обработки и использования.
На платформе CUDA также поддерживаются различные технологии ускорения вычислений, например, NVLink, которая обеспечивает высокоскоростной доступ к памяти и позволяет разделить задачи между несколькими графическими процессорами. Кроме того, CUDA поддерживает технологию динамической оптимизации, которая позволяет GPU адаптироваться к уникальным характеристикам каждой задачи, улучшая производительность и снижая расходы энергии.
Недостатки и преимущества CUDA
Преимущества CUDA:
- Высокая производительность: CUDA значительно ускоряет выполнение вычислений, особенно тех, которые требуют параллельной обработки данных.
- Распределенные вычисления: CUDA имеет возможность распределенных вычислений, что позволяет использовать несколько графических процессоров, работающих в сети, для решения вычислительных задач.
- Настраиваемость: CUDA позволяет настраивать все параметры процесса вычисления, чтобы получить максимальную производительность.
- Множество инструментов разработки: NVIDIA предоставляет разнообразные инструменты разработки для CUDA, включая языки программирования, библиотеки, среды разработки и фреймворки для машинного обучения и глубокого обучения.
- Широкий спектр применения: технология CUDA может быть использована во многих отраслях, например, при обработке изображений и видео, научных исследованиях, машинном обучении, финансах и т.д.
Недостатки CUDA:
- Размерные ограничения: CUDA имеет определенные ограничения по объему оперативной памяти на GPU, что иногда ограничивает размер обрабатываемых данных.
- Сложность программирования: CUDA является сложной платформой для программистов, особенно для тех, кто не знаком с использованием параллельных вычислений и GPU.
Ограничения CUDA
Один из главных недостатков CUDA состоит в том, что она является эксклюзивной платформой для работы на GPU компании NVIDIA. Это означает, что программа, написанная на CUDA, не будет работать на машинах с графическими процессорами других производителей (например, AMD или Intel).
Для работы с платформой CUDA необходимо превращать вычислительные операции в графические, таким образом, не все вычислительные задачи позволяют использовать CUDA в своей работе.
Еще одним ограничением CUDA является количество памяти на видеокарте. Каждая видеокарта имеет конечное количество памяти, что может стать проблемой для выполнения вычислительных задач с большими объемами данных.
В каких областях можно использовать CUDA
Технология CUDA используется в областях, где требуются высокопроизводительные вычисления, например:
- Научные исследования в физике, химии, биологии и астрономии. Например, моделирование различных научных явлений.
- Машинное обучение. Например, распознавания изображений и обработки естественного языка.
- Обработка видео и графики. Например, в индустрии кино и мультимедиа.
- Финансы. Например, для анализа рынков акций и ценных бумаг.
- Медицина. Например, для обработки рентгеновских снимков и магнитно-резонансной томографии.
- Обработка сигналов. Например, для расшифровки сигналов из космических источников.
- Робототехника. Например, для расширения возможностей роботов.
Часто задаваемые вопросы о CUDA
- Какие операционные системы поддерживает CUDA?
CUDA поддерживает Windows, Linux и Mac OS.
- Какие вычисления можно выполнять с помощью CUDA?
CUDA позволяет выполнять вычислительные задачи из различных областей: научные исследования, машинное обучение, обработка графики и видео, финансовый анализ, медицинские и биологические расчеты, обработка сигналов.
- В чем отличие между CPU и GPU?
CPU и GPU обрабатывают данные по-разному. CPU выполнит один поток данных за раз, тогда как GPU может обрабатывать множество потоков одновременно. GPU имеет большое количество ядер, которые позволяют выполнять многопоточные вычисления с высокой эффективностью.
- Какие языки программирования поддерживают CUDA?
CUDA поддерживает такие языки программирования, как C++, Python , Fortran, Java и другие.
Заключение
Преимущества CUDA заключаются в более быстрой обработке информации, в возможности работать с большим количеством данных и параллельных процессов, которые ранее не могли быть выполнены на CPU. Однако, для использования CUDA необходимы знания в области программирования и умения ставить специализированные вычислительные задачи, требующие больших вычислительных мощностей.
Использование CUDA
Запуск задач на графических процессорах в системе SLURM задается опцией —gres=gpu:N , где N — число GPU.
Свежая версия библиотеки CUDA находится в каталоге /opt/cuda/.
/opt/cuda/include/ — заголовочные файлы;
/opt/cuda/lib /— библиотека CUDA;
/opt/cuda/doc/ — документация.
Чтобы использовать библиотеку CUDA, необходимо при компиляции программы заказать данную библиотеку, например:
gcc mytest.c -o mytest -lcuda -L/opt/cuda/lib -I/opt/cuda/include
Можно использовать компилятор nvcc:
nvcc -o
На кластере «Уран» при выполнении данной команды по умолчанию подключается библиотека CUDA . Можно компилировать программы на языках C и C++ (файлы с расширением .c и .cpp) и программы, написанные с использованием технологии CUDA (файлы с расширением .cu), например:
u9999@umt:~$ nvcc main.c -o gputest
Пример
Пусть файл cuda_test.cu (из домашнего каталога) содержит программу на CUDA:
#include #include int main() < int GPU_N; int dev; cudaGetDeviceCount(&GPU_N); printf("Device count: %d\n", GPU_N); for(dev=0;devreturn 0; >
Тогда компиляция программы и запуск задачи на кластере могут иметь вид:
u9999@umt:~$ nvcc cuda_test.cu -o cuda_test u9999@umt:~$ srun --gres=gpu:1 ./cuda_test Device count: 1 PCI Bus id: 8 u9999@umt:~$ srun --gres=gpu:2 ./cuda_test Device count: 2 PCI Bus id: 10 PCI Bus id: 26
Поддержка CUDA есть в компиляторе Portland Group.
Инструкции по использованию CUDA в Фортране можно найти на сайте Portland Group (http://www.pgroup.com/resources/cudafortran.htm).
Для компиляции Fortran-программы с CUDA следует установить переменные окружения командой module или mpiset , выбрав связку MVAPICH+PGI, например:
module switch mpi/default mvapich2/pgi_12.10
mpiset 7
и откомпилировать программу компилятором pgfortran с опцией -Mcuda , указав при необходимости оптимизированные библиотеки, например:
pgfortran -o mytest test.cuf -Mcuda -lcublas
Ссылки на руководства по CUDA
CUDA и удалённый GPU
CUDA всем хороша, пока под рукой есть видеокарта от Nvidia. Но что делать, когда на любимом ноутбуке нет Nvidia видеокарты? Или нужно вести разработку в виртуальной машине?
Я постараюсь рассмотреть в этой статье такое решение, как фреймворк rCUDA (Remote CUDA), который поможет, когда Nvidia видеокарта есть, но установлена не в той машине, на которой предполагается запуск CUDA приложений. Тем, кому это интересно, добро пожаловать под кат.
rCUDA (Remote CUDA) — фреймворк, реализующий CUDA API, позволяющий использовать удалённую видеокарту. Находится в работоспособной бета-версии, доступен только под Linux. Основная цель rCUDA — полная совместимость с CUDA API, вам не нужно никак модифицировать свой код, достаточно задать специальные переменные среды.
Что такое rCUDA
rCUDA (Remote CUDA) — фреймворк, реализующий CUDA API, позволяющий использовать для CUDA вычислений видеокарту, расположенную на удалённой машине, не внося никаких изменений в ваш код. Разработан в политехническом университете Валенсии (rcuda-team).
Ограничения
На данный момент поддерживаются только GNU/Linux системы, однако разработчики обещают поддержку Windows в будущем. Текущая версия rCUDA, 18.03beta, совместима с CUDA 5-8, то есть CUDA 9 не поддерживается. Разработчиками заявлена полная совместимость с CUDA API, за исключением графики.
Возможные сценарии использования
- Запуск CUDA приложений в виртуальной машине тогда, когда проброс видеокарты неудобен или невозможен, например, когда видеокарта занята хостом, или когда виртуальных машин больше одной.
- Ноутбук без дискретной видеокарты.
- Желание использовать несколько видеокарт (кластеризация). Теоретически, можно использовать все имеющиеся в команде видеокарты, в том числе совместо.
Краткая инструкция
Тестовая конфигурация
Тестирование проводилось на следующей конфигурации:
Сервер:
Ubuntu 16.04, GeForce GTX 660
Клиент:
Виртуальная машина с Ubuntu 16.04 на ноутбуке без дискретной видеокарты.
Получение rCUDA
Cамый сложный этап. К сожалению, на данный момент единственный способ получить свой экземпляр этого фреймворка — заполнить соответствующую форму запроса на официальном сайте. Впрочем, разработчики обещают отвечать в течение 1-2 дней. В моём случае мне прислали дистрибутив в тот же день.
Установка CUDA
Для начала необходимо установить CUDA Toolkit на сервере и клиенте (даже если на клиенте нет nvidia видеокарты). Для этого можно скачать его с официального сайта или использовать репозиторий. Главное, использовать версию не выше 8. В данном примере используется установщик .run с оффициального сайта.
chmod +x cuda_8.0.61_375.26_linux.run ./cuda_8.0.61_375.26_linux.run
Важно! На клиенте следует отказаться от установки nvidia драйвера. По умолчанию CUDA Toolkit будет доступен по адресу /usr/local/cuda/. Установите CUDA Samples, они понадобятся.
Установка rCUDA
Распакуем полученный от разработчиков архив в нашу домашнюю директорию на сервере и на клиенте.
tar -xvf rCUDA*.tgz -C ~/ mv ~/rCUDA* ~/rCUDA
Проделать эти действия нужно как на сервере, так и на клиенте.
Запуск демона rCUDA на сервере
export PATH=$PATH/usr/local/cuda/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/home//rCUDA/lib/cudnn cd ~/rCUDA/bin ./rCUDAd
Замените < XXX>на имя вашего пользователя. Используйте ./rCUDAd -iv, если хотите видеть подробный вывод.
Настройка клиента
Откроем на клиенте терминал, в котором в дальнейшем будем запускать CUDA код. На стороне клиента нам необходимо «подменить» стандартные библиотеки CUDA на библиотеки rCUDA, для чего добавим соответствующие пути в переменную среды LD_LIBRARY_PATH. Также нам необходимо указать количество серверов и их адреса (в моём примере он будет один).
export PATH=$PATH/usr/local/cuda/bin export LD_LIBRARY_PATH=/home//rCUDA/lib/:$LD_LIBRARY_PATH export RCUDA_DEVICE_COUNT=1 # укажем количество видеокарт (серверов), их может быть несколько export RCUDA_DEVICE_0=:0 # укажем адрес первого сервера
Сборка и запуск
Попробуем собрать и запустить несколько примеров.
Пример 1
Начнём с простого, с deviceQuery — примера, который просто выведет нам параметры CUDA совместимого устройства, то есть в нашем случае удалённого GTX660.
cd /NVIDIA_CUDA-8.0_Samples/1_Utilities/deviceQuery make EXTRA_NVCCFLAGS=--cudart=shared
Важно! Без EXTRA_NVCCFLAGS=—cudart=shared чуда не получится
Замените на путь, который вы указали для CUDA Samples при установке CUDA.
Запустим собранный пример:
./deviceQuery
Если вы всё сделали правильно, результат будет примерно таким:
Результат
./deviceQuery Starting. CUDA Device Query (Runtime API) version (CUDART static linking) Detected 1 CUDA Capable device(s) Device 0: "GeForce GTX 660" CUDA Driver Version / Runtime Version 9.0 / 8.0 CUDA Capability Major/Minor version number: 3.0 Total amount of global memory: 1994 MBytes (2090991616 bytes) ( 5) Multiprocessors, (192) CUDA Cores/MP: 960 CUDA Cores GPU Max Clock rate: 1072 MHz (1.07 GHz) Memory Clock rate: 3004 Mhz Memory Bus Width: 192-bit L2 Cache Size: 393216 bytes Maximum Texture Dimension Size (x,y,z) 1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096) Maximum Layered 1D Texture Size, (num) layers 1D=(16384), 2048 layers Maximum Layered 2D Texture Size, (num) layers 2D=(16384, 16384), 2048 layers Total amount of constant memory: 65536 bytes Total amount of shared memory per block: 49152 bytes Total number of registers available per block: 65536 Warp size: 32 Maximum number of threads per multiprocessor: 2048 Maximum number of threads per block: 1024 Max dimension size of a thread block (x,y,z): (1024, 1024, 64) Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535) Maximum memory pitch: 2147483647 bytes Texture alignment: 512 bytes Concurrent copy and kernel execution: Yes with 1 copy engine(s) Run time limit on kernels: Yes Integrated GPU sharing Host Memory: No Support host page-locked memory mapping: Yes Alignment requirement for Surfaces: Yes Device has ECC support: Disabled Device supports Unified Addressing (UVA): Yes Device PCI Domain ID / Bus ID / location ID: 0 / 1 / 0 Compute Mode: < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 9.0, CUDA Runtime Version = 8.0, NumDevs = 1, Device0 = GeForce GTX 660 Result = PASS
Самое главное, что мы должны увидеть:
Device0 = GeForce GTX 660
Result = PASS
Отлично! Нам удалось собрать и запустить CUDA приложение на машине без дискретной видеокарты, использовав для этого видеокарту, установленную на удалённом сервере.
Важно! Если вывод приложения начинается со строк вида:
mlock error: Cannot allocate memory rCUDA warning: 1007.461 mlock error: Cannot allocate memory
значит необходимо добавить на сервере и на клиенте в файл «/etc/security/limits.conf» следующие строки:
* hard memlock unlimited * soft memlock unlimited
Таким образом, вы разрешите всем пользователям (*) неограниченное (unlimited) блокирование памяти (memlock). Еще лучше будет заменить * на нужного пользователя, а вместо unlimited подобрать менее жирные права.
Пример 2
Теперь попробуем что-то поинтереснее. Протестируем реализацию скалярного произведения векторов с использованием разделяемой памяти и синхронизации («Технология CUDA в примерах» Сандерс Дж. Кэндрот Э. 5.3.1).
В данном примере мы рассчитаем скалярное произведение двух векторов размерностью 33 * 1024, сравнивая ответ с результатом, полученным на CPU.
dotProd.cu
#include #define imin(a,b) (a // set the cache values cache[cacheIndex] = temp; // synchronize threads in this block __syncthreads(); // for reductions, threadsPerBlock must be a power of 2 // because of the following code int i = blockDim.x/2; while (i != 0) < if (cacheIndex < i) cache[cacheIndex] += cache[cacheIndex + i]; __syncthreads(); i /= 2; >if (cacheIndex == 0) c[blockIdx.x] = cache[0]; > int main (void) < float *a, *b, c, *partial_c; float *dev_a, *dev_b, *dev_partial_c; // allocate memory on the cpu side a = (float*)malloc(N*sizeof(float)); b = (float*)malloc(N*sizeof(float)); partial_c = (float*)malloc(blocksPerGrid*sizeof(float)); // allocate the memory on the gpu cudaMalloc((void**)&dev_a, N*sizeof(float)); cudaMalloc((void**)&dev_b, N*sizeof(float)); cudaMalloc((void**)&dev_partial_c, blocksPerGrid*sizeof(float)); // fill in the host memory with data for(int i=0; i// copy the arrays 'a' and 'b' to the gpu cudaMemcpy(dev_a, a, N*sizeof(float), cudaMemcpyHostToDevice); cudaMemcpy(dev_b, b, N*sizeof(float), cudaMemcpyHostToDevice); dot>>(dev_a, dev_b, dev_partial_c); // copy the array 'c' back from the gpu to the cpu cudaMemcpy(partial_c,dev_partial_c, blocksPerGrid*sizeof(float), cudaMemcpyDeviceToHost); // finish up on the cpu side c = 0; for(int i=0; i #define sum_squares(x) (x*(x+1)*(2*x+1)/6) printf("GPU - %.6g \nCPU - %.6g\n", c, 2*sum_squares((float)(N-1))); // free memory on the gpu side cudaFree(dev_a); cudaFree(dev_b); cudaFree(dev_partial_c); // free memory on the cpu side free(a); free(b); free(partial_c); >
Сборка и запуск:
/usr/local/cuda/bin/nvcc --cudart=shared dotProd.cu -o dotProd ./dotProd
Такой результат говорит нам, что всё у нас хорошо:
GPU — 2.57236e+13
CPU — 2.57236e+13
Пример 3
Запустим еще один стандартный тест CUDA- matrixMulCUBLAS (перемножение матриц).
cd < YYY>/NVIDIA_CUDA-8.0_Samples/0_Simple/matrixMulCUBLAS make EXTRA_NVCCFLAGS=--cudart=shared ./matrixMulCUBLAS
Результат
[Matrix Multiply CUBLAS] — Starting…
GPU Device 0: «GeForce GTX 660» with compute capability 3.0
MatrixA(640,480), MatrixB(480,320), MatrixC(640,320)
Computing result using CUBLAS. done.
Performance= 436.24 GFlop/s, Time= 0.451 msec, Size= 196608000 Ops
Computing result using host CPU. done.
Comparing CUBLAS Matrix Multiply with CPU results: PASS
NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
Performance= 436.24 GFlop/s,
Comparing CUBLAS Matrix Multiply with CPU results: PASS
Безопасность
Я не нашёл в документации к rCUDA упоминания о каком-либо способе авторизации. Думаю, на данный момент самое простое, что можно сделать, это открыть доступ к нужному порту (8308) только с определённого адреса.
При помощи iptables это будет выглядеть так:
iptables -A INPUT -m state --state NEW -p tcp -s --dport 8308 -j ACCEPT
В остальном оставляю вопрос безопасности за рамками данного поста.
