[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
こちらも合わせてお読みください。
今回は「カーネル」について解説します。
カーネルというとよく意味が取れない方もいらっしゃるかも知れません。
OpenCLでカーネルというと、GPUで動かす関数のことです。
前回登場した「プログラム」との違いを言うと、カーネルは関数であるのに対し、プログラムはカーネルの塊である、といったところでしょうか。
今回することを3つにまとめるとこうなります:
今回はすることは3つあります。
それらを行うメソッドを一つ一つ紹介します。
まずはカーネルの生成を行うメソッドから。
ComputeProgram.CreateKenerlメソッドです。
public ComputeKernel CreateKernel(string kernelName);
kernelNameは関数名です。
次はカーネルに引数をセットするメソッドです。
ComputeKernel.SetMemoryArgumentメソッドです。
public void SetMemoryArgument(int index, ComputeMemory memObj);
indexは引数の位置です。例えば最初の引数なら0です。
最後はカーネルの実行を行うComputeCommandQueue.ExecuteTaskメソッドを紹介します。
public void ExecuteTask(ComputeKernel kernel, ICollection<ComputeEventBase> events);
kernelは実行するカーネルです。
eventsにはとりあえずnullを入れましょう。
using Cloo; using System.Linq; class Program { static void Main() { ComputePlatform platform = ComputePlatform.Platforms[0]; ComputeDevice[] devices = platform .Devices .Where(d => d.Type == ComputeDeviceTypes.Gpu) .ToArray(); ComputeContext context = new ComputeContext( devices, new ComputeContextPropertyList(platform), null, System.IntPtr.Zero ); ComputeProgram program = new ComputeProgram( context, System.IO.File.ReadAllText("myKernelProgram.cl") ); program.Build(devices, null, null, System.IntPtr.Zero); ComputeKernel kernel = program.CreateKernel("myKernelFunction"); const int bufferNumberCount = 3; ComputeBuffer<float> buffer = new ComputeBuffer<float>( context, ComputeMemoryFlags.ReadWrite, bufferNumberCount); kernel.SetMemoryArgument(0, buffer); ComputeCommandQueue commandQueue = new ComputeCommandQueue( context, devices[0], ComputeCommandQueueFlags.None ); commandQueue.ExecuteTask(kernel, null); float[] dataFromGpu = new float[bufferNumberCount]; commandQueue.ReadFromBuffer(buffer, ref dataFromGpu, true, null); foreach (var number in dataFromGpu) { System.Console.WriteLine(number); } commandQueue.Dispose(); buffer.Dispose(); kernel.Dispose(); program.Dispose(); context.Dispose(); } }
__kernel void myKernelFunction(__global float* numbers) { numbers[0] = 3; numbers[1] = 4; numbers[2] = 5; }
このプログラムは実行すると次のような結果になります:
3 4 5