[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
こちらも合わせてお読みください。
今回は「カーネル」について解説します。
カーネルというとよく意味が取れない方もいらっしゃるかも知れません。
OpenCLでカーネルというと、GPUで動かす関数のことです。
前回登場した「プログラム」との違いを言うと、カーネルは関数であるのに対し、プログラムはカーネルの塊である、といったところでしょうか。
今回することを3つにまとめるとこうなります:
今回はすることは3つあります。
それらを行うメソッドを一つ一つ紹介します。
まずはカーネルの生成を行うメソッドから。
Program.CreateKenerlメソッドです。
public Kernel CreateKernel(string kernelName);
kernelNameは関数名です。
次はカーネルに引数をセットするメソッドです。
Kernel.SetArgメソッドです。
public void SetArg(int argIndex, byte c); public void SetArg(int argIndex, Char16 c); public void SetArg(int argIndex, Char2 c); public void SetArg(int argIndex, Char3 c); public void SetArg(int argIndex, Char4 c); public void SetArg(int argIndex, Char8 c); public void SetArg(int argIndex, double c); public void SetArg(int argIndex, Double16 c); public void SetArg(int argIndex, Double2 c); public void SetArg(int argIndex, Double3 c); public void SetArg(int argIndex, Double4 c); public void SetArg(int argIndex, Double8 c); public void SetArg(int argIndex, float c); public void SetArg(int argIndex, Float16 c); public void SetArg(int argIndex, Float2 c); public void SetArg(int argIndex, Float3 c); public void SetArg(int argIndex, Float4 c); public void SetArg(int argIndex, Float8 c); public void SetArg(int argIndex, int c); public void SetArg(int argIndex, Int16 c); public void SetArg(int argIndex, Int2 c); public void SetArg(int argIndex, Int3 c); public void SetArg(int argIndex, Int4 c); public void SetArg(int argIndex, Int8 c); public void SetArg(int argIndex, IntPtr c); public void SetArg(int argIndex, long c); public void SetArg(int argIndex, Long16 c); public void SetArg(int argIndex, Long2 c); public void SetArg(int argIndex, Long3 c); public void SetArg(int argIndex, Long4 c); public void SetArg(int argIndex, Long8 c); public void SetArg(int argIndex, Mem mem); public void SetArg(int argIndex, Sampler sampler); public void SetArg(int argIndex, sbyte c); public void SetArg(int argIndex, short c); public void SetArg(int argIndex, Short16 c); public void SetArg(int argIndex, Short2 c); public void SetArg(int argIndex, Short3 c); public void SetArg(int argIndex, Short4 c); public void SetArg(int argIndex, Short8 c); public void SetArg(int argIndex, UChar16 c); public void SetArg(int argIndex, UChar2 c); public void SetArg(int argIndex, UChar3 c); public void SetArg(int argIndex, UChar4 c); public void SetArg(int argIndex, UChar8 c); public void SetArg(int argIndex, uint c); public void SetArg(int argIndex, UInt16 c); public void SetArg(int argIndex, UInt2 c); public void SetArg(int argIndex, UInt3 c); public void SetArg(int argIndex, UInt4 c); public void SetArg(int argIndex, UInt8 c); public void SetArg(int argIndex, ulong c); public void SetArg(int argIndex, ULong16 c); public void SetArg(int argIndex, ULong2 c); public void SetArg(int argIndex, ULong3 c); public void SetArg(int argIndex, ULong4 c); public void SetArg(int argIndex, ULong8 c); public void SetArg(int argIndex, ushort c); public void SetArg(int argIndex, UShort16 c); public void SetArg(int argIndex, UShort2 c); public void SetArg(int argIndex, UShort3 c); public void SetArg(int argIndex, UShort4 c); public void SetArg(int argIndex, UShort8 c); public void SetArg(int argIndex, IntPtr argSize, IntPtr argValue);
多いですね。
しかし今回使うのはSetArg(int argIndex, Mem mem)だけです。
argIndexは引数の位置です。例えば最初の引数なら0です。
最後はカーネルの実行を行うCommandQueue.EnqueueTaskメソッドを紹介します。
public void EnqueueTask(Kernel kernel);
kernelは実行するカーネルです。
using OpenCLNet; class Program { static void Main() { var platform = OpenCL.GetPlatform(0); var context = platform.CreateDefaultContext(); var commandQueue = context.CreateCommandQueue(platform.QueryDevices(DeviceType.DEFAULT)[0]); var program = context.CreateProgramWithSource( System.IO.File.ReadAllText("myKernelProgram.cl") ); program.Build(); var kernel = program.CreateKernel("myKernelFunction"); var buffer = context.CreateBuffer(MemFlags.READ_WRITE, 3 * sizeof(float)); kernel.SetArg(0, buffer); commandQueue.EnqueueTask(kernel); float[] readBack = new float[3]; buffer.Read(commandQueue, 0, readBack, 0, readBack.Length); foreach (var number in readBack) { System.Console.WriteLine(number); } buffer.Dispose(); kernel.Dispose(); program.Dispose(); commandQueue.Dispose(); context.Dispose(); } }
__kernel void myKernelFunction(__global float* numbers) { numbers[0] = 3; numbers[1] = 4; numbers[2] = 5; }
このプログラムは実行すると次のような結果になります:
3 4 5