gpt4 book ai didi

java - enqueueNDRange上的InvalidKernelArgs,而类似的调用工作正常

转载 作者:行者123 更新时间:2023-12-03 17:02:08 26 4
gpt4 key购买 nike

我正在使用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 *传递,但它也不起作用。
两个 call 都接连发生。

更新资料

经过几个小时,我将其修复:
  • __constant似乎有一个大小限制(尽管在规范中找不到)。 XYZ是R,G或B大小的4倍,它在运行时崩溃。
  • 之后我遇到了float3的问题。似乎我被迫使用的库不是最新的,因此没有得到足够的支持,所以我切换到float4

  • 但是,如果您对__constant大小限制和内容有更多了解,请告诉我,我相信这对于遇到此问题的人员将非常有用。

    最佳答案

    __constant seems to have a size limit (couldn't find that in the specs though).


    限制取决于设备。常量缓冲区有每个缓冲区的大小限制(CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,最小64KB),并且对可以传递给内核的常量参数的数量也有限制(CL_DEVICE_MAX_CONSTANT_ARGS,最小8)。 AMD和Nvidia GPU通常都接近最小值,因此可以作为__constant传递的数据总量可能很小。
    “恒定”内存的目的不是将只读的输入用户数据传递给内核(就像您正在使用的那样);重点是存储特定于算法的常量(查找表,矩阵/多项式/滤波器系数等)。如果要传递只读输入数据,通常的方法是将内核参数声明为 __global const <type>*,并使用 CL_MEM_READ_ONLY创建相应的缓冲区。
    Here有更多见识。

    关于java - enqueueNDRange上的InvalidKernelArgs,而类似的调用工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54971253/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com