I'm writing a program on C# using OpenCL (Cloo.dll) and i need to pass the large buffer to OpenCL ComputeDevice. When I pass this buffer to OpenCL ComputeDevice - program crashes without any exception or error.
Code:
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:
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);}
}
I read about ComputeDevice.MaxParameterSize - maximum size of parameter that can be passed to device. To my mind, the problem is here, because small buffers (size < 1KB) can be passed well. MaxParameterSizes in my devices are 1024 and 4096 bytes, but these values are very small. I need to pass buffers with size over 100 MB.
How can I pass a large buffer to device? Can I pass only a pointer to this buffer?
My OpenCL Devices:
AMD Radeon HD8750M 2048MB,
Intel Core I3 4000M + 6GB RAM
Edited:
Because of kernel works with uchar16
data, i have to set GlobalSize as buffer.size / 16
.
I only changed one line of code(buffer size divides by 16):
this._queue.Execute(this._kernel, null, new long[] {data.LongLength/16}, null, null);
Everything works fine. Thanks everyone!!!)