主要内容

coder.gpu.nokernel

Pragma禁用循环的内核创建

描述

例子

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

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

例子

全部折叠

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

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

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

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

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

GPU Coder创建了两个内核: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 threadId;…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 threadId;…;如果(< 512){C (i + (j < < 5)] = [i + G (< < 5)) * 3.0;}

主函数的一个片段显示,代码生成器已经融合了第一个嵌套循环,如内核的launch参数所示。如前所述,第二个嵌套循环的外部循环是没有映射到内核的那个循环。因此,代码生成器放置一个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

Baidu
map