此示例演示如何通过实现John H.Conway的“生命游戏”,为模具类型操作生成CUDA®内核。
“生命游戏”是一个零玩家细胞自动机由一组细胞组成的游戏(人口)在矩形网格(宇宙).细胞以离散的时间步进化,称为一代又一代.一套应用于细胞及其邻近细胞的数学规则控制它们的生、死和繁殖。这个“生活游戏”的实现是基于电子书中提供的示例MATLAB中的实验由Cleve Moler提供。实施遵循以下规则:
单元排列在二维网格中。
在每一步中,每个细胞的八个近邻的生命力决定了它的命运。
任何有三个邻居的细胞在下一步就会有生命。
一个有两个邻居的活细胞在下一步仍然是活的。
所有其他单元格(包括有三个以上邻居的单元格)都会在下一步死亡或保持空状态。
下面是一些单元格如何更新的示例。
许多数组操作可以表示为钢网操作,其中输出数组的每个元素依赖于输入数组的一个小区域。本例中的模具是每个单元周围的3×3区域。有限差分、卷积、中值滤波和有限元方法是模板处理可以执行的其他操作的示例。
CUDA®支持NVIDIA®GPU,具有3.2或更高的计算能力。
NVIDIA CUDA工具包和驱动程序。
编译器和库的环境变量。有关编译器和库支持的版本的信息,请参见万博1manbetx第三方产品s manbetx 845. 有关设置环境变量的信息,请参见设置前提产品s manbetx 845.
要验证运行此示例所需的编译器和库是否正确设置,请使用coder.checkGpuInstall
函数。
envCfg=coder.gpuEnvConfig(“主持人”);envCfg。BasicCodegen = 1;envCfg。安静= 1;coder.checkGpuInstall (envCfg);
由于游戏是零玩家,游戏的演化由其初始状态决定。例如,在二维网格上创建初始细胞群,约25%的位置处于活动状态。
gridSize = 500;numGenerations = 100;initialGrid = (rand(gridSize,gridSize) > .75);%绘制初始网格显示亮度图像(initialGrid);Colormap ([1 1 1;0 0.5 0]);标题(“初始网格”);
的原始生命的游戏函数是“Game of Life”的完全矢量化实现。该函数每次生成一个单元格就更新网格上的所有单元格。
类型生命起源游戏
%%MATLAB矢量化实现函数网格=gameoflife_orig(initialGrid)%2016-2019版权所有MathWorks,Inc.numGenerations=100;网格=初始网格;[gridSize,~]=大小(初始网格);%循环通过每一代更新网格并显示它。对于generation=1:numGenerations grid=updateGrid(grid,gridSize);imagesc(网格);彩色地图([11;0.50]);标题([“迭代时的网格”,num2str(生成)];现在抽;end function X=updateGrid(X,N)%Index向量将中心索引增加或减少1%,从而访问左、右、上和下的邻居。p=[11:N-1];q=[2:N];%数一数八个邻居中有多少人还活着。邻居=X(:,p)+X(:,q)+X(p,:)+X(q,:)+。。。X(p,p)+X(q,q)+X(p,q)+X(q,p);%具有两个活动邻居的活动单元或具有%3个活动邻居的任何单元在下一步处于活动状态。X=(X&(邻居==2))|(邻居==3);结束
通过调用。来玩游戏生命起源游戏
具有初始总体的函数。游戏会在100代中迭代,并在每一代中显示人口。
gameoflife_orig (initialGrid);
看一下updateGrid
函数时,显然相同的操作分别应用于每个网格位置。然而,每个细胞必须知道它的八个邻居。修改后的gameoflife_模具函数使用gpucoder.stencilKernel
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) [winH, winW] = size(window);邻居= 0;for wh = 1:winH 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);end end X = (window(2,2) & (neighbors == 2))) | (neighbors == 3); end
要生成CUDA MEX,请执行以下操作:gameoflife_stencil
函数,创建GPU代码配置对象,然后使用codegen
命令。
cfg = coder.gpuConfig (墨西哥人的);评估('codegen -config cfg -args {initialGrid} gameoflife_stencil');
运行生成的gameoflife_stencil_mex
随机初始总体。
gridGPU = gameoflife_stencil_mex (initialGrid);%100代后绘制网格显示亮度图像(gridGPU);Colormap ([1 1 1;0 0.5 0]);标题(“最终网格-CUDA MEX”);
CUDA代码是为一个简单的模具操作生成的,康威的“生命游戏”gpucoder.stencilKernel
您可以使用本例中显示的技术来实现一系列模板操作,包括有限元算法、卷积和过滤器。