Main Content

本页采用了机器翻译。点击此处可查看最新英文版本。

运行包含 CUDA 代码的 MEX 函数

编写包含 CUDA 代码的 MEX 文件

所有 MEX 文件(包括包含 CUDA® 代码的文件)都有一个称为 mexFunction 的入口点。MEX 函数包含与来自 MATLAB®gpuArray 对象交互并启动 CUDA 代码的主机端代码。MEX 文件中的 CUDA 代码必须符合 CUDA 运行时 API。

您必须在 MEX 文件的入口处调用 mxInitGPU 函数,以确保 GPU 设备已正确初始化并且为 MATLAB 所知。

用于为 gpuArray 对象编写 MEX 文件的接口与标准 MATLAB 数组的 MEX 接口不同。

您可以在此处看到包含 CUDA 代码的 MEX 文件示例:

该文件包含此 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 以获取输出数组中的值。为了测试函数,从每个元素都是 1 的 gpuArray 矩阵开始:

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 对象。

与 CUDA 内核比较

Parallel Computing Toolbox™ 软件还支持 CUDAKernel 对象,您可以使用它将 CUDA 代码与 MATLAB 集成。您可以使用 CU 和 PTX 文件创建 CUDAKernel 对象。通常,使用 MEX 文件比使用 CUDAKernel 对象更灵活,因为:

  • MEX 文件可以包含对主机端库的调用,包括 NVIDIA® 库,例如 NVIDIA 性能原语 (NPP) 或 cuFFT 库。MEX 文件还可以包含主机对 CUDA 运行时库中的函数的调用。

  • MEX 文件可以分析输入的大小并从 C 或 C++ 代码分配不同大小的内存,或者启动不同大小的网格。相比之下,调用 CUDAKernel 对象的 MATLAB 代码必须预先分配输出内存并确定网格大小。

访问复杂数据

GPU 设备上的复杂数据以交错复杂格式存储。也就是说,对于复数 gpuArray A,每个元素的实部和虚部都存储在连续的地址中。MATLAB 使用 CUDA 内置向量类型在设备上存储复数数据。有关更多信息,请参阅 NVIDIA CUDA C++ 编程指南

根据内核的需要,您可以将指向复杂数据的指针转换为实数类型或内置向量类型。例如,在 MATLAB 中,假设您创建了以下矩阵:

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

如果将 gpuArray 作为第一个参量 prhs[0] 传递给 MEX 函数,那么您可以使用以下调用获取指向复杂数据的指针:

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));

您可以使用这些 Parallel Computing Toolbox 函数在 GPU 上在复数格式和实数格式之间转换数据。这些操作需要副本来交错数据。

mxGetImagData 函数没有与 mxGPUArray 对象等效的函数。

编译 GPU MEX 文件

使用 MATLAB 中的 mexcuda 函数编译包含 CUDA 代码的 MEX 文件。默认情况下,mexcuda 函数使用随 MATLAB 一起安装的 NVIDIA CUDA 编译器(nvcc)编译 CUDA 代码。该软件将进一步的编译步骤转发到系统上安装的 C++主机编译器。要检查 mexcuda 正在使用哪个编译器,请在 mexcuda 函数中使用 -v 标志进行详细输出。

mexcuda mexGPUExample.cu

如果 mexcuda 无法找到 nvcc,则它可能安装在非默认位置。您可以通过将 nvcc 存储在 MW_NVCC_PATH 环境变量中来指定系统上它的位置。您可以使用 setenv 命令设置此变量。例如:

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

支持的主机编译器

要使用 mexcuda 函数编译 MEX 文件,您必须安装受支持的 C++主机编译器。mexcuda 仅支持 Visual Studio® 编译器的子集。要确定您的编译器是否受支持,请按照下列步骤操作:

  1. 通过查阅 安装 CUDA 工具包(可选) 中的表来确定 MATLAB 版本使用的是 CUDA 哪个版本。

  2. 查阅与步骤 1 中确定的 CUDA 版本对应的 NVIDIA CUDA 工具包文档。文档在安装指南部分列出了支持的编译器。

安装 CUDA 工具包(可选)

与 MATLAB 一起安装的 CUDA 工具包不包含 CUDA 工具包中可用的所有库。如果要使用未随 MATLAB 安装的特定库,请安装 CUDA 工具包。

注意

您不需要 CUDA 工具包来在 GPU 上运行 MATLAB 函数或生成支持 CUDA 的 MEX 函数。

CUDA 工具包包含用于编译的 CUDA 库和工具。

为您所使用的 MATLAB 版本下载适当的 CUDA 工具包版本。使用此表检查哪个版本的工具包与您的 MATLAB 版本兼容。建议的最佳做法是使用受支持的 CUDA 工具包的最新版本,包括来自 NVIDIA 的任何更新和补丁。

MATLAB 版本CUDA 工具包版本
R2024a12.2
R2023b11.8
R2023a11.8
R2022b11.2
R2022a11.2
R2021b11.0
R2021a11.0
R2020b10.2
R2020a10.1
R2019b10.1
R2019a10.0
R2018b9.1
R2018a9.0
R2017b8.0
R2017a8.0
R2016b7.5
R2016a7.5
R2015b7.0
R2015a6.5
R2014b6.0
R2014a5.5
R2013b5.0
R2013a5.0
R2012b4.2
R2012a4.0
R2011b4.0

有关 CUDA 工具包的更多信息以及下载支持的版本,请参阅 CUDA 工具包存档 (NVIDIA)

另请参阅

| |

相关主题