Я использую JavaCL для обработки изображений.Я продолжаю получать
com.nativelibs4java.opencl.CLException $ InvalidKernelArgs: InvalidKernelArgs
При вызове enqueueNDRange вызов в этом (часть)функция:
FloatBuffer outBuffer = ByteBuffer.allocateDirect(4*XYZ.length).order(context.getByteOrder()).asFloatBuffer();
CLFloatBuffer cl_outBuffer = context.createFloatBuffer(CLMem.Usage.Output, outBuffer, false);
CLFloatBuffer cl_inBuffer = context.createFloatBuffer(CLMem.Usage.Input,XYZ.length);
FloatBuffer inBuffer = cl_inBuffer.map(queue, CLMem.MapFlags.Write).put(XYZ);
inBuffer.rewind();
event = cl_inBuffer.unmap(queue, inBuffer);
XYZ2RGBKernel.setArgs(cl_inBuffer, XYZ.length/4,cl_outBuffer);
event = XYZ2RGBKernel.enqueueNDRange(queue, new int[]{XYZ.length/4}, event);
event = cl_outBuffer.read(queue, outBuffer, true, event);
XYZ - массив пикселей с 4 числами на пиксель (закодированный как RGBARGBARGBA ....)
Связанный заголовок ядра:
__kernel void XYZ2RGB( __constant float3* inputXYZ,
int numberOfPixels,
__global float* output
)
Я не могу понять, почему это не работает, так как этот вызов enqueueNDRange:
CLFloatBuffer cl_Rbuffer = context.createFloatBuffer(CLMem.Usage.Input, R.length);
FloatBuffer R_buffer = cl_Rbuffer.map(queue, CLMem.MapFlags.Write).put(R);
R_buffer.rewind();
event = cl_Rbuffer.unmap(queue, R_buffer);
CLFloatBuffer cl_Gbuffer = context.createFloatBuffer(CLMem.Usage.Input, G.length);
FloatBuffer G_buffer = cl_Gbuffer.map(queue, CLMem.MapFlags.Write, event).put(G);
G_buffer.rewind();
event = cl_Gbuffer.unmap(queue, G_buffer);
CLFloatBuffer cl_Bbuffer = context.createFloatBuffer(CLMem.Usage.Input, B.length);
FloatBuffer B_buffer = cl_Bbuffer.map(queue, CLMem.MapFlags.Write, event).put(B);
B_buffer.rewind();
event = cl_Bbuffer.unmap(queue, B_buffer);
FloatBuffer outBuffer = ByteBuffer.allocateDirect(4*4*R.length).order(context.getByteOrder()).asFloatBuffer();
CLFloatBuffer cl_outBuffer = context.createFloatBuffer(CLMem.Usage.Output, outBuffer, false);
RGB2XYZKernel.setArgs(cl_Rbuffer, cl_Gbuffer, cl_Bbuffer, cl_outBuffer);
event = RGB2XYZKernel.enqueueNDRange(queue, new int[]{R.length}, event);
event = cl_outBuffer.read(queue, outBuffer, true, event);
Со связанным заголовком ядра:
__kernel void RGB2XYZ( __constant float* inputR,
__constant float* inputG,
__constant float* inputB,
__global float3* output)
Работает без проблем.
Прежде чем кто-либо спросит, float3 или float4 будут работать одинаково, потому что спецификации OpenCL используют 4 * sizeof (float) выравнивание для обоих.И я пробовал переключаться между ними.Я также попытался передать ввод как float *, но он тоже не работает.Оба вызова происходят один за другим.
Обновление
Я исправил это после нескольких часов:
- __ константа, кажется, имеет ограничение размера (не удалось найтичто в спецификации хотя).XYZ в 4 раза больше R, G или B, он завис во время выполнения.
- У меня были проблемы с float3.Кажется, что библиотека, которую я вынужден использовать, не обновлена, и поэтому она не была достаточно хорошо поддержана, поэтому я перешел на float4
Однако, если у кого-то из вас есть какие-тобольше информации о __constant ограничение размера и прочее, дайте мне знать, я уверен, что это будет полезно для людей, которые столкнутся с этой темой.