ich die Python-Bindings für OpenCL verwende, und ich habe einen Kernel geschrieben, die einen skalaren (float) Argument erwartet, aber ich kann die richtige Art und Weise nicht herausfinden, es zu passieren in.Wie übergebe ich in Python ein skalares Argument an einen OpenCL-Kernel?
Wenn ich einfach
aufrufenprg.bloop(queue, [width,height], None, centers_g, 16/9, result_g)
ich diesen Fehler:
pyopencl.cffi_cl.LogicError: when processing argument #2 (1-based): 'float' does not support the buffer interface
wenn ich es mit numpy.float32(16/9)
wickeln dann der Kernel verhält, als ob es 0 statt 1,7777777 geben wurden.
Hier ist mehr von dem Quellcode für den Fall, dass Sie verstehen, was ich mache.
def mission2(cells, width, height):
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
centers = numpy.array(list(cells), dtype=numpy.float32)
centers_g = cl.Buffer(ctx, cl.mem_flags.READ_ONLY|cl.mem_flags.COPY_HOST_PTR, hostbuf = centers)
prg = cl.Program(ctx, """
__kernel void test1(__global char *out) {
out[0] = 77;
}
float sphere(float r, float x, float y)
{
float q = r*r-(x*x+y*y);
if (q<0)
return 0;
return sqrt(q);
}
__kernel void bloop(__global const float centers[][6], float aspect, __global char * out)
{
int u = get_global_id(0);
int v = get_global_id(1);
int width = get_global_size(0);
int height = get_global_size(1);
float x = u/(float)width * aspect;
float y = v/(float)height;
float max = sphere(0.3, x-centers[0][0], y-centers[0][1]);
int idx = u+v*width;
out[idx] = 255*max;
}
""").build()
result_g = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY, width*height)
if False:
prg.test1(queue, [width,height], None, result_g)
else:
prg.bloop(queue, [width,height], None, centers_g, numpy.float32(16/9), result_g)
result = numpy.zeros([height,width], dtype=numpy.uint8)
future = cl.enqueue_copy(queue, result, result_g)
future.wait()
print(result)
imsave("/tmp/bloop.png", result, cmap = matplotlib.pyplot.get_cmap('gray'))
Sind Sie sicher, dass es sich nicht so verhält, als wäre es 1? 16/9 gibt 1 in Python 2. Wrapping in numpy.float32 ist was ich mache, wenn ich PyOpenCL benutze und es funktioniert hier. –
Center ist nicht in Ihrem Kernel definiert. Es ist in Ihrem Host-Code definiert. Der Fehler sagt es: Buffer-Schnittstelle ist nicht für Floats definiert. "Zentren" ist ein Float. Also Zentren [] [6] ist illegal. – Dschoni
Ich benutze nicht Python 2. Dies ist eine Python 3 App und wenn ich 'print (16/9)' es gibt mir definitiv 1.77777. –