exponenta event banner

Запуск MEX-функций, содержащих код CUDA

Запись MEX-файла, содержащего код CUDA

Как и для любых MEX-файлов, файлы, содержащие код CUDA ®, имеют одну точку входа, известную какmexFunction. MEX-функция содержит код на стороне хоста, который взаимодействует с объектами gpuArray из MATLAB ® и запускает код CUDA. Код CUDA в MEX-файле должен соответствовать API среды выполнения CUDA.

Необходимо вызвать функцию mxInitGPU при входе в MEX-файл. Это гарантирует, что устройство графического процессора будет правильно инициализировано и известно MATLAB.

Интерфейс, используемый для записи MEX-файла для объектов gpuArray, отличается от интерфейса MEX для стандартных массивов MATLAB.

Пример MEX-файла, содержащего код CUDA, можно посмотреть по адресу:

Этот файл содержит следующую функцию устройства CUDA:

void __global__ TimesTwo(double const * const A,
                         double * const B,
                         int const N)
{
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < N)
        B[i] = 2.0 * A[i];
}

Он содержит следующие строки для определения размера массива и запуска сетки соответствующего размера:

N = (int)(mxGPUGetNumberOfElements(A));
blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
TimesTwo<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, N);

Выполнение результирующих MEX-функций

MEX-функция в этом примере умножает каждый элемент во входном массиве на 2, чтобы получить значения в выходном массиве. Чтобы проверить его, начните с gpuArray, в котором каждый элемент равен 1:

x = ones(4,4,'gpuArray');
y = mexGPUExample(x)
y = 

    2    2    2    2
    2    2    2    2
    2    2    2    2
    2    2    2    2

И входной, и выходной массивы являются объектами gpuArray:

disp(['class(x) = ',class(x),', class(y) = ',class(y)])
class(x) = gpuArray, class(y) = gpuArray

Сравнение с ядром CUDA

Toolbox™ параллельных вычислений также поддерживает CUDAKernel объекты, которые можно использовать для интеграции кода CUDA с MATLAB. Можно создавать CUDAKernel с использованием файлов CU и PTX. Как правило, использование MEX-файлов является более гибким, чем использование CUDAKernel объекты:

  • MEX-файлы могут включать в себя вызовы библиотек на стороне хоста, включая библиотеки NVIDIA ®, такие как библиотеки NVIDIA Performance Primitives (NPP) или cuFFT. MEX-файлы также могут содержать вызовы от хоста к функциям в библиотеке среды выполнения CUDA.

  • MEX-файлы могут анализировать размер входных данных и выделять память другого размера, или запускать сетки другого размера, из кода C или C++. Для сравнения, код MATLAB, который вызывает CUDAKernel объекты должны предварительно выделить выходную память и определить размер сетки.

Доступ к сложным данным

Сложные данные на устройстве GPU хранятся в перемежающемся сложном формате. То есть для сложного gpuArray A, действительная и мнимая части элемента i хранятся в последовательных адресах. MATLAB использует встроенные векторные типы CUDA для хранения сложных данных на устройстве (см. Руководство по программированию NVIDIA CUDA C).

В зависимости от потребностей ядра, можно привести указатель к сложным данным либо как вещественный тип, либо как встроенный векторный тип. Например, в MATLAB предположим, что создается следующая матрица:

a = complex(ones(4,'gpuArray'),ones(4,'gpuArray'));

Если передать gpuArray функции MEX в качестве первого аргумента (prhs [0]), то можно получить указатель на сложные данные с помощью вызовов:

mxGPUArray const * A = mxGPUCreateFromMxArray(prhs[0]);
mwSize numel_complex = mxGPUGetNumberOfElements(A);
double2 * d_A = (double2 const *)(mxGPUGetDataReadOnly(A));

Чтобы считать массив реальным массивом двойной точности с удвоенной длиной, можно сделать это следующим образом:

mxGPUArray const * A = mxGPUCreateFromMxArray(prhs[0]);
mwSize numel_real =2*mxGPUGetNumberOfElements(A);
double * d_A = (double const *)(mxGPUGetDataReadOnly(A));

Существуют различные функции преобразования данных между сложным и реальным форматами на GPU. Для этих операций требуется копия для перемежения данных. Функция mxGPUCreateComplexGPUArray принимает два реальных луча mxGPUAray и перемежает их элементы для получения единого комплексного луча mxGPUAray одинаковой длины. Функции mxGPUCopyReal и mxGPUCopyImag каждый копирует вещественные или мнимые элементы в новый реальный mxGPUAray. (Нет эквивалента mxGetImagData функция для объектов mxGPUAray.)

Компиляция файла MEX графического процессора

Используйте mexcuda в MATLAB для компиляции MEX-файла, содержащего код CUDA. Файл примера можно скомпилировать с помощью команды:

mexcuda mexGPUExample.cu

Если набор средств CUDA не обнаружен или не является поддерживаемой версией, MATLAB компилирует код CUDA с помощью NVIDIA nvcc компилятор установлен с MATLAB. Проверка компилятора mexcuda использует, используйте -v флаг для подробного вывода в mexcuda команда.

Набор инструментов CUDA, установленный с MATLAB, не содержит всех библиотек, доступных в наборе инструментов CUDA. Если требуется связать определенную библиотеку, которая не установлена с MATLAB, установите набор инструментов CUDA. Вы можете проверить, какой набор инструментов CUDA версии MATLAB требуется с помощью gpuDevice. Дополнительные сведения о CUDA Toolkit см. в разделе CUDA Toolkit.

Если mexcuda не удалось найти компилятор NVIDIA (nvcc) в установленном инструментарии CUDA, он может быть установлен в расположение, отличное от расположения по умолчанию. Можно указать расположение nvcc в системе путем сохранения в переменной среды MW_NVCC_PATH. Эту переменную можно задать с помощью MATLAB. setenv команда. Например,

setenv('MW_NVCC_PATH','/usr/local/CUDA/bin')

Для mexcuda поддерживается только подмножество компиляторов Visual Studio ®. Для получения более подробной информации см. документацию по инструментарию NVIDIA.

См. также

| |

Связанные темы