1

OpenCL (Cloo.dll) を使用して C# でプログラムを作成していますが、大きなバッファを OpenCL ComputeDevice に渡す必要があります。このバッファを OpenCL ComputeDevice に渡すと、例外やエラーなしでプログラムがクラッシュします。

コード:

    ComputeBuffer<Byte> dataBuffer = new ComputeBuffer<Byte>(this._context,
        ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, data.LongLength, ptrData);
    ComputeBuffer<Byte> keysBuffer = new ComputeBuffer<Byte>(this._context,
        ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, Keys);
    ComputeBuffer<Byte> resultBuffer = new ComputeBuffer<Byte>(this._context,
        ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.CopyHostPointer, result.LongLength, ptrResult);


    this._kernel = this._program.CreateKernel("AES_ECB_Encrypt");

    this._kernel.SetMemoryArgument(0, dataBuffer);
    this._kernel.SetMemoryArgument(1, keysBuffer);
    this._kernel.SetValueArgument<int>(2, 10);
    this._kernel.SetValueArgument<long>(3, data.LongLength);
    this._kernel.SetMemoryArgument(4, resultBuffer);

    ComputeDevice bestDevice = this._devices[0];

    this._queue = new ComputeCommandQueue(this._context, bestDevice, ComputeCommandQueueFlags.None);
    this._queue.Execute(this._kernel, null, new long[] {data.LongLength}, null, null); // here is the crash.

OpenCL カーネル:

kernel void AES_ECB_Encrypt(__global uchar16* InputData,__global uchar16* Keys,int GRounds,ulong GLength,__global uchar16* Result)
{
    int Index=get_global_id(0);

    int Rounds=GRounds;
    ulong Length=GLength;

    if (Index<Length){
        uchar16 State=TurnData(InputData[Index]);

        State=AddRoundKey(State,Keys[0]);

        for (int round=1;round<Rounds;round++){
            State=SubBytes(State);
            State=ShiftRows(State);
            State=MixColumns(State);
            State=AddRoundKey(State,Keys[round]);}


        State=SubBytes(State);
        State=ShiftRows(State);
        State=AddRoundKey(State,Keys[Rounds]);

        Result[Index]=TurnData(State);}
}

ComputeDevice.MaxParameterSize - デバイスに渡すことができるパラメーターの最大サイズについて読みました。私の考えでは、問題はここにあります。小さなバッファー (サイズが 1KB 未満) をうまく渡すことができるからです。私のデバイスの MaxParameterSizes は 1024 バイトと 4096 バイトですが、これらの値は非常に小さいです。サイズが 100 MB を超えるバッファを渡す必要があります。

大きなバッファをデバイスに渡すにはどうすればよいですか? このバッファへのポインタのみを渡すことはできますか?

私の OpenCL デバイス:

AMD Radeon HD8750M 2048MB、

Intel Core I3 4000M + 6GB RAM

編集

カーネルがuchar16データを扱うため、GlobalSize を に設定する必要がありbuffer.size / 16ます。

コードを 1 行だけ変更しました (バッファー サイズは 16 で除算されます)。

this._queue.Execute(this._kernel, null, new long[] {data.LongLength/16}, null, null);

すべて正常に動作します。みんな、ありがとう!!!)

4

1 に答える 1