主要内容

coder.gpu.nokernel

为循环禁用内核创建的Pragma

描述

例子

coder.gpu.nokernel ()是一个循环级别的pragma,当放置在for循环之前阻止代码生成器生成CUDA®循环中语句的内核。此pragma不需要任何输入参数。

这个函数是一个代码生成函数。在MATLAB中没有影响®

例子

全部折叠

这个例子展示了如何使用nokernelpragma,并防止代码生成器为循环中的语句生成CUDA内核

在一个文件中,编写入口点函数nestedLoop它接受两个向量输入A、B的大小32 x512.该函数有两个嵌套不同迭代长度的循环,一个用于沿列操作,一个用于沿行操作。第一个嵌套循环计算两个向量输入的和,而第二个嵌套循环将和缩放为3倍。

函数[C] = nestedLoop(A, B); [C] = nestedLoop(A, B);C = 0 (32, 512);coder.gpu.kernelfun ();%这个嵌套循环将被融合i = 1时32分G(i,j) = A(1,j) + B(1,j);结束结束coder.gpu.nokernel ();i = 1时32分C(i,j) = G(i,j) * 3;结束结束结束

使用codegen函数生成CUDA MEX函数。

cfg = coder.gpuConfig (墨西哥人的);cfg。GenerateReport = true;codegen配置cfgarg游戏{的(1512年,“双”)的(1512年,“双”)}nestedLoop

GPU编码器创建两个内核:nestedLoop_kernel1执行计算G(i,j) = A(1,j) + B(1,j);第一个嵌套循环的nestedLoop_kernel2内核执行计算C(i,j) = G(i,j) * 3;第二个嵌套循环的。第二个内核是为第二个嵌套循环的内部循环创建的。的noKernelPragma仅适用于紧跟在语句后面的循环。生成的内核代码片段将显示出来。

static __global__ __launch_bounds__(512, 1) void nestedLoop_kernel1(const real_T B[512], const real_T A[512], real_T G[16384]) {uint32_T threaddid;...if (i < 32) {G[i + (j << 5)] = A[j] + B[j];}} static __global__ __launch_bounds__(512, 1) void nestedLoop_kernel2(real_T G [16384], int32_T i, real_T C[16384]) {uint32_T threaddid;…;如果(< 512){C (i + (j < < 5)] = [i + G (< < 5)) * 3.0;}

main函数的一个片段显示,代码生成器已经融合了内核启动参数所指示的第一个嵌套循环。如前所述,第二个嵌套循环的外层循环是没有映射到内核的循环。因此,代码生成器放置一个for循环语句就在调用第二个CUDA内核之前nestedLoop_kernel2

void nestedLoop(const real_T A[512], const real_T B[512], real_T C[16384]) {int32_T i;...//这两个循环将被融合cudaMemcpy(gpu_B, (void *)&B[0], 4096UL, cudaMemcpyHostToDevice);cudaMemcpy(gpu_A, (void *)& &A[0], 4096UL, cudaMemcpyHostToDevice);nestedLoop_kernel1 < < < dim3 (32 u, 1 u, 1 u), dim3 (512 u, 1 u, 1 u) > > > (* gpu_B, * gpu_A, * gpu_G);For (i = 0;我< 32;我+ +){nestedLoop_kernel2 < < < dim3 (1 u, 1 u, 1 u), dim3 (512 u, 1 u, 1 u) > > > (* gpu_G, * gpu_C);C_dirtyOnGpu = true;}…… cudaFree(*gpu_C); }
介绍了R2019a