0

我一直在尝试学习 OpenCL,但偶然发现了一个问题。在下面的代码中,我创建了一个空的 write_only opencl 图像对象并尝试让一个简单的内核变黑(或者至少以某种方式更改它),但是它只返回一个空图像。(我正在做一个图像卷积练习,它一直返回一个空图像,下面的代码只是试图隔离问题。)

我已经搞砸了2个多小时了,我很确定我被卡住了。

import matplotlib.pyplot as plt
import scipy.ndimage as si
import pyopencl as cl
import numpy as np
import os

kernel = """
__kernel void black(__write_only image2d_t dst,
                    int rows,
                    int columns)
{
    const int column = get_global_id(0);
    const int row = get_global_id(1);

        if (column < columns && row < rows)
        {
            write_imagef(dst, (int2)(column, row),
                (float4)(1.0f, 1.0f, 1.0f, 1.0f));
        }   
}
"""

ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)

mf = cl.mem_flags

f = cl.ImageFormat(cl.channel_order.R, cl.channel_type.UNSIGNED_INT8)

dst_image = cl.Image(ctx, mf.WRITE_ONLY , f, shape=(100,100,4))

prg = cl.Program(ctx, kernel).build()

prg.black(queue, (100,100), None, dst_image,
          np.int32(100),
          np.int32(100))

postimage = np.zeros((100,100,4), dtype=np.uint8)
cl.enqueue_copy(queue, postimage, dst_image,
                origin=(0, 0, 0),
                region=(100,100,4))

plt.imshow(postimage)
plt.show()
4

1 回答 1

1

您的内核代码实际上很好(尽管您发布的代码将每个像素都设置为白色,因此很难判断它是否正常工作!)。问题在于您创建图像的方式。当您shape=(100,100,4)cl.Image构造函数中指定时,您实际上是在请求 3D 图像。

让您的示例代码产生有用的东西的最简单方法是修改这些行:

f = cl.ImageFormat(cl.channel_order.R, cl.channel_type.UNSIGNED_INT8)
....
dst_image = cl.Image(ctx, mf.WRITE_ONLY , f, shape=(100,100,4))
...
cl.enqueue_copy(queue, postimage, dst_image,
                origin=(0, 0, 0),
                region=(100,100,4))

f = cl.ImageFormat(cl.channel_order.RGBA, cl.channel_type.UNSIGNED_INT8)
....
dst_image = cl.Image(ctx, mf.WRITE_ONLY , f, shape=(100,100))
....
cl.enqueue_copy(queue, postimage, dst_image,
                origin=(0, 0),
                region=(100,100))

在这里,我已将图像格式更改为 RGBA,这与matplotlib图像显示功能所期望的相匹配(我不熟悉该库,因此您可能也可以让它显示单通道图像)。我还修改了创建图像并将其复制回主机的行,使其成为 2D,而不是 3D。

现在,如果您更改内核以将此数据写入映像:

write_imagef(dst, (int2)(column, row), (float4)(1.0f, 0.0f, 0.0f, 1.0f));

你应该得到一个漂亮的红色输出图像!

于 2014-01-05T11:04:05.090 回答