Запустите 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. Рассмотрите следующее при выборе подхода файла MEX по сравнению с подходом CUDAKernel:

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

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

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

Комплексные данные на устройстве графического процессора хранятся в чередованном сложном формате. Таким образом, для комплексного 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 берет два действительных mxGPUArrays и чередует их элементы, чтобы произвести один комплекс mxGPUArray той же длины. Функции mxGPUCopyReal и mxGPUCopyImag каждая копия или действительное или мнимые элементы в новый действительный mxGPUArray. (Нет никакого эквивалента функции mxGetImagData для объектов mxGPUArray.)

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

Чтобы скомпилировать код CUDA, вы, должно быть, установили версию инструментария CUDA, сопоставимую со свойством ToolkitVersion объекта gpuDevice.

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

mexcuda mexGPUExample.cu

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

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

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

Похожие темы