Запуск 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

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

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

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

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

Комплексные данные на графическом процессоре хранятся в чередующемся сложном формате. То есть для сложного 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));

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

Скомпилируйте файл MEX графического процессора

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

mexcuda mexGPUExample.cu

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

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

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

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

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

См. также

| |

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте