Вычисления на GPU могут быть полезны многим разработчикам, поскольку они позволяют повысить производительность кода. Эта технология доступна, но для ускорения выполнения кода или создания красочной визуализации нельзя просто перенести вычисления с CPU на GPU — для этого требуются специальные компиляторы и библиотеки.

Сегодня собрали несколько интересных решений, которые пригодятся в разнообразных задачах: от ускорения высоконагруженных вычислений до генерации графики.

ILGPU

ILGPU — это компилятор для реализации GPU-вычислений на .NET-языках, представленный в 2021 году. Он поддерживает технологию just-in-time, которая переводит код на машинный язык в процессе исполнения программы. ILGPU распространяют по open source лицензии NCSA. Она разрешает использовать, модифицировать и распространять ПО при сохранении отметки об авторских правах.

ILGPU написан на C# и сочетает в себе возможности C++ AMP и CUDA. Решение обеспечивает высокую скорость диспетчеризации, а типобезопасные делегаты позволяют избежать боксинга, то есть преобразования размерных типов данных языка из значимых в ссылочные. Также ILGPU позволяет адаптировать код под целевую архитектуру, будь то x86 или x64, без необходимости вносить изменения вручную.

В то же время компилятор поддерживает работу не только со статической, но и с динамической разделяемой памятью. Последние версии ILGPU позволяют выделять её для каждого ядра по отдельности.

class ...
{
    static void SharedMemKernel(ArrayView<int> data)
    {
        var staticMemory = SharedMemory.Allocate<int>>(1024);
        var dynamicMemory = SharedMemory.GetDynamic<int>>();
        ...
        var dynamicMemory2 = SharedMemory.GetDynamic<double>>();
        ...
    }
    static void ...(...)
    {
        using var context = Context.CreateDefault();
        using var accl = context.CreateCudaAccelerator(0);
        var config = SharedMemoryConfig.RequestDynamic<byte>(<GroupSize> * sizeof(int));
        var config2 = SharedMemoryConfig.RequestDynamic<int>(<GroupSize>);

        ...
        kernel((<UserGridDim>, <UserGroupDim>, config), buffer.View);
        ...
    }
}

Компилятор позволяет применять стандартные отладчики .NET для поиска и исправления ошибок в коде и поддерживает однопоточное выполнение программ.

Из других возможностей ILGPU можно отметить атомарные операции и низкоуровневые механизмы, такие как функции warp-перемешивания. Поддержка высокопроизводительных математических функций дополнительно ускоряет вычисления, особенно при работе с 32-битной арифметикой. Интересно, что с помощью компилятора смоделировали игру «Жизнь» с частотой обновления 300+ FPS.

В инструмент также входит библиотека ILGPU.Algorithms. Она предлагает набор вспомогательных алгоритмов высокого уровня, например, для сортировки и вычисления префиксных сумм, которые поддерживаются на всех типах ускорителей.

Дополнительную информацию можно почерпнуть в репозитории на GitHub и Discord-сообществе, участники которого готовы делиться опытом.

ComputeSharp

Это — библиотека .NET для работы с графикой, которая распространяется под лицензией MIT. Она была разработана Microsoft  несколько лет назад, и её до сих пор применяют в продуктах компании: Microsoft Store и Paint.NET.

Программные интерфейсы ComputeSharp позволяют получать доступ к GPU-устройствам, перемещать данные между GPU-буферами и оперативной памятью, а также писать шейдеры на C#.

ComputeSharp поддерживает диспетчеризацию многомерных групп потоков и позволяет использовать различные типы данных, включая векторные типы .NET и HLSL для сложных вычислений.

Например, вот пример шейдера, который применяет многопеременную логистическую функцию (softmax function) ко всем элементам в заданном буфере. Обычно её используют в задачах классификации в машинном обучении.

[ThreadGroupSize(DefaultThreadGroupSizes.X)]
[GeneratedComputeShaderDescriptor].
public readonly partial struct SoftmaxActivation(
    ReadWriteBuffer<float> buffer,
    float k) : IComputeShader
{
    public void Execute()
    {
        float exp = Hlsl.Exp(k * buffer[ThreadIds.X]);
        float log = Hlsl.Log(1 + exp);

        buffer[ThreadIds.X] = log / k;
    }
}

Стоит учесть, что работа на DX12 ограничивает применимость библиотеки. Как минимум этот факт делает ComputeSharp менее универсальной по сравнению с аналогами, например, ILGPU, ShaderGen.

gpu.cpp

Это — открытая библиотека для GPU-вычислений на С++. Она была представлена в июле 2024 года научно-исследовательской лабораторией Answer AI, основанной бывшим CEO Kaggle. Библиотека распространяется под лицензией Apache 2.0.

Разработчики библиотеки отмечают, что решения для вычислений на персональных устройствах в основном предназначены для игровых движков и ML-компиляторов, но не учитывают интересы программистов из других сфер. Проект имеет множество применений, включая автономный рендеринг графики и построение симуляций процессов, происходящих в реальном мире (различные примеры есть в репозитории).

Под капотом gpu.cpp — библиотека Dawn для обеспечения базовой функциональности WebGPU. Dawn — это кроссплатформенная реализация стандарта WebGPU с открытым исходным кодом, предоставляющая основные инструменты для разработки WebGPU-приложений, включая заголовки C/C++ и поддержку D3D12, Metal, Vulkan и OpenGL. В библиотеку встроен компилятор языка шейдеров под названием Tint.

Stardust

Это — библиотека для рендеринга с использованием GPU (WebGL). Цель проекта — упростить и ускорить создание визуализаций без отвлечений на управление шейдерами и буферами API. Библиотека предназначена в первую очередь для веб-разработчиков, специалистов по исследованию данных и дизайнеров, которым необходимо генерировать интерактивную 2D- и 3D-графику.

Среди ключевых возможностей Stardust можно выделить рендеринг в реальном времени — библиотека обрабатывает десятки тысяч графических элементов (в проекте они называются «маркерами»). Авторы приводят простой пример на сайте проекта — код для рендеринга нескольких геометрических фигур.

<script type="text/javascript">
    var canvas = document.getElementById("main-canvas");
    var width = 960;
    var height = 500;
    var platform = Stardust.platform("webgl-2d", canvas, width, height);
    var data = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    var circleSpec = Stardust.mark.circle();
    var circles = Stardust.mark.create(circleSpec, platform);
    circles.attr("center", (d) => [ d * 80, 250 ]);
    circles.attr("radius", (d) => d * 3);
    circles.attr("color", [ 0, 0, 0, 1 ]);
    circles.data(data);
    circles.render();
</script>

На портале приведены и комплексные примеры: построение графиков с применением глифов и визуализации с использованием three.js. Также в документации проекта можно найти обучающие материалы, а в песочнице опробовать их на практике.


Когда речь идет о доступности вычислительных ресурсов, часто упоминается виртуальная инфраструктура с GPU для машинного обучения, аналитики, рендеринга и 3D-моделирования. Однако проекты бывают разными — виртуальные рабочие места с графическими ресурсами (VDI GPU) эффективно справляются с задачами 3D-рендеринга и проектирования на обычных ПК без необходимости приобретать дорогостоящие графические станции.

В проектах большого масштаба может возникнуть необходимость в развертывании виртуальной ИТ-инфраструктуры для решения комплексных задач. Сейчас доступные облачные сервисы можно использовать со скидкой в течение шести месяцев. Подробнее об этом вы можете узнать на сайте.

Комментарии (3)


  1. Nail_S
    04.09.2024 19:39

    https://github.com/gfx-rs/wgpu WGPU под Rust забыли. Сам ей пользовался, очень популярна.


  1. unreal_undead2
    04.09.2024 19:39

     от ускорения высоконагруженных вычислений

    А чем обычный OpenMP с offload не нравится?


  1. Krasnoarmeec
    04.09.2024 19:39

    Весьма однобокая статья. Если хочется посчитать на GPU, то библиотек просто тьма. Об основной, Cloo, вообще ничего не сказано. А, между тем, библиотека позволяет проводить распараллеленные вычисления и на GPU и на CPU. Причём любых типов устройств, а не только на NVIDIA, как CUDA.

    Даже я отметился библиотекой вычислений на GPU (и на CPU тоже).