这个例子展示了如何通过执行John H. Conway的“Game of Life”来生成用于模板类型操作的CUDA®内核。
《Game of Life》是一个零玩家细胞自动机由一系列细胞组成的游戏(人口)在矩形网格中(宇宙).细胞按离散时间步进化,称为几代人。应用于细胞的一组数学规则及其邻居控制他们的生命,死亡和再现。这种“生命游戏”实现基于电子书中提供的示例Matlab的实验由克里夫硅藻土。实施遵循以下规则:
单元格按二维网格排列。
在每个步骤中,每个细胞的八个最近邻居的活力决定了其命运。
任何一个具有恰好三个现场邻居的细胞都在下一步来到生命。
一个带有恰好两个现场邻居的活细胞在下一步中保持活力。
所有其他细胞(包括具有超过三个邻居的细胞)在下一步中死亡,或者保持空。
以下是如何更新单元格的一些示例。
许多数组操作可以表示为模版操作,其中输出数组的每个元素依赖于输入数组的一个小区域。本例中的模板是每个单元格周围的3x3区域。有限差分、卷积、中值滤波和有限元方法是模板处理可以执行的其他操作的例子。
要求
本例生成CUDA MEX,并具有以下第三方需求。
CUDA支持NVIDIA®GPU和兼容驱动程序。
可选的
对于非mex构建,如静态、动态库或可执行文件,本例有以下附加要求。
英伟达工具包。
编译器和库的环境变量。有关更多信息,请参见第三方硬件和设置先决条件产品下载188bet金宝搏。
要验证运行此示例所需的编译器和库是否正确设置,请使用coder.checkGpuInstall
功能。
envCfg = coder.gpuEnvConfig (“主机”);Envcfg.basicCodegen = 1;Envcfg.quiet = 1;Coder.CheckGpuInstall(Envcfg);
因为游戏是零玩家,所以游戏的发展取决于它的初始状态。对于本例,在一个二维网格上创建了一个初始的细胞群,其中大约25%的位置是活的。
gridsize = 500;numgenerations = 100;initialGrid =(RAND(GridSize,Gridsize)> .75);%绘制初始网格ImagesC(初始奖金);Colormap ([1 1 1;0 0.5 0]);标题(“初始网格”);
这gameoflife_orig.m
功能是完全矢量化的“生命游戏”的实现。该函数在每个生成的一次通行证中更新网格上的所有单元格。
类型gameoflife_orig
%% MATLAB矢量化实现函数grid = gameoflife_origin (initialGrid) % Copyright 2016-2019 The MathWorks, Inc. numGenerations = 100;网格= initialGrid;[gridSize ~] =大小(initialGrid);%循环每一代更新网格并显示它。for generation = 1:numGenerations grid = updateGrid(grid, gridSize);显示亮度图像(网格);Colormap ([1 1 1;0 0.5 0]);title(['Grid at Iteration ',num2str(generation)]);drawnow;索引向量增加或减少居中索引1%,从而访问左、右、上、下的邻居。 p = [1 1:N-1]; q = [2:N N]; % Count how many of the eight neighbors are alive. neighbors = X(:,p) + X(:,q) + X(p,:) + X(q,:) + ... X(p,p) + X(q,q) + X(p,q) + X(q,p); % A live cell with two live neighbors, or any cell with % three live neighbors, is alive at the next step. X = (X & (neighbors == 2)) | (neighbors == 3); end end
通过打电话来玩游戏gameoflife_orig
功能初始群体。游戏通过100代迭代并显示每代人口。
gameoflife_orig(initialGrid);
看着计算的计算updateGrid
功能,很明显,相同的操作是独立地在每个网格位置应用。但是,每个单元格必须知道其八个邻居。修改了gameoflife_stencil.m
函数使用gpucoder.stildkernel.
pragma以在每个单元格周围计算3×3区域。模板内核的GPU编码器™实现计算每个线程中网格的一个元素,并使用共享存储器来改善内存带宽和数据局部。
类型gameoflife_stencil.
function grid = gameoflife_stencil(initialGrid) %#codegen % Copyright 2016-2019 The MathWorks, Inc. numGenerations = 100;网格= initialGrid;%循环每代更新网格。for generation = 1:numGenerations grid = gpucoder. for generation = 1:numGenerationsstencilKernel(@updateElem, grid, [3,3], 'same');X = updateElem(window) neighbors = window(1,1) + window(1,2) + window(1,3)…+ window(2,1) + window(2,3)…+ window(3,1) + window(3,2) + window(3,3);X = (window(2,2) & (neighbors == 2))) | (neighbors == 3);结束
要生成CUDA MEXgameoflife_stencil.
函数,创建图形处理器代码配置对象,然后使用Codegen.
命令。
cfg = coder.gpuconfig('mex');evalc ('codegen -config cfg -args {itialgrid} gameoflife_stencil');
运行生成的gameoflife_stcencil_mex.
随着随机初始人口。
gridgpu = gameoflife_stcence_mex(initialGrid);%在100代之后绘制网格ImagesC(GridGPU);Colormap ([1 1 1;0 0.5 0]);标题(“最终网格- CUDA MEX”);
Codegen.
|coder.gpu.kernel.
|coder.gpu.kernelfun.
|gpucoder.matrixMatrixKernel
|coder.gpu.constantmemory.
|gpucoder.stildkernel.
|coder.checkGpuInstall